Add options to AddressSanitizer passes to make them configurable by frontend.
authorAlexey Samsonov <samsonov@google.com>
Thu, 29 Nov 2012 18:14:24 +0000 (18:14 +0000)
committerAlexey Samsonov <samsonov@google.com>
Thu, 29 Nov 2012 18:14:24 +0000 (18:14 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@168910 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Transforms/Instrumentation.h
lib/Transforms/Instrumentation/AddressSanitizer.cpp

index 57b6ab3d30b3a9eef59333f7eb13b8afc1860672..c84ecb6a230e14061ec9b7bfe4d8d2808eebb0a4 100644 (file)
@@ -34,8 +34,10 @@ ModulePass *createGCOVProfilerPass(bool EmitNotes = true, bool EmitData = true,
                                    bool UseExtraChecksum = false);
 
 // Insert AddressSanitizer (address sanity checking) instrumentation
                                    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
 // Insert MemorySanitizer instrumentation (detection of uninitialized reads)
 FunctionPass *createMemorySanitizerPass();
 // Insert ThreadSanitizer (race detection) instrumentation
index 318e393afeaedd12622bea92f166d1b0da82f204..4d8040834ed008ca40493074df49c79e5a9027dc 100644 (file)
@@ -136,6 +136,10 @@ static cl::opt<bool> ClOptSameTemp("asan-opt-same-temp",
 static cl::opt<bool> ClOptGlobals("asan-opt-globals",
        cl::desc("Don't instrument scalar globals"), cl::Hidden, cl::init(true));
 
 static cl::opt<bool> ClOptGlobals("asan-opt-globals",
        cl::desc("Don't instrument scalar globals"), cl::Hidden, cl::init(true));
 
+static cl::opt<bool> ClCheckLifetime("asan-check-lifetime",
+       cl::desc("Use llvm.lifetime intrinsics to insert extra checks"),
+       cl::Hidden, cl::init(false));
+
 // Debug flags.
 static cl::opt<int> ClDebug("asan-debug", cl::desc("debug"), cl::Hidden,
                             cl::init(0));
 // Debug flags.
 static cl::opt<int> 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: 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";
   }
   virtual const char *getPassName() const {
     return "AddressSanitizerFunctionPass";
   }
@@ -232,6 +242,9 @@ struct AddressSanitizer : public FunctionPass {
   bool LooksLikeCodeInBug11395(Instruction *I);
   void FindDynamicInitializers(Module &M);
 
   bool LooksLikeCodeInBug11395(Instruction *I);
   void FindDynamicInitializers(Module &M);
 
+  bool CheckInitOrder;
+  bool CheckUseAfterReturn;
+  bool CheckLifetime;
   LLVMContext *C;
   DataLayout *TD;
   uint64_t MappingOffset;
   LLVMContext *C;
   DataLayout *TD;
   uint64_t MappingOffset;
@@ -251,9 +264,11 @@ struct AddressSanitizer : public FunctionPass {
 
 class AddressSanitizerModule : public ModulePass {
  public:
 
 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
   bool runOnModule(Module &M);
   static char ID;  // Pass identification, replacement for typeid
-  AddressSanitizerModule() : ModulePass(ID) { }
   virtual const char *getPassName() const {
     return "AddressSanitizerModule";
   }
   virtual const char *getPassName() const {
     return "AddressSanitizerModule";
   }
@@ -262,6 +277,7 @@ class AddressSanitizerModule : public ModulePass {
   void createInitializerPoisonCalls(Module &M, Value *FirstAddr,
                                     Value *LastAddr);
 
   void createInitializerPoisonCalls(Module &M, Value *FirstAddr,
                                     Value *LastAddr);
 
+  bool CheckInitOrder;
   OwningPtr<BlackList> BL;
   SetOfDynamicallyInitializedGlobals DynamicallyInitializedGlobals;
   Type *IntptrTy;
   OwningPtr<BlackList> 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)
 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)
 }
 
 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) {
 }
 
 static size_t TypeSizeToSizeIndex(uint32_t TypeSize) {
@@ -396,7 +413,7 @@ void AddressSanitizer::instrumentMop(Instruction *I) {
     if (GlobalVariable *G = dyn_cast<GlobalVariable>(Addr)) {
       // If initialization order checking is disabled, a simple access to a
       // dynamically initialized global is always valid.
     if (GlobalVariable *G = dyn_cast<GlobalVariable>(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
         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.
         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;
       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.
       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(
     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();
 
 
   uint64_t LocalStackSize = TotalSize + (AllocaVec.size() + 1) * RedzoneSize();
 
-  bool DoStackMalloc = ClUseAfterReturn
+  bool DoStackMalloc = CheckUseAfterReturn
       && LocalStackSize <= kMaxStackMallocSize;
 
   Instruction *InsBefore = AllocaVec[0];
       && LocalStackSize <= kMaxStackMallocSize;
 
   Instruction *InsBefore = AllocaVec[0];