[llvm-commits] [llvm] r150102 - in /llvm/trunk: lib/Transforms/Instrumentation/AddressSanitizer.cpp test/Instrumentation/AddressSanitizer/instrument-no-return.ll

Kostya Serebryany kcc at google.com
Wed Feb 8 13:36:17 PST 2012


Author: kcc
Date: Wed Feb  8 15:36:17 2012
New Revision: 150102

URL: http://llvm.org/viewvc/llvm-project?rev=150102&view=rev
Log:
[asan] unpoison the stack before every noreturn call. Fixes asan issue 37. llvm part

Added:
    llvm/trunk/test/Instrumentation/AddressSanitizer/instrument-no-return.ll
Modified:
    llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp

Modified: llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp?rev=150102&r1=150101&r2=150102&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp (original)
+++ llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp Wed Feb  8 15:36:17 2012
@@ -60,6 +60,7 @@
 static const char *kAsanRegisterGlobalsName = "__asan_register_globals";
 static const char *kAsanUnregisterGlobalsName = "__asan_unregister_globals";
 static const char *kAsanInitName = "__asan_init";
+static const char *kAsanHandleNoReturnName = "__asan_handle_no_return";
 static const char *kAsanMappingOffsetName = "__asan_mapping_offset";
 static const char *kAsanMappingScaleName = "__asan_mapping_scale";
 static const char *kAsanStackMallocName = "__asan_stack_malloc";
@@ -649,6 +650,7 @@
   // (unless there are calls between uses).
   SmallSet<Value*, 16> TempsToInstrument;
   SmallVector<Instruction*, 16> ToInstrument;
+  SmallVector<Instruction*, 8> NoReturnCalls;
 
   // Fill the set of memory operations to instrument.
   for (Function::iterator FI = F.begin(), FE = F.end();
@@ -667,9 +669,12 @@
       } else if (isa<MemIntrinsic>(BI) && ClMemIntrin) {
         // ok, take it.
       } else {
-        if (isa<CallInst>(BI)) {
+        if (CallInst *CI = dyn_cast<CallInst>(BI)) {
           // A call inside BB.
           TempsToInstrument.clear();
+          if (CI->doesNotReturn()) {
+            NoReturnCalls.push_back(CI);
+          }
         }
         continue;
       }
@@ -694,7 +699,17 @@
   DEBUG(dbgs() << F);
 
   bool ChangedStack = poisonStackInFunction(M, F);
-  return NumInstrumented > 0 || ChangedStack;
+
+  // We must unpoison the stack before every NoReturn call (throw, _exit, etc).
+  // See e.g. http://code.google.com/p/address-sanitizer/issues/detail?id=37
+  for (size_t i = 0, n = NoReturnCalls.size(); i != n; i++) {
+    Instruction *CI = NoReturnCalls[i];
+    IRBuilder<> IRB(CI);
+    IRB.CreateCall(M.getOrInsertFunction(kAsanHandleNoReturnName,
+                                         IRB.getVoidTy(), NULL));
+  }
+
+  return NumInstrumented > 0 || ChangedStack || !NoReturnCalls.empty();
 }
 
 static uint64_t ValueForPoison(uint64_t PoisonByte, size_t ShadowRedzoneSize) {

Added: llvm/trunk/test/Instrumentation/AddressSanitizer/instrument-no-return.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Instrumentation/AddressSanitizer/instrument-no-return.ll?rev=150102&view=auto
==============================================================================
--- llvm/trunk/test/Instrumentation/AddressSanitizer/instrument-no-return.ll (added)
+++ llvm/trunk/test/Instrumentation/AddressSanitizer/instrument-no-return.ll Wed Feb  8 15:36:17 2012
@@ -0,0 +1,17 @@
+; RUN: opt < %s -asan -S | FileCheck %s
+; AddressSanitizer must insert __asan_handle_no_return
+; before every noreturn call.
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+declare void @MyNoReturnFunc(i32) noreturn
+
+define i32 @_Z5ChildPv(i8* nocapture %arg) uwtable address_safety {
+entry:
+  call void @MyNoReturnFunc(i32 1) noreturn
+  unreachable
+}
+
+; CHECK:        call void @__asan_handle_no_return
+; CHECK-NEXT:   call void @MyNoReturnFunc





More information about the llvm-commits mailing list