aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Transforms/Instrumentation
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Transforms/Instrumentation')
-rw-r--r--lib/Transforms/Instrumentation/AddressSanitizer.cpp14
-rw-r--r--lib/Transforms/Instrumentation/CMakeLists.txt1
-rw-r--r--lib/Transforms/Instrumentation/DebugIR.cpp310
-rw-r--r--lib/Transforms/Instrumentation/GCOVProfiling.cpp2
-rw-r--r--lib/Transforms/Instrumentation/MemorySanitizer.cpp66
-rw-r--r--lib/Transforms/Instrumentation/ThreadSanitizer.cpp2
6 files changed, 372 insertions, 23 deletions
diff --git a/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/lib/Transforms/Instrumentation/AddressSanitizer.cpp
index 623c470..22851b4 100644
--- a/lib/Transforms/Instrumentation/AddressSanitizer.cpp
+++ b/lib/Transforms/Instrumentation/AddressSanitizer.cpp
@@ -39,9 +39,9 @@
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Support/Endian.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/system_error.h"
-#include "llvm/Target/TargetMachine.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Transforms/Utils/BlackList.h"
#include "llvm/Transforms/Utils/Local.h"
@@ -56,6 +56,7 @@ static const uint64_t kDefaultShadowOffset32 = 1ULL << 29;
static const uint64_t kDefaultShadowOffset64 = 1ULL << 44;
static const uint64_t kDefaultShort64bitShadowOffset = 0x7FFF8000; // < 2G.
static const uint64_t kPPC64_ShadowOffset64 = 1ULL << 41;
+static const uint64_t kMIPS32_ShadowOffset32 = 0x0aaa8000;
static const size_t kMaxStackMallocSize = 1 << 16; // 64K
static const uintptr_t kCurrentStackFrameMagic = 0x41B58AB3;
@@ -208,6 +209,8 @@ static ShadowMapping getShadowMapping(const Module &M, int LongSize,
bool IsMacOSX = TargetTriple.getOS() == llvm::Triple::MacOSX;
bool IsPPC64 = TargetTriple.getArch() == llvm::Triple::ppc64;
bool IsX86_64 = TargetTriple.getArch() == llvm::Triple::x86_64;
+ bool IsMIPS32 = TargetTriple.getArch() == llvm::Triple::mips ||
+ TargetTriple.getArch() == llvm::Triple::mipsel;
ShadowMapping Mapping;
@@ -217,7 +220,8 @@ static ShadowMapping getShadowMapping(const Module &M, int LongSize,
Mapping.OrShadowOffset = !IsPPC64 && !ClShort64BitOffset;
Mapping.Offset = (IsAndroid || ZeroBaseShadow) ? 0 :
- (LongSize == 32 ? kDefaultShadowOffset32 :
+ (LongSize == 32 ?
+ (IsMIPS32 ? kMIPS32_ShadowOffset32 : kDefaultShadowOffset32) :
IsPPC64 ? kPPC64_ShadowOffset64 : kDefaultShadowOffset64);
if (!ZeroBaseShadow && ClShort64BitOffset && IsX86_64 && !IsMacOSX) {
assert(LongSize == 64);
@@ -520,7 +524,7 @@ ModulePass *llvm::createAddressSanitizerModulePass(
}
static size_t TypeSizeToSizeIndex(uint32_t TypeSize) {
- size_t Res = CountTrailingZeros_32(TypeSize / 8);
+ size_t Res = countTrailingZeros(TypeSize / 8);
assert(Res < kNumberOfAccessSizes);
return Res;
}
@@ -1270,6 +1274,10 @@ void FunctionStackPoisoner::poisonRedZones(
RedzoneSize(),
1ULL << Mapping.Scale,
kAsanStackPartialRedzoneMagic);
+ Poison =
+ ASan.TD->isLittleEndian()
+ ? support::endian::byte_swap<uint32_t, support::little>(Poison)
+ : support::endian::byte_swap<uint32_t, support::big>(Poison);
}
Value *PartialPoison = ConstantInt::get(RZTy, Poison);
IRB.CreateStore(PartialPoison, IRB.CreateIntToPtr(Ptr, RZPtrTy));
diff --git a/lib/Transforms/Instrumentation/CMakeLists.txt b/lib/Transforms/Instrumentation/CMakeLists.txt
index 1c9e053..aa265a4 100644
--- a/lib/Transforms/Instrumentation/CMakeLists.txt
+++ b/lib/Transforms/Instrumentation/CMakeLists.txt
@@ -2,6 +2,7 @@ add_llvm_library(LLVMInstrumentation
AddressSanitizer.cpp
BlackList.cpp
BoundsChecking.cpp
+ DebugIR.cpp
EdgeProfiling.cpp
GCOVProfiling.cpp
MemorySanitizer.cpp
diff --git a/lib/Transforms/Instrumentation/DebugIR.cpp b/lib/Transforms/Instrumentation/DebugIR.cpp
new file mode 100644
index 0000000..020804f
--- /dev/null
+++ b/lib/Transforms/Instrumentation/DebugIR.cpp
@@ -0,0 +1,310 @@
+//===--- DebugIR.cpp - Transform debug metadata to allow debugging IR -----===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// A Module transform pass that emits a succinct version of the IR and replaces
+// the source file metadata to allow debuggers to step through the IR.
+//
+// The location where the IR file is emitted is the same as the directory
+// operand of the !llvm.dbg.cu metadata node present in the input module. The
+// file name is constructed from the original file name by stripping the
+// extension and replacing it with "-debug-ll" or the Postfix string specified
+// at construction.
+//
+// FIXME: instead of replacing debug metadata, additional metadata should be
+// used to point capable debuggers to the IR file without destroying the
+// mapping to the original source file.
+//
+// FIXME: this pass should not depend on the existance of debug metadata in
+// the module as it does now. Instead, it should use DIBuilder to create the
+// required metadata.
+//
+//===----------------------------------------------------------------------===//
+
+#include <string>
+
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/ValueMap.h"
+#include "llvm/Assembly/AssemblyAnnotationWriter.h"
+#include "llvm/DebugInfo.h"
+#include "llvm/DIBuilder.h"
+#include "llvm/InstVisitor.h"
+#include "llvm/IR/Instruction.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Pass.h"
+#include "llvm/Transforms/Instrumentation.h"
+#include "llvm/Transforms/Utils/Cloning.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/ToolOutputFile.h"
+#include "llvm/Support/FormattedStream.h"
+using namespace llvm;
+
+namespace {
+
+/// Builds a map of Value* to line numbers on which the Value appears in a
+/// textual representation of the IR by plugging into the AssemblyWriter by
+/// masquerading as an AssemblyAnnotationWriter.
+class ValueToLineMap : public AssemblyAnnotationWriter {
+ ValueMap<const Value *, unsigned int> Lines;
+ typedef ValueMap<const Value *, unsigned int>::const_iterator LineIter;
+
+public:
+
+ /// Prints Module to a null buffer in order to build the map of Value pointers
+ /// to line numbers.
+ ValueToLineMap(Module *M) {
+ raw_null_ostream ThrowAway;
+ M->print(ThrowAway, this);
+ }
+
+ // This function is called after an Instruction, GlobalValue, or GlobalAlias
+ // is printed.
+ void printInfoComment(const Value &V, formatted_raw_ostream &Out) {
+ Out.flush();
+ Lines.insert(std::make_pair(&V, Out.getLine() + 1));
+ }
+
+ /// If V appears on a line in the textual IR representation, sets Line to the
+ /// line number and returns true, otherwise returns false.
+ bool getLine(const Value *V, unsigned int &Line) const {
+ LineIter i = Lines.find(V);
+ if (i != Lines.end()) {
+ Line = i->second;
+ return true;
+ }
+ return false;
+ }
+};
+
+/// Removes debug intrisncs like llvm.dbg.declare and llvm.dbg.value.
+class DebugIntrinsicsRemover : public InstVisitor<DebugIntrinsicsRemover> {
+ void remove(Instruction &I) { I.eraseFromParent(); }
+
+public:
+ void visitDbgDeclareInst(DbgDeclareInst &I) { remove(I); }
+ void visitDbgValueInst(DbgValueInst &I) { remove(I); }
+ void visitDbgInfoIntrinsic(DbgInfoIntrinsic &I) { remove(I); }
+};
+
+/// Removes debug metadata (!dbg) nodes from all instructions as well as
+/// metadata named "llvm.dbg.cu" in the Module.
+class DebugMetadataRemover : public InstVisitor<DebugMetadataRemover> {
+public:
+ void visitInstruction(Instruction &I) {
+ if (I.getMetadata(LLVMContext::MD_dbg))
+ I.setMetadata(LLVMContext::MD_dbg, 0);
+ }
+
+ void run(Module *M) {
+ // Remove debug metadata attached to instructions
+ visit(M);
+
+ // Remove CU named metadata (and all children nodes)
+ NamedMDNode *Node = M->getNamedMetadata("llvm.dbg.cu");
+ M->eraseNamedMetadata(Node);
+ }
+};
+
+/// Replaces line number metadata attached to Instruction nodes with new line
+/// numbers provided by the ValueToLineMap.
+class LineNumberReplacer : public InstVisitor<LineNumberReplacer> {
+ /// Table of line numbers
+ const ValueToLineMap &LineTable;
+
+ /// Table of cloned values
+ const ValueToValueMapTy &VMap;
+
+ /// Directory of debug metadata
+ const DebugInfoFinder &Finder;
+
+public:
+ LineNumberReplacer(const ValueToLineMap &VLM, const DebugInfoFinder &Finder,
+ const ValueToValueMapTy &VMap)
+ : LineTable(VLM), VMap(VMap), Finder(Finder) {}
+
+ void visitInstruction(Instruction &I) {
+ DebugLoc Loc(I.getDebugLoc());
+
+ unsigned Col = 0; // FIXME: support columns
+ unsigned Line;
+ if (!LineTable.getLine(VMap.lookup(&I), Line))
+ // Instruction has no line, it may have been removed (in the module that
+ // will be passed to the debugger) so there is nothing to do here.
+ return;
+
+ DebugLoc NewLoc;
+ if (!Loc.isUnknown())
+ // I had a previous debug location: re-use the DebugLoc
+ NewLoc = DebugLoc::get(Line, Col, Loc.getScope(I.getContext()),
+ Loc.getInlinedAt(I.getContext()));
+ else if (MDNode *scope = findFunctionMD(I.getParent()->getParent()))
+ // I had no previous debug location, but M has some debug information
+ NewLoc =
+ DebugLoc::get(Line, Col, scope, /*FIXME: inlined instructions*/ 0);
+ else
+ // Neither I nor M has any debug information -- nothing to do here.
+ // FIXME: support debugging of undecorated IR (generated by clang without
+ // the -g option)
+ return;
+
+ addDebugLocation(const_cast<Instruction &>(I), NewLoc);
+ }
+
+private:
+
+ /// Returns the MDNode that corresponds with F
+ MDNode *findFunctionMD(const Function *F) {
+ for (DebugInfoFinder::iterator i = Finder.subprogram_begin(),
+ e = Finder.subprogram_end();
+ i != e; ++i) {
+ DISubprogram S(*i);
+ if (S.getFunction() == F)
+ return *i;
+ }
+ // cannot find F -- likely means there is no debug information
+ return 0;
+ }
+
+ void addDebugLocation(Instruction &I, DebugLoc Loc) {
+ MDNode *MD = Loc.getAsMDNode(I.getContext());
+ I.setMetadata(LLVMContext::MD_dbg, MD);
+ }
+};
+
+class DebugIR : public ModulePass {
+ std::string Postfix;
+ std::string Filename;
+
+ /// Flags to control the verbosity of the generated IR file
+ bool hideDebugIntrinsics;
+ bool hideDebugMetadata;
+
+public:
+ static char ID;
+
+ const char *getPassName() const { return "DebugIR"; }
+
+ // FIXME: figure out if we are compiling something that already exists on disk
+ // in text IR form, in which case we can omit outputting a new IR file, or if
+ // we're building something from memory where we actually need to emit a new
+ // IR file for the debugger.
+
+ /// Output a file with the same base name as the original, but with the
+ /// postfix "-debug-ll" appended.
+ DebugIR()
+ : ModulePass(ID), Postfix("-debug-ll"), hideDebugIntrinsics(true),
+ hideDebugMetadata(true) {}
+
+ /// Customize the postfix string used to replace the extension of the
+ /// original filename that appears in the !llvm.dbg.cu metadata node.
+ DebugIR(StringRef postfix, bool hideDebugIntrinsics, bool hideDebugMetadata)
+ : ModulePass(ID), Postfix(postfix),
+ hideDebugIntrinsics(hideDebugIntrinsics),
+ hideDebugMetadata(hideDebugMetadata) {}
+
+private:
+ // Modify the filename embedded in the Compilation-Unit debug information of M
+ bool replaceFilename(Module &M, const DebugInfoFinder &Finder) {
+ bool changed = false;
+
+ // Sanity check -- if llvm.dbg.cu node exists, the DebugInfoFinder
+ // better have found at least one CU!
+ if (M.getNamedMetadata("llvm.dbg.cu"))
+ assert(Finder.compile_unit_count() > 0 &&
+ "Found no compile units but llvm.dbg.cu node exists");
+
+ for (DebugInfoFinder::iterator i = Finder.compile_unit_begin(),
+ e = Finder.compile_unit_end();
+ i != e; ++i) {
+ DICompileUnit CU(*i);
+ Filename = CU.getFilename();
+
+ // Replace extension with postfix
+ size_t dot = Filename.find_last_of(".");
+ if (dot != std::string::npos)
+ Filename.erase(dot);
+ Filename += Postfix;
+
+ CU.setFilename(Filename, M.getContext());
+ changed = true;
+ }
+ return changed;
+ }
+
+ /// Replace existing line number metadata with line numbers that correspond
+ /// with the IR file that is seen by the debugger.
+ void addLineNumberMetadata(Module *M, const ValueToLineMap &VLM,
+ const ValueToValueMapTy &VMap,
+ const DebugInfoFinder &Finder) {
+ LineNumberReplacer Replacer(VLM, Finder, VMap);
+ Replacer.visit(M);
+ }
+
+ void writeDebugBitcode(Module *M) {
+ std::string error;
+ tool_output_file OutFile(Filename.c_str(), error);
+ OutFile.keep();
+ formatted_raw_ostream OS;
+ OS.setStream(OutFile.os());
+ M->print(OS, 0);
+ }
+
+ void removeDebugIntrinsics(Module *M) {
+ DebugIntrinsicsRemover Remover;
+ Remover.visit(M);
+ }
+
+ void removeDebugMetadata(Module *M) {
+ DebugMetadataRemover Remover;
+ Remover.run(M);
+ }
+
+ void updateAndWriteDebugIRFile(Module *M, const DebugInfoFinder &Finder) {
+ // The module we output in text form for a debugger to open is stripped of
+ // 'extras' like debug intrinsics that end up in DWARF anyways and just
+ // clutter the debug experience.
+
+ ValueToValueMapTy VMap;
+ Module *DebuggerM = CloneModule(M, VMap);
+
+ if (hideDebugIntrinsics)
+ removeDebugIntrinsics(DebuggerM);
+
+ if (hideDebugMetadata)
+ removeDebugMetadata(DebuggerM);
+
+ // FIXME: remove all debug metadata from M once we support generating DWARF
+ // subprogram attributes.
+
+ ValueToLineMap LineTable(DebuggerM);
+ addLineNumberMetadata(M, LineTable, VMap, Finder);
+ writeDebugBitcode(DebuggerM);
+ }
+
+ bool runOnModule(Module &M) {
+ // Stores existing debug info needed when creating new line number entries.
+ DebugInfoFinder Finder;
+ Finder.processModule(M);
+
+ bool changed = replaceFilename(M, Finder);
+ if (changed)
+ updateAndWriteDebugIRFile(&M, Finder);
+ return changed;
+ }
+};
+
+} // anonymous namespace
+
+char DebugIR::ID = 0;
+INITIALIZE_PASS(DebugIR, "debug-ir", "Enable debugging IR", false, false)
+
+ModulePass *llvm::createDebugIRPass(StringRef FilenamePostfix,
+ bool hideDebugIntrinsics,
+ bool hideDebugMetadata) {
+ return new DebugIR(FilenamePostfix, hideDebugIntrinsics, hideDebugMetadata);
+}
diff --git a/lib/Transforms/Instrumentation/GCOVProfiling.cpp b/lib/Transforms/Instrumentation/GCOVProfiling.cpp
index 2edd151..3ce9cf6 100644
--- a/lib/Transforms/Instrumentation/GCOVProfiling.cpp
+++ b/lib/Transforms/Instrumentation/GCOVProfiling.cpp
@@ -34,7 +34,7 @@
#include "llvm/Support/DebugLoc.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/InstIterator.h"
-#include "llvm/Support/PathV2.h"
+#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Utils/ModuleUtils.h"
#include <string>
diff --git a/lib/Transforms/Instrumentation/MemorySanitizer.cpp b/lib/Transforms/Instrumentation/MemorySanitizer.cpp
index 4e75904..a3a688d 100644
--- a/lib/Transforms/Instrumentation/MemorySanitizer.cpp
+++ b/lib/Transforms/Instrumentation/MemorySanitizer.cpp
@@ -74,6 +74,7 @@
#include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Triple.h"
#include "llvm/ADT/ValueMap.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Function.h"
@@ -228,7 +229,7 @@ class MemorySanitizer : public FunctionPass {
MDNode *ColdCallWeights;
/// \brief Branch weights for origin store.
MDNode *OriginStoreWeights;
- /// \bried Path to blacklist file.
+ /// \brief Path to blacklist file.
SmallString<64> BlacklistFile;
/// \brief The blacklist.
OwningPtr<BlackList> BL;
@@ -299,30 +300,30 @@ void MemorySanitizer::initializeCallbacks(Module &M) {
RetvalTLS = new GlobalVariable(
M, ArrayType::get(IRB.getInt64Ty(), 8), false,
GlobalVariable::ExternalLinkage, 0, "__msan_retval_tls", 0,
- GlobalVariable::GeneralDynamicTLSModel);
+ GlobalVariable::InitialExecTLSModel);
RetvalOriginTLS = new GlobalVariable(
M, OriginTy, false, GlobalVariable::ExternalLinkage, 0,
- "__msan_retval_origin_tls", 0, GlobalVariable::GeneralDynamicTLSModel);
+ "__msan_retval_origin_tls", 0, GlobalVariable::InitialExecTLSModel);
ParamTLS = new GlobalVariable(
M, ArrayType::get(IRB.getInt64Ty(), 1000), false,
GlobalVariable::ExternalLinkage, 0, "__msan_param_tls", 0,
- GlobalVariable::GeneralDynamicTLSModel);
+ GlobalVariable::InitialExecTLSModel);
ParamOriginTLS = new GlobalVariable(
M, ArrayType::get(OriginTy, 1000), false, GlobalVariable::ExternalLinkage,
- 0, "__msan_param_origin_tls", 0, GlobalVariable::GeneralDynamicTLSModel);
+ 0, "__msan_param_origin_tls", 0, GlobalVariable::InitialExecTLSModel);
VAArgTLS = new GlobalVariable(
M, ArrayType::get(IRB.getInt64Ty(), 1000), false,
GlobalVariable::ExternalLinkage, 0, "__msan_va_arg_tls", 0,
- GlobalVariable::GeneralDynamicTLSModel);
+ GlobalVariable::InitialExecTLSModel);
VAArgOverflowSizeTLS = new GlobalVariable(
M, IRB.getInt64Ty(), false, GlobalVariable::ExternalLinkage, 0,
"__msan_va_arg_overflow_size_tls", 0,
- GlobalVariable::GeneralDynamicTLSModel);
+ GlobalVariable::InitialExecTLSModel);
OriginTLS = new GlobalVariable(
M, IRB.getInt32Ty(), false, GlobalVariable::ExternalLinkage, 0,
- "__msan_origin_tls", 0, GlobalVariable::GeneralDynamicTLSModel);
+ "__msan_origin_tls", 0, GlobalVariable::InitialExecTLSModel);
// We insert an empty inline asm after __msan_report* to avoid callback merge.
EmptyAsm = InlineAsm::get(FunctionType::get(IRB.getVoidTy(), false),
@@ -365,11 +366,13 @@ bool MemorySanitizer::doInitialization(Module &M) {
appendToGlobalCtors(M, cast<Function>(M.getOrInsertFunction(
"__msan_init", IRB.getVoidTy(), NULL)), 0);
- new GlobalVariable(M, IRB.getInt32Ty(), true, GlobalValue::WeakODRLinkage,
- IRB.getInt32(TrackOrigins), "__msan_track_origins");
+ if (TrackOrigins)
+ new GlobalVariable(M, IRB.getInt32Ty(), true, GlobalValue::WeakODRLinkage,
+ IRB.getInt32(TrackOrigins), "__msan_track_origins");
- new GlobalVariable(M, IRB.getInt32Ty(), true, GlobalValue::WeakODRLinkage,
- IRB.getInt32(ClKeepGoing), "__msan_keep_going");
+ if (ClKeepGoing)
+ new GlobalVariable(M, IRB.getInt32Ty(), true, GlobalValue::WeakODRLinkage,
+ IRB.getInt32(ClKeepGoing), "__msan_keep_going");
return true;
}
@@ -768,14 +771,21 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
if (AI->hasByValAttr()) {
// ByVal pointer itself has clean shadow. We copy the actual
// argument shadow to the underlying memory.
+ // Figure out maximal valid memcpy alignment.
+ unsigned ArgAlign = AI->getParamAlignment();
+ if (ArgAlign == 0) {
+ Type *EltType = A->getType()->getPointerElementType();
+ ArgAlign = MS.TD->getABITypeAlignment(EltType);
+ }
+ unsigned CopyAlign = std::min(ArgAlign, kShadowTLSAlignment);
Value *Cpy = EntryIRB.CreateMemCpy(
- getShadowPtr(V, EntryIRB.getInt8Ty(), EntryIRB),
- Base, Size, AI->getParamAlignment());
+ getShadowPtr(V, EntryIRB.getInt8Ty(), EntryIRB), Base, Size,
+ CopyAlign);
DEBUG(dbgs() << " ByValCpy: " << *Cpy << "\n");
(void)Cpy;
*ShadowPtr = getCleanShadow(V);
} else {
- *ShadowPtr = EntryIRB.CreateLoad(Base);
+ *ShadowPtr = EntryIRB.CreateAlignedLoad(Base, kShadowTLSAlignment);
}
DEBUG(dbgs() << " ARG: " << *AI << " ==> " <<
**ShadowPtr << "\n");
@@ -784,7 +794,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
setOrigin(A, EntryIRB.CreateLoad(OriginPtr));
}
}
- ArgOffset += DataLayout::RoundUpAlignment(Size, 8);
+ ArgOffset += DataLayout::RoundUpAlignment(Size, kShadowTLSAlignment);
}
assert(*ShadowPtr && "Could not find shadow for an argument");
return *ShadowPtr;
@@ -1963,9 +1973,29 @@ struct VarArgAMD64Helper : public VarArgHelper {
}
};
-VarArgHelper* CreateVarArgHelper(Function &Func, MemorySanitizer &Msan,
+/// \brief A no-op implementation of VarArgHelper.
+struct VarArgNoOpHelper : public VarArgHelper {
+ VarArgNoOpHelper(Function &F, MemorySanitizer &MS,
+ MemorySanitizerVisitor &MSV) {}
+
+ void visitCallSite(CallSite &CS, IRBuilder<> &IRB) {}
+
+ void visitVAStartInst(VAStartInst &I) {}
+
+ void visitVACopyInst(VACopyInst &I) {}
+
+ void finalizeInstrumentation() {}
+};
+
+VarArgHelper *CreateVarArgHelper(Function &Func, MemorySanitizer &Msan,
MemorySanitizerVisitor &Visitor) {
- return new VarArgAMD64Helper(Func, Msan, Visitor);
+ // VarArg handling is only implemented on AMD64. False positives are possible
+ // on other platforms.
+ llvm::Triple TargetTriple(Func.getParent()->getTargetTriple());
+ if (TargetTriple.getArch() == llvm::Triple::x86_64)
+ return new VarArgAMD64Helper(Func, Msan, Visitor);
+ else
+ return new VarArgNoOpHelper(Func, Msan, Visitor);
}
} // namespace
diff --git a/lib/Transforms/Instrumentation/ThreadSanitizer.cpp b/lib/Transforms/Instrumentation/ThreadSanitizer.cpp
index 299060a..318fa3f 100644
--- a/lib/Transforms/Instrumentation/ThreadSanitizer.cpp
+++ b/lib/Transforms/Instrumentation/ThreadSanitizer.cpp
@@ -579,7 +579,7 @@ int ThreadSanitizer::getMemoryAccessFuncIndex(Value *Addr) {
// Ignore all unusual sizes.
return -1;
}
- size_t Idx = CountTrailingZeros_32(TypeSize / 8);
+ size_t Idx = countTrailingZeros(TypeSize / 8);
assert(Idx < kNumberOfAccessSizes);
return Idx;
}