mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-19 19:12:56 +02:00
[SanitizerCoverage] Optimize stack-depth instrumentation.
Summary: Use the initialexec TLS type and eliminate calls to the TLS wrapper. Fixes the sanitizer-x86_64-linux-fuzzer bot failure. Reviewers: vitalybuka, kcc Reviewed By: kcc Subscribers: hiraditya, llvm-commits Differential Revision: https://reviews.llvm.org/D37026 llvm-svn: 311490
This commit is contained in:
parent
8ac12d00ab
commit
1e506ce96c
@ -77,8 +77,6 @@ static const char *const SanCovCountersSectionName = "sancov_cntrs";
|
|||||||
static const char *const SanCovPCsSectionName = "sancov_pcs";
|
static const char *const SanCovPCsSectionName = "sancov_pcs";
|
||||||
|
|
||||||
static const char *const SanCovLowestStackName = "__sancov_lowest_stack";
|
static const char *const SanCovLowestStackName = "__sancov_lowest_stack";
|
||||||
static const char *const SanCovLowestStackTLSWrapperName =
|
|
||||||
"_ZTW21__sancov_lowest_stack";
|
|
||||||
|
|
||||||
static cl::opt<int> ClCoverageLevel(
|
static cl::opt<int> ClCoverageLevel(
|
||||||
"sanitizer-coverage-level",
|
"sanitizer-coverage-level",
|
||||||
@ -229,7 +227,6 @@ private:
|
|||||||
Function *SanCovTraceDivFunction[2];
|
Function *SanCovTraceDivFunction[2];
|
||||||
Function *SanCovTraceGepFunction;
|
Function *SanCovTraceGepFunction;
|
||||||
Function *SanCovTraceSwitchFunction;
|
Function *SanCovTraceSwitchFunction;
|
||||||
Function *SanCovLowestStackTLSWrapper;
|
|
||||||
GlobalVariable *SanCovLowestStack;
|
GlobalVariable *SanCovLowestStack;
|
||||||
InlineAsm *EmptyAsm;
|
InlineAsm *EmptyAsm;
|
||||||
Type *IntptrTy, *IntptrPtrTy, *Int64Ty, *Int64PtrTy, *Int32Ty, *Int32PtrTy,
|
Type *IntptrTy, *IntptrPtrTy, *Int64Ty, *Int64PtrTy, *Int32Ty, *Int32PtrTy,
|
||||||
@ -351,20 +348,11 @@ bool SanitizerCoverageModule::runOnModule(Module &M) {
|
|||||||
|
|
||||||
Constant *SanCovLowestStackConstant =
|
Constant *SanCovLowestStackConstant =
|
||||||
M.getOrInsertGlobal(SanCovLowestStackName, IntptrTy);
|
M.getOrInsertGlobal(SanCovLowestStackName, IntptrTy);
|
||||||
SanCovLowestStackTLSWrapper =
|
|
||||||
checkSanitizerInterfaceFunction(M.getOrInsertFunction(
|
|
||||||
SanCovLowestStackTLSWrapperName, IntptrTy->getPointerTo()));
|
|
||||||
if (Options.StackDepth) {
|
|
||||||
assert(isa<GlobalVariable>(SanCovLowestStackConstant));
|
|
||||||
SanCovLowestStack = cast<GlobalVariable>(SanCovLowestStackConstant);
|
SanCovLowestStack = cast<GlobalVariable>(SanCovLowestStackConstant);
|
||||||
if (!SanCovLowestStack->isDeclaration()) {
|
SanCovLowestStack->setThreadLocalMode(
|
||||||
// Check that the user has correctly defined:
|
GlobalValue::ThreadLocalMode::InitialExecTLSModel);
|
||||||
// thread_local uintptr_t __sancov_lowest_stack
|
if (Options.StackDepth && !SanCovLowestStack->isDeclaration())
|
||||||
// and initialize it.
|
|
||||||
assert(SanCovLowestStack->isThreadLocal());
|
|
||||||
SanCovLowestStack->setInitializer(Constant::getAllOnesValue(IntptrTy));
|
SanCovLowestStack->setInitializer(Constant::getAllOnesValue(IntptrTy));
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make sure smaller parameters are zero-extended to i64 as required by the
|
// Make sure smaller parameters are zero-extended to i64 as required by the
|
||||||
// x86_64 ABI.
|
// x86_64 ABI.
|
||||||
@ -484,9 +472,6 @@ bool SanitizerCoverageModule::runOnFunction(Function &F) {
|
|||||||
if (F.getName() == "__local_stdio_printf_options" ||
|
if (F.getName() == "__local_stdio_printf_options" ||
|
||||||
F.getName() == "__local_stdio_scanf_options")
|
F.getName() == "__local_stdio_scanf_options")
|
||||||
return false;
|
return false;
|
||||||
// Avoid infinite recursion by not instrumenting stack depth TLS wrapper
|
|
||||||
if (F.getName() == SanCovLowestStackTLSWrapperName)
|
|
||||||
return false;
|
|
||||||
// Don't instrument functions using SEH for now. Splitting basic blocks like
|
// Don't instrument functions using SEH for now. Splitting basic blocks like
|
||||||
// we do for coverage breaks WinEHPrepare.
|
// we do for coverage breaks WinEHPrepare.
|
||||||
// FIXME: Remove this when SEH no longer uses landingpad pattern matching.
|
// FIXME: Remove this when SEH no longer uses landingpad pattern matching.
|
||||||
@ -771,12 +756,11 @@ void SanitizerCoverageModule::InjectCoverageAtBlock(Function &F, BasicBlock &BB,
|
|||||||
auto FrameAddrPtr =
|
auto FrameAddrPtr =
|
||||||
IRB.CreateCall(GetFrameAddr, {Constant::getNullValue(Int32Ty)});
|
IRB.CreateCall(GetFrameAddr, {Constant::getNullValue(Int32Ty)});
|
||||||
auto FrameAddrInt = IRB.CreatePtrToInt(FrameAddrPtr, IntptrTy);
|
auto FrameAddrInt = IRB.CreatePtrToInt(FrameAddrPtr, IntptrTy);
|
||||||
auto LowestStackPtr = IRB.CreateCall(SanCovLowestStackTLSWrapper);
|
auto LowestStack = IRB.CreateLoad(SanCovLowestStack);
|
||||||
auto LowestStack = IRB.CreateLoad(LowestStackPtr);
|
|
||||||
auto IsStackLower = IRB.CreateICmpULT(FrameAddrInt, LowestStack);
|
auto IsStackLower = IRB.CreateICmpULT(FrameAddrInt, LowestStack);
|
||||||
auto ThenTerm = SplitBlockAndInsertIfThen(IsStackLower, &*IP, false);
|
auto ThenTerm = SplitBlockAndInsertIfThen(IsStackLower, &*IP, false);
|
||||||
IRBuilder<> ThenIRB(ThenTerm);
|
IRBuilder<> ThenIRB(ThenTerm);
|
||||||
ThenIRB.CreateStore(FrameAddrInt, LowestStackPtr);
|
ThenIRB.CreateStore(FrameAddrInt, SanCovLowestStack);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||||
target triple = "x86_64-unknown-linux-gnu"
|
target triple = "x86_64-unknown-linux-gnu"
|
||||||
|
|
||||||
; CHECK: @__sancov_lowest_stack = thread_local global i64 -1
|
; CHECK: @__sancov_lowest_stack = thread_local(initialexec) global i64 -1
|
||||||
@__sancov_lowest_stack = thread_local global i64 0, align 8
|
@__sancov_lowest_stack = thread_local global i64 0, align 8
|
||||||
|
|
||||||
define i32 @foo() {
|
define i32 @foo() {
|
||||||
@ -16,12 +16,11 @@ entry:
|
|||||||
; CHECK-LABEL: define i32 @foo
|
; CHECK-LABEL: define i32 @foo
|
||||||
; CHECK: [[framePtr:%[^ \t]+]] = call i8* @llvm.frameaddress(i32 0)
|
; CHECK: [[framePtr:%[^ \t]+]] = call i8* @llvm.frameaddress(i32 0)
|
||||||
; CHECK: [[frameInt:%[^ \t]+]] = ptrtoint i8* [[framePtr]] to [[$intType:i[0-9]+]]
|
; CHECK: [[frameInt:%[^ \t]+]] = ptrtoint i8* [[framePtr]] to [[$intType:i[0-9]+]]
|
||||||
; CHECK: [[lowestPtr:%[^ \t]+]] = call [[$intType]]* @_ZTW21__sancov_lowest_stack
|
; CHECK: [[lowest:%[^ \t]+]] = load [[$intType]], [[$intType]]* @__sancov_lowest_stack
|
||||||
; CHECK: [[lowestInt:%[^ \t]+]] = load [[$intType]], [[$intType]]* [[lowestPtr]]
|
; CHECK: [[cmp:%[^ \t]+]] = icmp ult [[$intType]] [[frameInt]], [[lowest]]
|
||||||
; CHECK: [[cmp:%[^ \t]+]] = icmp ult [[$intType]] [[frameInt]], [[lowestInt]]
|
|
||||||
; CHECK: br i1 [[cmp]], label %[[ifLabel:[^ \t]+]], label
|
; CHECK: br i1 [[cmp]], label %[[ifLabel:[^ \t]+]], label
|
||||||
; CHECK: <label>:[[ifLabel]]:
|
; CHECK: <label>:[[ifLabel]]:
|
||||||
; CHECK: store [[$intType]] [[frameInt]], [[$intType]]* [[lowestPtr]]
|
; CHECK: store [[$intType]] [[frameInt]], [[$intType]]* @__sancov_lowest_stack
|
||||||
; CHECK: ret i32 7
|
; CHECK: ret i32 7
|
||||||
|
|
||||||
ret i32 7
|
ret i32 7
|
||||||
@ -32,12 +31,11 @@ entry:
|
|||||||
; CHECK-LABEL: define i32 @bar
|
; CHECK-LABEL: define i32 @bar
|
||||||
; CHECK: [[framePtr:%[^ \t]+]] = call i8* @llvm.frameaddress(i32 0)
|
; CHECK: [[framePtr:%[^ \t]+]] = call i8* @llvm.frameaddress(i32 0)
|
||||||
; CHECK: [[frameInt:%[^ \t]+]] = ptrtoint i8* [[framePtr]] to [[$intType]]
|
; CHECK: [[frameInt:%[^ \t]+]] = ptrtoint i8* [[framePtr]] to [[$intType]]
|
||||||
; CHECK: [[lowestPtr:%[^ \t]+]] = call [[$intType]]* @_ZTW21__sancov_lowest_stack
|
; CHECK: [[lowest:%[^ \t]+]] = load [[$intType]], [[$intType]]* @__sancov_lowest_stack
|
||||||
; CHECK: [[lowestInt:%[^ \t]+]] = load [[$intType]], [[$intType]]* [[lowestPtr]]
|
; CHECK: [[cmp:%[^ \t]+]] = icmp ult [[$intType]] [[frameInt]], [[lowest]]
|
||||||
; CHECK: [[cmp:%[^ \t]+]] = icmp ult [[$intType]] [[frameInt]], [[lowestInt]]
|
|
||||||
; CHECK: br i1 [[cmp]], label %[[ifLabel:[^ \t]+]], label
|
; CHECK: br i1 [[cmp]], label %[[ifLabel:[^ \t]+]], label
|
||||||
; CHECK: <label>:[[ifLabel]]:
|
; CHECK: <label>:[[ifLabel]]:
|
||||||
; CHECK: store [[$intType]] [[frameInt]], [[$intType]]* [[lowestPtr]]
|
; CHECK: store [[$intType]] [[frameInt]], [[$intType]]* @__sancov_lowest_stack
|
||||||
; CHECK: %call = call i32 @foo()
|
; CHECK: %call = call i32 @foo()
|
||||||
; CHECK: ret i32 %call
|
; CHECK: ret i32 %call
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user