From ee548275c63a1eeffda9d3edd2bea04e1dadcc67 Mon Sep 17 00:00:00 2001 From: Alexey Samsonov Date: Thu, 29 Nov 2012 18:14:24 +0000 Subject: [PATCH] Add options to AddressSanitizer passes to make them configurable by frontend. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@168910 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Transforms/Instrumentation.h | 6 ++- .../Instrumentation/AddressSanitizer.cpp | 39 +++++++++++++------ 2 files changed, 32 insertions(+), 13 deletions(-) diff --git a/include/llvm/Transforms/Instrumentation.h b/include/llvm/Transforms/Instrumentation.h index 57b6ab3d30b..c84ecb6a230 100644 --- a/include/llvm/Transforms/Instrumentation.h +++ b/include/llvm/Transforms/Instrumentation.h @@ -34,8 +34,10 @@ ModulePass *createGCOVProfilerPass(bool EmitNotes = true, bool EmitData = true, bool UseExtraChecksum = false); // Insert AddressSanitizer (address sanity checking) instrumentation -FunctionPass *createAddressSanitizerFunctionPass(); -ModulePass *createAddressSanitizerModulePass(); +FunctionPass *createAddressSanitizerFunctionPass( + bool CheckInitOrder = false, bool CheckUseAfterReturn = false, + bool CheckLifetime = false); +ModulePass *createAddressSanitizerModulePass(bool CheckInitOrder = false); // Insert MemorySanitizer instrumentation (detection of uninitialized reads) FunctionPass *createMemorySanitizerPass(); // Insert ThreadSanitizer (race detection) instrumentation diff --git a/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/lib/Transforms/Instrumentation/AddressSanitizer.cpp index 318e393afea..4d8040834ed 100644 --- a/lib/Transforms/Instrumentation/AddressSanitizer.cpp +++ b/lib/Transforms/Instrumentation/AddressSanitizer.cpp @@ -136,6 +136,10 @@ static cl::opt ClOptSameTemp("asan-opt-same-temp", static cl::opt ClOptGlobals("asan-opt-globals", cl::desc("Don't instrument scalar globals"), cl::Hidden, cl::init(true)); +static cl::opt ClCheckLifetime("asan-check-lifetime", + cl::desc("Use llvm.lifetime intrinsics to insert extra checks"), + cl::Hidden, cl::init(false)); + // Debug flags. static cl::opt ClDebug("asan-debug", cl::desc("debug"), cl::Hidden, cl::init(0)); @@ -186,7 +190,13 @@ static size_t RedzoneSize() { /// AddressSanitizer: instrument the code in module to find memory bugs. struct AddressSanitizer : public FunctionPass { - AddressSanitizer(); + AddressSanitizer(bool CheckInitOrder = false, + bool CheckUseAfterReturn = false, + bool CheckLifetime = false) + : FunctionPass(ID), + CheckInitOrder(CheckInitOrder || ClInitializers), + CheckUseAfterReturn(CheckUseAfterReturn || ClUseAfterReturn), + CheckLifetime(CheckLifetime || ClCheckLifetime) {} virtual const char *getPassName() const { return "AddressSanitizerFunctionPass"; } @@ -232,6 +242,9 @@ struct AddressSanitizer : public FunctionPass { bool LooksLikeCodeInBug11395(Instruction *I); void FindDynamicInitializers(Module &M); + bool CheckInitOrder; + bool CheckUseAfterReturn; + bool CheckLifetime; LLVMContext *C; DataLayout *TD; uint64_t MappingOffset; @@ -251,9 +264,11 @@ struct AddressSanitizer : public FunctionPass { class AddressSanitizerModule : public ModulePass { public: + AddressSanitizerModule(bool CheckInitOrder = false) + : ModulePass(ID), + CheckInitOrder(CheckInitOrder || ClInitializers) {} bool runOnModule(Module &M); static char ID; // Pass identification, replacement for typeid - AddressSanitizerModule() : ModulePass(ID) { } virtual const char *getPassName() const { return "AddressSanitizerModule"; } @@ -262,6 +277,7 @@ class AddressSanitizerModule : public ModulePass { void createInitializerPoisonCalls(Module &M, Value *FirstAddr, Value *LastAddr); + bool CheckInitOrder; OwningPtr BL; SetOfDynamicallyInitializedGlobals DynamicallyInitializedGlobals; Type *IntptrTy; @@ -275,17 +291,18 @@ char AddressSanitizer::ID = 0; INITIALIZE_PASS(AddressSanitizer, "asan", "AddressSanitizer: detects use-after-free and out-of-bounds bugs.", false, false) -AddressSanitizer::AddressSanitizer() : FunctionPass(ID) { } -FunctionPass *llvm::createAddressSanitizerFunctionPass() { - return new AddressSanitizer(); +FunctionPass *llvm::createAddressSanitizerFunctionPass( + bool CheckInitOrder, bool CheckUseAfterReturn, bool CheckLifetime) { + return new AddressSanitizer(CheckInitOrder, CheckUseAfterReturn, + CheckLifetime); } char AddressSanitizerModule::ID = 0; INITIALIZE_PASS(AddressSanitizerModule, "asan-module", "AddressSanitizer: detects use-after-free and out-of-bounds bugs." "ModulePass", false, false) -ModulePass *llvm::createAddressSanitizerModulePass() { - return new AddressSanitizerModule(); +ModulePass *llvm::createAddressSanitizerModulePass(bool CheckInitOrder) { + return new AddressSanitizerModule(CheckInitOrder); } static size_t TypeSizeToSizeIndex(uint32_t TypeSize) { @@ -396,7 +413,7 @@ void AddressSanitizer::instrumentMop(Instruction *I) { if (GlobalVariable *G = dyn_cast(Addr)) { // If initialization order checking is disabled, a simple access to a // dynamically initialized global is always valid. - if (!ClInitializers) + if (!CheckInitOrder) return; // If a global variable does not have dynamic initialization we don't // have to instrument it. However, if a global does not have initailizer @@ -690,7 +707,7 @@ bool AddressSanitizerModule::runOnModule(Module &M) { NULL); // Populate the first and last globals declared in this TU. - if (ClInitializers && GlobalHasDynamicInitializer) { + if (CheckInitOrder && GlobalHasDynamicInitializer) { LastDynamic = ConstantExpr::getPointerCast(NewGlobal, IntptrTy); if (FirstDynamic == 0) FirstDynamic = LastDynamic; @@ -705,7 +722,7 @@ bool AddressSanitizerModule::runOnModule(Module &M) { ConstantArray::get(ArrayOfGlobalStructTy, Initializers), ""); // Create calls for poisoning before initializers run and unpoisoning after. - if (ClInitializers && FirstDynamic && LastDynamic) + if (CheckInitOrder && FirstDynamic && LastDynamic) createInitializerPoisonCalls(M, FirstDynamic, LastDynamic); Function *AsanRegisterGlobals = checkInterfaceFunction(M.getOrInsertFunction( @@ -1081,7 +1098,7 @@ bool AddressSanitizer::poisonStackInFunction(Function &F) { uint64_t LocalStackSize = TotalSize + (AllocaVec.size() + 1) * RedzoneSize(); - bool DoStackMalloc = ClUseAfterReturn + bool DoStackMalloc = CheckUseAfterReturn && LocalStackSize <= kMaxStackMallocSize; Instruction *InsBefore = AllocaVec[0]; -- 2.34.1