mirror of
https://github.com/RPCSX/llvm.git
synced 2024-12-26 14:15:53 +00:00
[asan] unpoison the stack before every noreturn call. Fixes asan issue 37. llvm part
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@150102 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
1dd8c8560d
commit
95e3cf44a9
@ -60,6 +60,7 @@ static const char *kAsanReportErrorTemplate = "__asan_report_";
|
||||
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 @@ bool AddressSanitizer::handleFunction(Module &M, Function &F) {
|
||||
// (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 @@ bool AddressSanitizer::handleFunction(Module &M, Function &F) {
|
||||
} 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 @@ bool AddressSanitizer::handleFunction(Module &M, Function &F) {
|
||||
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) {
|
||||
|
@ -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
|
Loading…
Reference in New Issue
Block a user