[llvm] r276480 - Unpoison stack before resume instruction

Vitaly Buka via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 22 15:04:38 PDT 2016


Author: vitalybuka
Date: Fri Jul 22 17:04:38 2016
New Revision: 276480

URL: http://llvm.org/viewvc/llvm-project?rev=276480&view=rev
Log:
Unpoison stack before resume instruction

Summary:
Clang inserts cleanup code before resume similar way as before return instruction.
This makes asan poison local variables causing false use-after-scope reports.

__asan_handle_no_return does not help here as it was executed before
llvm.lifetime.end inserted into resume block.

To avoid false report we need to unpoison stack for resume same way as for return.

PR27453

Reviewers: kcc, eugenis

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

Added:
    llvm/trunk/test/Instrumentation/AddressSanitizer/lifetime-throw.ll
Modified:
    llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp
    llvm/trunk/test/Instrumentation/AddressSanitizer/lifetime.ll

Modified: llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp?rev=276480&r1=276479&r2=276480&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp (original)
+++ llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp Fri Jul 22 17:04:38 2016
@@ -676,6 +676,12 @@ struct FunctionStackPoisoner : public In
   /// \brief Collect all Ret instructions.
   void visitReturnInst(ReturnInst &RI) { RetVec.push_back(&RI); }
 
+  /// \brief Collect all Resume instructions.
+  void visitResumeInst(ResumeInst &RI) { RetVec.push_back(&RI); }
+
+  /// \brief Collect all CatchReturnInst instructions.
+  void visitCleanupReturnInst(CleanupReturnInst &CRI) { RetVec.push_back(&CRI); }
+
   void unpoisonDynamicAllocasBeforeInst(Instruction *InstBefore,
                                         Value *SavedStack) {
     IRBuilder<> IRB(InstBefore);

Added: llvm/trunk/test/Instrumentation/AddressSanitizer/lifetime-throw.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Instrumentation/AddressSanitizer/lifetime-throw.ll?rev=276480&view=auto
==============================================================================
--- llvm/trunk/test/Instrumentation/AddressSanitizer/lifetime-throw.ll (added)
+++ llvm/trunk/test/Instrumentation/AddressSanitizer/lifetime-throw.ll Fri Jul 22 17:04:38 2016
@@ -0,0 +1,106 @@
+; Test handling of llvm.lifetime intrinsics with C++ exceptions.
+; RUN: opt < %s -asan -asan-module -asan-use-after-scope -asan-use-after-return=0 -S | FileCheck %s
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+%struct.ABC = type { i32 }
+
+$_ZN3ABCD2Ev = comdat any
+$_ZTS3ABC = comdat any
+$_ZTI3ABC = comdat any
+
+ at _ZTVN10__cxxabiv117__class_type_infoE = external global i8*
+ at _ZTS3ABC = linkonce_odr constant [5 x i8] c"3ABC\00", comdat
+ at _ZTI3ABC = linkonce_odr constant { i8*, i8* } { i8* bitcast (i8** getelementptr inbounds (i8*, i8** @_ZTVN10__cxxabiv117__class_type_infoE, i64 2) to i8*), i8* getelementptr inbounds ([5 x i8], [5 x i8]* @_ZTS3ABC, i32 0, i32 0) }, comdat
+
+define void @Throw() sanitize_address personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
+; CHECK-LABEL: define void @Throw()
+entry:
+  %x = alloca %struct.ABC, align 4
+  %0 = bitcast %struct.ABC* %x to i8*
+  call void @llvm.lifetime.start(i64 4, i8* %0)
+  ; CHECK: call void @__asan_unpoison_stack_memory
+  ; CHECK-NEXT: @llvm.lifetime.start
+
+  %exception = call i8* @__cxa_allocate_exception(i64 4)
+  invoke void @__cxa_throw(i8* %exception, i8* bitcast ({ i8*, i8* }* @_ZTI3ABC to i8*), i8* bitcast (void (%struct.ABC*)* @_ZN3ABCD2Ev to i8*)) noreturn
+          to label %unreachable unwind label %lpad
+  ; CHECK: call void @__asan_handle_no_return
+  ; CHECK-NEXT: @__cxa_throw
+
+lpad:
+  %1 = landingpad { i8*, i32 }
+          cleanup
+  call void @_ZN3ABCD2Ev(%struct.ABC* nonnull %x)
+  call void @llvm.lifetime.end(i64 4, i8* %0)
+  ; CHECK: call void @__asan_poison_stack_memory
+  ; CHECK-NEXT: @llvm.lifetime.end
+
+  resume { i8*, i32 } %1
+  ; CHECK: call void @__asan_unpoison_stack_memory
+  ; CHECK-NEXT: resume
+
+unreachable:
+  unreachable
+}
+
+%rtti.TypeDescriptor9 = type { i8**, i8*, [10 x i8] }
+%eh.CatchableType = type { i32, i32, i32, i32, i32, i32, i32 }
+%eh.CatchableTypeArray.1 = type { i32, [1 x i32] }
+%eh.ThrowInfo = type { i32, i32, i32, i32 }
+
+$"\01??1ABC@@QEAA at XZ" = comdat any
+$"\01??_R0?AUABC@@@8" = comdat any
+$"_CT??_R0?AUABC@@@84" = comdat any
+$"_CTA1?AUABC@@" = comdat any
+$"_TI1?AUABC@@" = comdat any
+
+@"\01??_7type_info@@6B@" = external constant i8*
+@"\01??_R0?AUABC@@@8" = linkonce_odr global %rtti.TypeDescriptor9 { i8** @"\01??_7type_info@@6B@", i8* null, [10 x i8] c".?AUABC@@\00" }, comdat
+ at __ImageBase = external constant i8
+@"_CT??_R0?AUABC@@@84" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor9* @"\01??_R0?AUABC@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 -1, i32 0, i32 4, i32 0 }, section ".xdata", comdat
+@"_CTA1?AUABC@@" = linkonce_odr unnamed_addr constant %eh.CatchableTypeArray.1 { i32 1, [1 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%eh.CatchableType* @"_CT??_R0?AUABC@@@84" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32)] }, section ".xdata", comdat
+@"_TI1?AUABC@@" = linkonce_odr unnamed_addr constant %eh.ThrowInfo { i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (void (%struct.ABC*)* @"\01??1ABC@@QEAA at XZ" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%eh.CatchableTypeArray.1* @"_CTA1?AUABC@@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, section ".xdata", comdat
+
+define void @ThrowWin() sanitize_address personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
+; CHECK-LABEL: define void @ThrowWin()
+entry:
+  %x = alloca %struct.ABC, align 4
+  %tmp = alloca %struct.ABC, align 4
+  %0 = bitcast %struct.ABC* %x to i8*
+  call void @llvm.lifetime.start(i64 4, i8* %0)
+  ; CHECK: call void @__asan_unpoison_stack_memory
+  ; CHECK-NEXT: @llvm.lifetime.start
+
+  %1 = bitcast %struct.ABC* %tmp to i8*
+  invoke void @_CxxThrowException(i8* %1, %eh.ThrowInfo* nonnull @"_TI1?AUABC@@") noreturn
+          to label %unreachable unwind label %ehcleanup
+  ; CHECK: call void @__asan_handle_no_return
+  ; CHECK-NEXT: @_CxxThrowException
+
+ehcleanup:
+  %2 = cleanuppad within none []
+  call void @"\01??1ABC@@QEAA at XZ"(%struct.ABC* nonnull %x) [ "funclet"(token %2) ]
+  call void @llvm.lifetime.end(i64 4, i8* %0)
+  ; CHECK: call void @__asan_poison_stack_memory
+  ; CHECK-NEXT: @llvm.lifetime.end
+
+  cleanupret from %2 unwind to caller
+  ; CHECK: call void @__asan_unpoison_stack_memory
+  ; CHECK-NEXT: cleanupret
+
+unreachable:
+  unreachable
+}
+
+
+declare i32 @__gxx_personality_v0(...)
+declare void @llvm.lifetime.start(i64, i8* nocapture)
+declare void @llvm.lifetime.end(i64, i8* nocapture)
+declare void @__cxa_throw(i8*, i8*, i8*) local_unnamed_addr
+declare i8* @__cxa_allocate_exception(i64) local_unnamed_addr
+declare void @_ZN3ABCD2Ev(%struct.ABC* %this) unnamed_addr
+declare void @"\01??1ABC@@QEAA at XZ"(%struct.ABC* %this)
+declare void @_CxxThrowException(i8*, %eh.ThrowInfo*)
+declare i32 @__CxxFrameHandler3(...)

Modified: llvm/trunk/test/Instrumentation/AddressSanitizer/lifetime.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Instrumentation/AddressSanitizer/lifetime.ll?rev=276480&r1=276479&r2=276480&view=diff
==============================================================================
--- llvm/trunk/test/Instrumentation/AddressSanitizer/lifetime.ll (original)
+++ llvm/trunk/test/Instrumentation/AddressSanitizer/lifetime.ll Fri Jul 22 17:04:38 2016
@@ -1,4 +1,4 @@
-; Test hanlding of llvm.lifetime intrinsics.
+; Test handling of llvm.lifetime intrinsics.
 ; RUN: opt < %s -asan -asan-module -asan-use-after-scope -asan-use-after-return=0 -S | FileCheck %s
 ; RUN: opt < %s -asan -asan-module -asan-use-after-scope -asan-use-after-return=0 -asan-instrument-allocas=0 -S | FileCheck %s --check-prefix=CHECK-NO-DYNAMIC
 




More information about the llvm-commits mailing list