[llvm] r352948 - [ASan] Do not instrument other runtime functions with `__asan_handle_no_return`

Julian Lettner via llvm-commits llvm-commits at lists.llvm.org
Fri Feb 1 18:05:16 PST 2019


Author: yln
Date: Fri Feb  1 18:05:16 2019
New Revision: 352948

URL: http://llvm.org/viewvc/llvm-project?rev=352948&view=rev
Log:
[ASan] Do not instrument other runtime functions with `__asan_handle_no_return`

Summary:
Currently, ASan inserts a call to `__asan_handle_no_return` before every
`noreturn` function call/invoke. This is unnecessary for calls to other
runtime funtions. This patch changes ASan to skip instrumentation for
functions calls marked with `!nosanitize` metadata.

Reviewers: TODO

Differential Revision: https://reviews.llvm.org/D57489

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

Modified: llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp?rev=352948&r1=352947&r2=352948&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp (original)
+++ llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp Fri Feb  1 18:05:16 2019
@@ -2554,7 +2554,8 @@ bool AddressSanitizer::runOnFunction(Fun
         if (CS) {
           // A call inside BB.
           TempsToInstrument.clear();
-          if (CS.doesNotReturn()) NoReturnCalls.push_back(CS.getInstruction());
+          if (CS.doesNotReturn() && !CS->getMetadata("nosanitize"))
+            NoReturnCalls.push_back(CS.getInstruction());
         }
         if (CallInst *CI = dyn_cast<CallInst>(&Inst))
           maybeMarkSanitizerLibraryCallNoBuiltin(CI, TLI);
@@ -2591,7 +2592,7 @@ bool AddressSanitizer::runOnFunction(Fun
   FunctionStackPoisoner FSP(F, *this);
   bool ChangedStack = FSP.runOnFunction();
 
-  // We must unpoison the stack before every NoReturn call (throw, _exit, etc).
+  // We must unpoison the stack before NoReturn calls (throw, _exit, etc).
   // See e.g. https://github.com/google/sanitizers/issues/37
   for (auto CI : NoReturnCalls) {
     IRBuilder<> IRB(CI);

Modified: 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=352948&r1=352947&r2=352948&view=diff
==============================================================================
--- llvm/trunk/test/Instrumentation/AddressSanitizer/instrument-no-return.ll (original)
+++ llvm/trunk/test/Instrumentation/AddressSanitizer/instrument-no-return.ll Fri Feb  1 18:05:16 2019
@@ -1,37 +1,45 @@
-; RUN: opt < %s -asan -asan-module -S | FileCheck %s
+; RUN: opt < %s -asan -S | FileCheck %s
 ; AddressSanitizer must insert __asan_handle_no_return
-; before every noreturn call or invoke.
+; before noreturn calls that aren't inserted by sanitizers.
 
 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
+declare void @NormalFunc()
+declare void @NoReturnFunc() noreturn
 
-define i32 @Call1(i8* nocapture %arg) uwtable sanitize_address {
-entry:
-  call void @MyNoReturnFunc(i32 1) noreturn  ; The call insn has noreturn attr.
-; CHECK:        @Call1
-; CHECK:        call void @__asan_handle_no_return
-; CHECK-NEXT:   call void @MyNoReturnFunc
-; CHECK-NEXT: unreachable
+; Instrument noreturn callsites (regardless of function)
+define i32 @Call1() sanitize_address {
+  call void @NormalFunc() noreturn
   unreachable
 }
-
-define i32 @Call2(i8* nocapture %arg) uwtable sanitize_address {
-entry:
-  call void @MyNoReturnFunc(i32 1)  ; No noreturn attribure on the call.
-; CHECK:        @Call2
-; CHECK:        call void @__asan_handle_no_return
-; CHECK-NEXT:   call void @MyNoReturnFunc
-; CHECK-NEXT: unreachable
+; CHECK-LABEL:  @Call1
+; CHECK-NEXT:   call void @__asan_handle_no_return
+; CHECK-NEXT:   call void @NormalFunc
+
+; Instrument calls to noreturn functions (regardless of callsite)
+define i32 @Call2() sanitize_address {
+  call void @NoReturnFunc()
+  unreachable
+}
+; CHECK-LABEL:  @Call2
+; CHECK-NEXT:   call void @__asan_handle_no_return
+; CHECK-NEXT:   call void @NoReturnFunc
+
+; Do *not* instrument callsites marked !nosanitize
+define i32 @Call3() sanitize_address {
+  call void @NoReturnFunc() noreturn, !nosanitize !{}
   unreachable
 }
+; CHECK-LABEL:  @Call3
+; CHECK-NOT:    call void @__asan_handle_no_return
+; CHECK:        call void @NoReturnFunc
 
 declare i32 @__gxx_personality_v0(...)
 
-define i64 @Invoke1(i8** %esc) nounwind uwtable ssp sanitize_address personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
+define i64 @Invoke1() nounwind uwtable ssp sanitize_address personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
 entry:
-  invoke void @MyNoReturnFunc(i32 1)
+  invoke void @NoReturnFunc()
           to label %invoke.cont unwind label %lpad
 
 invoke.cont:
@@ -42,8 +50,8 @@ lpad:
           filter [0 x i8*] zeroinitializer
   ret i64 1
 }
-; CHECK: @Invoke1
+; CHECK-LABEL:  @Invoke1
 ; CHECK:        call void @__asan_handle_no_return
-; CHECK-NEXT:   invoke void @MyNoReturnFunc
+; CHECK-NEXT:   invoke void @NoReturnFunc
 ; CHECK: ret i64 0
 ; CHECK: ret i64 1




More information about the llvm-commits mailing list