Index: compiler-rt/lib/fuzzer/FuzzerTracePC.cpp =================================================================== --- compiler-rt/lib/fuzzer/FuzzerTracePC.cpp +++ compiler-rt/lib/fuzzer/FuzzerTracePC.cpp @@ -32,7 +32,8 @@ uintptr_t __sancov_trace_pc_pcs[fuzzer::TracePC::kNumPCs]; // Used by -fsanitize-coverage=stack-depth to track stack depth -ATTRIBUTE_INTERFACE thread_local uintptr_t __sancov_lowest_stack; +ATTRIBUTE_INTERFACE __attribute__((tls_model("initial-exec"))) +thread_local uintptr_t __sancov_lowest_stack; namespace fuzzer { Index: compiler-rt/test/fuzzer/deep-recursion.test =================================================================== --- compiler-rt/test/fuzzer/deep-recursion.test +++ compiler-rt/test/fuzzer/deep-recursion.test @@ -1,5 +1,4 @@ # Test that we can find a stack overflow -RUN: echo DISABLED -DISABLED: %cpp_compiler -fsanitize-coverage=stack-depth %S/DeepRecursionTest.cpp -o %t -DISABLED: not %t -seed=1 -runs=100000000 2>&1 | FileCheck %s -DISABLED: ERROR: libFuzzer: deadly signal +RUN: %cpp_compiler -fsanitize-coverage=stack-depth %S/DeepRecursionTest.cpp -o %t +RUN: not %t -seed=1 -runs=100000000 2>&1 | FileCheck %s +CHECK: ERROR: libFuzzer: deadly signal Index: llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp =================================================================== --- llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp +++ llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp @@ -77,8 +77,6 @@ static const char *const SanCovPCsSectionName = "sancov_pcs"; static const char *const SanCovLowestStackName = "__sancov_lowest_stack"; -static const char *const SanCovLowestStackTLSWrapperName = - "_ZTW21__sancov_lowest_stack"; static cl::opt ClCoverageLevel( "sanitizer-coverage-level", @@ -229,7 +227,6 @@ Function *SanCovTraceDivFunction[2]; Function *SanCovTraceGepFunction; Function *SanCovTraceSwitchFunction; - Function *SanCovLowestStackTLSWrapper; GlobalVariable *SanCovLowestStack; InlineAsm *EmptyAsm; Type *IntptrTy, *IntptrPtrTy, *Int64Ty, *Int64PtrTy, *Int32Ty, *Int32PtrTy, @@ -351,20 +348,11 @@ Constant *SanCovLowestStackConstant = M.getOrInsertGlobal(SanCovLowestStackName, IntptrTy); - SanCovLowestStackTLSWrapper = - checkSanitizerInterfaceFunction(M.getOrInsertFunction( - SanCovLowestStackTLSWrapperName, IntptrTy->getPointerTo())); - if (Options.StackDepth) { - assert(isa(SanCovLowestStackConstant)); - SanCovLowestStack = cast(SanCovLowestStackConstant); - if (!SanCovLowestStack->isDeclaration()) { - // Check that the user has correctly defined: - // thread_local uintptr_t __sancov_lowest_stack - // and initialize it. - assert(SanCovLowestStack->isThreadLocal()); - SanCovLowestStack->setInitializer(Constant::getAllOnesValue(IntptrTy)); - } - } + SanCovLowestStack = cast(SanCovLowestStackConstant); + SanCovLowestStack->setThreadLocalMode( + GlobalValue::ThreadLocalMode::InitialExecTLSModel); + if (Options.StackDepth && !SanCovLowestStack->isDeclaration()) + SanCovLowestStack->setInitializer(Constant::getAllOnesValue(IntptrTy)); // Make sure smaller parameters are zero-extended to i64 as required by the // x86_64 ABI. @@ -484,9 +472,6 @@ if (F.getName() == "__local_stdio_printf_options" || F.getName() == "__local_stdio_scanf_options") 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 // we do for coverage breaks WinEHPrepare. // FIXME: Remove this when SEH no longer uses landingpad pattern matching. @@ -771,12 +756,11 @@ auto FrameAddrPtr = IRB.CreateCall(GetFrameAddr, {Constant::getNullValue(Int32Ty)}); auto FrameAddrInt = IRB.CreatePtrToInt(FrameAddrPtr, IntptrTy); - auto LowestStackPtr = IRB.CreateCall(SanCovLowestStackTLSWrapper); - auto LowestStack = IRB.CreateLoad(LowestStackPtr); + auto LowestStack = IRB.CreateLoad(SanCovLowestStack); auto IsStackLower = IRB.CreateICmpULT(FrameAddrInt, LowestStack); auto ThenTerm = SplitBlockAndInsertIfThen(IsStackLower, &*IP, false); IRBuilder<> ThenIRB(ThenTerm); - ThenIRB.CreateStore(FrameAddrInt, LowestStackPtr); + ThenIRB.CreateStore(FrameAddrInt, SanCovLowestStack); } } Index: llvm/test/Instrumentation/SanitizerCoverage/stack-depth.ll =================================================================== --- llvm/test/Instrumentation/SanitizerCoverage/stack-depth.ll +++ llvm/test/Instrumentation/SanitizerCoverage/stack-depth.ll @@ -8,7 +8,7 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" 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 define i32 @foo() { @@ -16,12 +16,11 @@ ; CHECK-LABEL: define i32 @foo ; CHECK: [[framePtr:%[^ \t]+]] = call i8* @llvm.frameaddress(i32 0) ; CHECK: [[frameInt:%[^ \t]+]] = ptrtoint i8* [[framePtr]] to [[$intType:i[0-9]+]] -; CHECK: [[lowestPtr:%[^ \t]+]] = call [[$intType]]* @_ZTW21__sancov_lowest_stack -; CHECK: [[lowestInt:%[^ \t]+]] = load [[$intType]], [[$intType]]* [[lowestPtr]] -; CHECK: [[cmp:%[^ \t]+]] = icmp ult [[$intType]] [[frameInt]], [[lowestInt]] +; CHECK: [[lowest:%[^ \t]+]] = load [[$intType]], [[$intType]]* @__sancov_lowest_stack +; CHECK: [[cmp:%[^ \t]+]] = icmp ult [[$intType]] [[frameInt]], [[lowest]] ; CHECK: br i1 [[cmp]], label %[[ifLabel:[^ \t]+]], label ; CHECK: