[sanitizer-coverage/libFuzzer] make the guards for trace-pc 32-bit; create one array of guards per function, instead of one guard per BB. reorganize the code so that trace-pc-guard does not create unneeded globals

llvm-svn: 282735
This commit is contained in:
Kostya Serebryany 2016-09-29 17:43:24 +00:00
parent ba72b95f7b
commit a9b0dd0e51
7 changed files with 107 additions and 80 deletions

View File

@ -334,7 +334,7 @@ on every edge:
if (guard_variable) if (guard_variable)
__sanitizer_cov_trace_pc_guard(&guard_variable) __sanitizer_cov_trace_pc_guard(&guard_variable)
Every edge will have its own `guard_variable` (uintptr_t). Every edge will have its own `guard_variable` (uint32_t).
The compler will also insert a module constructor that will call The compler will also insert a module constructor that will call
@ -342,7 +342,7 @@ The compler will also insert a module constructor that will call
// The guards are [start, stop). // The guards are [start, stop).
// This function may be called multiple times with the same values of start/stop. // This function may be called multiple times with the same values of start/stop.
__sanitizer_cov_trace_pc_guard_init(uintptr_t *start, uintptr_t *stop); __sanitizer_cov_trace_pc_guard_init(uint32_t_t *start, uint32_t *stop);
Similarly to `trace-pc,indirect-calls`, with `trace-pc-guards,indirect-calls` Similarly to `trace-pc,indirect-calls`, with `trace-pc-guards,indirect-calls`
``__sanitizer_cov_trace_pc_indirect(void *callee)`` will be inserted on every indirect call. ``__sanitizer_cov_trace_pc_indirect(void *callee)`` will be inserted on every indirect call.

View File

@ -500,7 +500,8 @@ void Fuzzer::ExecuteCallback(const uint8_t *Data, size_t Size) {
UnitStartTime = system_clock::now(); UnitStartTime = system_clock::now();
ResetCounters(); // Reset coverage right before the callback. ResetCounters(); // Reset coverage right before the callback.
TPC.ResetMaps(); TPC.ResetMaps();
TPC.ResetGuards(); if (Options.UseCounters)
TPC.ResetGuards();
int Res = CB(DataCopy, Size); int Res = CB(DataCopy, Size);
UnitStopTime = system_clock::now(); UnitStopTime = system_clock::now();
(void)Res; (void)Res;

View File

@ -20,8 +20,8 @@ namespace fuzzer {
TracePC TPC; TracePC TPC;
void TracePC::HandleTrace(uintptr_t *Guard, uintptr_t PC) { void TracePC::HandleTrace(uint32_t *Guard, uintptr_t PC) {
uintptr_t Idx = *Guard; uint32_t Idx = *Guard;
if (!Idx) return; if (!Idx) return;
uint8_t *CounterPtr = &Counters[Idx % kNumCounters]; uint8_t *CounterPtr = &Counters[Idx % kNumCounters];
uint8_t Counter = *CounterPtr; uint8_t Counter = *CounterPtr;
@ -43,10 +43,10 @@ void TracePC::HandleTrace(uintptr_t *Guard, uintptr_t PC) {
} }
} }
void TracePC::HandleInit(uintptr_t *Start, uintptr_t *Stop) { void TracePC::HandleInit(uint32_t *Start, uint32_t *Stop) {
if (Start == Stop || *Start) return; if (Start == Stop || *Start) return;
assert(NumModules < sizeof(Modules) / sizeof(Modules[0])); assert(NumModules < sizeof(Modules) / sizeof(Modules[0]));
for (uintptr_t *P = Start; P < Stop; P++) for (uint32_t *P = Start; P < Stop; P++)
*P = ++NumGuards; *P = ++NumGuards;
Modules[NumModules].Start = Start; Modules[NumModules].Start = Start;
Modules[NumModules].Stop = Stop; Modules[NumModules].Stop = Stop;
@ -61,9 +61,9 @@ void TracePC::PrintModuleInfo() {
} }
void TracePC::ResetGuards() { void TracePC::ResetGuards() {
uintptr_t N = 0; uint32_t N = 0;
for (size_t M = 0; M < NumModules; M++) for (size_t M = 0; M < NumModules; M++)
for (uintptr_t *X = Modules[M].Start; X < Modules[M].Stop; X++) for (uint32_t *X = Modules[M].Start; X < Modules[M].Stop; X++)
*X = ++N; *X = ++N;
assert(N == NumGuards); assert(N == NumGuards);
} }
@ -138,13 +138,13 @@ void TracePC::PrintFeatureSet() {
extern "C" { extern "C" {
__attribute__((visibility("default"))) __attribute__((visibility("default")))
void __sanitizer_cov_trace_pc_guard(uintptr_t *Guard) { void __sanitizer_cov_trace_pc_guard(uint32_t *Guard) {
uintptr_t PC = (uintptr_t)__builtin_return_address(0); uintptr_t PC = (uintptr_t)__builtin_return_address(0);
fuzzer::TPC.HandleTrace(Guard, PC); fuzzer::TPC.HandleTrace(Guard, PC);
} }
__attribute__((visibility("default"))) __attribute__((visibility("default")))
void __sanitizer_cov_trace_pc_guard_init(uintptr_t *Start, uintptr_t *Stop) { void __sanitizer_cov_trace_pc_guard_init(uint32_t *Start, uint32_t *Stop) {
fuzzer::TPC.HandleInit(Start, Stop); fuzzer::TPC.HandleInit(Start, Stop);
} }

View File

@ -19,8 +19,8 @@ namespace fuzzer {
class TracePC { class TracePC {
public: public:
void HandleTrace(uintptr_t *guard, uintptr_t PC); void HandleTrace(uint32_t *guard, uintptr_t PC);
void HandleInit(uintptr_t *start, uintptr_t *stop); void HandleInit(uint32_t *start, uint32_t *stop);
void HandleCallerCallee(uintptr_t Caller, uintptr_t Callee); void HandleCallerCallee(uintptr_t Caller, uintptr_t Callee);
void HandleValueProfile(size_t Value) { ValueProfileMap.AddValue(Value); } void HandleValueProfile(size_t Value) { ValueProfileMap.AddValue(Value); }
size_t GetTotalPCCoverage() { return TotalPCCoverage; } size_t GetTotalPCCoverage() { return TotalPCCoverage; }
@ -71,7 +71,7 @@ private:
} }
struct Module { struct Module {
uintptr_t *Start, *Stop; uint32_t *Start, *Stop;
}; };
Module Modules[4096]; Module Modules[4096];

View File

@ -207,8 +207,10 @@ private:
void InjectTraceForSwitch(Function &F, void InjectTraceForSwitch(Function &F,
ArrayRef<Instruction *> SwitchTraceTargets); ArrayRef<Instruction *> SwitchTraceTargets);
bool InjectCoverage(Function &F, ArrayRef<BasicBlock *> AllBlocks); bool InjectCoverage(Function &F, ArrayRef<BasicBlock *> AllBlocks);
void CreateFunctionGuardArray(size_t NumGuards, Function &F);
void SetNoSanitizeMetadata(Instruction *I); void SetNoSanitizeMetadata(Instruction *I);
void InjectCoverageAtBlock(Function &F, BasicBlock &BB, bool UseCalls); void InjectCoverageAtBlock(Function &F, BasicBlock &BB, size_t Idx,
bool UseCalls);
unsigned NumberOfInstrumentedBlocks() { unsigned NumberOfInstrumentedBlocks() {
return SanCovFunction->getNumUses() + return SanCovFunction->getNumUses() +
SanCovWithCheckFunction->getNumUses() + SanCovTraceBB->getNumUses() + SanCovWithCheckFunction->getNumUses() + SanCovTraceBB->getNumUses() +
@ -223,12 +225,13 @@ private:
Function *SanCovTraceGepFunction; Function *SanCovTraceGepFunction;
Function *SanCovTraceSwitchFunction; Function *SanCovTraceSwitchFunction;
InlineAsm *EmptyAsm; InlineAsm *EmptyAsm;
Type *IntptrTy, *IntptrPtrTy, *Int64Ty, *Int64PtrTy; Type *IntptrTy, *IntptrPtrTy, *Int64Ty, *Int64PtrTy, *Int32Ty, *Int32PtrTy;
Module *CurModule; Module *CurModule;
LLVMContext *C; LLVMContext *C;
const DataLayout *DL; const DataLayout *DL;
GlobalVariable *GuardArray; GlobalVariable *GuardArray;
GlobalVariable *FunctionGuardArray; // for trace-pc-guard.
GlobalVariable *EightBitCounterArray; GlobalVariable *EightBitCounterArray;
bool HasSancovGuardsSection; bool HasSancovGuardsSection;
@ -249,9 +252,10 @@ bool SanitizerCoverageModule::runOnModule(Module &M) {
Type *VoidTy = Type::getVoidTy(*C); Type *VoidTy = Type::getVoidTy(*C);
IRBuilder<> IRB(*C); IRBuilder<> IRB(*C);
Type *Int8PtrTy = PointerType::getUnqual(IRB.getInt8Ty()); Type *Int8PtrTy = PointerType::getUnqual(IRB.getInt8Ty());
Type *Int32PtrTy = PointerType::getUnqual(IRB.getInt32Ty());
Int64PtrTy = PointerType::getUnqual(IRB.getInt64Ty()); Int64PtrTy = PointerType::getUnqual(IRB.getInt64Ty());
Int32PtrTy = PointerType::getUnqual(IRB.getInt32Ty());
Int64Ty = IRB.getInt64Ty(); Int64Ty = IRB.getInt64Ty();
Int32Ty = IRB.getInt32Ty();
SanCovFunction = checkSanitizerInterfaceFunction( SanCovFunction = checkSanitizerInterfaceFunction(
M.getOrInsertFunction(SanCovName, VoidTy, Int32PtrTy, nullptr)); M.getOrInsertFunction(SanCovName, VoidTy, Int32PtrTy, nullptr));
@ -296,7 +300,7 @@ bool SanitizerCoverageModule::runOnModule(Module &M) {
SanCovTracePC = checkSanitizerInterfaceFunction( SanCovTracePC = checkSanitizerInterfaceFunction(
M.getOrInsertFunction(SanCovTracePCName, VoidTy, nullptr)); M.getOrInsertFunction(SanCovTracePCName, VoidTy, nullptr));
SanCovTracePCGuard = checkSanitizerInterfaceFunction(M.getOrInsertFunction( SanCovTracePCGuard = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
SanCovTracePCGuardName, VoidTy, IntptrPtrTy, nullptr)); SanCovTracePCGuardName, VoidTy, Int32PtrTy, nullptr));
SanCovTraceEnter = checkSanitizerInterfaceFunction( SanCovTraceEnter = checkSanitizerInterfaceFunction(
M.getOrInsertFunction(SanCovTraceEnterName, VoidTy, Int32PtrTy, nullptr)); M.getOrInsertFunction(SanCovTraceEnterName, VoidTy, Int32PtrTy, nullptr));
SanCovTraceBB = checkSanitizerInterfaceFunction( SanCovTraceBB = checkSanitizerInterfaceFunction(
@ -307,9 +311,10 @@ bool SanitizerCoverageModule::runOnModule(Module &M) {
Type *Int32Ty = IRB.getInt32Ty(); Type *Int32Ty = IRB.getInt32Ty();
Type *Int8Ty = IRB.getInt8Ty(); Type *Int8Ty = IRB.getInt8Ty();
GuardArray = if (!Options.TracePCGuard)
new GlobalVariable(M, Int32Ty, false, GlobalValue::ExternalLinkage, GuardArray =
nullptr, "__sancov_gen_cov_tmp"); new GlobalVariable(M, Int32Ty, false, GlobalValue::ExternalLinkage,
nullptr, "__sancov_gen_cov_tmp");
if (Options.Use8bitCounters) if (Options.Use8bitCounters)
EightBitCounterArray = EightBitCounterArray =
new GlobalVariable(M, Int8Ty, false, GlobalVariable::ExternalLinkage, new GlobalVariable(M, Int8Ty, false, GlobalVariable::ExternalLinkage,
@ -320,17 +325,20 @@ bool SanitizerCoverageModule::runOnModule(Module &M) {
auto N = NumberOfInstrumentedBlocks(); auto N = NumberOfInstrumentedBlocks();
// Now we know how many elements we need. Create an array of guards GlobalVariable *RealGuardArray = nullptr;
// with one extra element at the beginning for the size. if (!Options.TracePCGuard) {
Type *Int32ArrayNTy = ArrayType::get(Int32Ty, N + 1); // Now we know how many elements we need. Create an array of guards
GlobalVariable *RealGuardArray = new GlobalVariable( // with one extra element at the beginning for the size.
M, Int32ArrayNTy, false, GlobalValue::PrivateLinkage, Type *Int32ArrayNTy = ArrayType::get(Int32Ty, N + 1);
Constant::getNullValue(Int32ArrayNTy), "__sancov_gen_cov"); RealGuardArray = new GlobalVariable(
M, Int32ArrayNTy, false, GlobalValue::PrivateLinkage,
Constant::getNullValue(Int32ArrayNTy), "__sancov_gen_cov");
// Replace the dummy array with the real one. // Replace the dummy array with the real one.
GuardArray->replaceAllUsesWith( GuardArray->replaceAllUsesWith(
IRB.CreatePointerCast(RealGuardArray, Int32PtrTy)); IRB.CreatePointerCast(RealGuardArray, Int32PtrTy));
GuardArray->eraseFromParent(); GuardArray->eraseFromParent();
}
GlobalVariable *RealEightBitCounterArray; GlobalVariable *RealEightBitCounterArray;
if (Options.Use8bitCounters) { if (Options.Use8bitCounters) {
@ -359,16 +367,16 @@ bool SanitizerCoverageModule::runOnModule(Module &M) {
GlobalVariable *Bounds[2]; GlobalVariable *Bounds[2];
const char *Prefix[2] = {"__start_", "__stop_"}; const char *Prefix[2] = {"__start_", "__stop_"};
for (int i = 0; i < 2; i++) { for (int i = 0; i < 2; i++) {
Bounds[i] = new GlobalVariable(M, IntptrPtrTy, false, Bounds[i] = new GlobalVariable(M, Int32PtrTy, false,
GlobalVariable::ExternalLinkage, nullptr, GlobalVariable::ExternalLinkage, nullptr,
Prefix[i] + SectionName); Prefix[i] + SectionName);
Bounds[i]->setVisibility(GlobalValue::HiddenVisibility); Bounds[i]->setVisibility(GlobalValue::HiddenVisibility);
} }
std::tie(CtorFunc, std::ignore) = createSanitizerCtorAndInitFunctions( std::tie(CtorFunc, std::ignore) = createSanitizerCtorAndInitFunctions(
M, SanCovModuleCtorName, SanCovTracePCGuardInitName, M, SanCovModuleCtorName, SanCovTracePCGuardInitName,
{IntptrPtrTy, IntptrPtrTy}, {Int32PtrTy, Int32PtrTy},
{IRB.CreatePointerCast(Bounds[0], IntptrPtrTy), {IRB.CreatePointerCast(Bounds[0], Int32PtrTy),
IRB.CreatePointerCast(Bounds[1], IntptrPtrTy)}); IRB.CreatePointerCast(Bounds[1], Int32PtrTy)});
appendToGlobalCtors(M, CtorFunc, SanCtorAndDtorPriority); appendToGlobalCtors(M, CtorFunc, SanCtorAndDtorPriority);
} }
@ -419,6 +427,14 @@ static bool isFullPostDominator(const BasicBlock *BB,
static bool shouldInstrumentBlock(const Function& F, const BasicBlock *BB, const DominatorTree *DT, static bool shouldInstrumentBlock(const Function& F, const BasicBlock *BB, const DominatorTree *DT,
const PostDominatorTree *PDT) { const PostDominatorTree *PDT) {
// Don't insert coverage for unreachable blocks: we will never call
// __sanitizer_cov() for them, so counting them in
// NumberOfInstrumentedBlocks() might complicate calculation of code coverage
// percentage. Also, unreachable instructions frequently have no debug
// locations.
if (isa<UnreachableInst>(BB->getTerminator()))
return false;
if (!ClPruneBlocks || &F.getEntryBlock() == BB) if (!ClPruneBlocks || &F.getEntryBlock() == BB)
return true; return true;
@ -486,19 +502,34 @@ bool SanitizerCoverageModule::runOnFunction(Function &F) {
InjectTraceForGep(F, GepTraceTargets); InjectTraceForGep(F, GepTraceTargets);
return true; return true;
} }
void SanitizerCoverageModule::CreateFunctionGuardArray(size_t NumGuards, Function &F) {
if (!Options.TracePCGuard) return;
HasSancovGuardsSection = true;
ArrayType *ArrayOfInt32Ty = ArrayType::get(Int32Ty, NumGuards);
FunctionGuardArray = new GlobalVariable(
*CurModule, ArrayOfInt32Ty, false, GlobalVariable::LinkOnceODRLinkage,
Constant::getNullValue(ArrayOfInt32Ty), "__sancov_guard." + F.getName());
if (auto Comdat = F.getComdat())
FunctionGuardArray->setComdat(Comdat);
FunctionGuardArray->setSection(SanCovTracePCGuardSection);
FunctionGuardArray->setVisibility(GlobalValue::HiddenVisibility);
}
bool SanitizerCoverageModule::InjectCoverage(Function &F, bool SanitizerCoverageModule::InjectCoverage(Function &F,
ArrayRef<BasicBlock *> AllBlocks) { ArrayRef<BasicBlock *> AllBlocks) {
if (AllBlocks.empty()) return false;
switch (Options.CoverageType) { switch (Options.CoverageType) {
case SanitizerCoverageOptions::SCK_None: case SanitizerCoverageOptions::SCK_None:
return false; return false;
case SanitizerCoverageOptions::SCK_Function: case SanitizerCoverageOptions::SCK_Function:
InjectCoverageAtBlock(F, F.getEntryBlock(), false); CreateFunctionGuardArray(1, F);
InjectCoverageAtBlock(F, F.getEntryBlock(), 0, false);
return true; return true;
default: { default: {
bool UseCalls = ClCoverageBlockThreshold < AllBlocks.size(); bool UseCalls = ClCoverageBlockThreshold < AllBlocks.size();
for (auto BB : AllBlocks) CreateFunctionGuardArray(AllBlocks.size(), F);
InjectCoverageAtBlock(F, *BB, UseCalls); for (size_t i = 0, N = AllBlocks.size(); i < N; i++)
InjectCoverageAtBlock(F, *AllBlocks[i], i, UseCalls);
return true; return true;
} }
} }
@ -635,16 +666,8 @@ void SanitizerCoverageModule::SetNoSanitizeMetadata(Instruction *I) {
} }
void SanitizerCoverageModule::InjectCoverageAtBlock(Function &F, BasicBlock &BB, void SanitizerCoverageModule::InjectCoverageAtBlock(Function &F, BasicBlock &BB,
bool UseCalls) { size_t Idx, bool UseCalls) {
// Don't insert coverage for unreachable blocks: we will never call
// __sanitizer_cov() for them, so counting them in
// NumberOfInstrumentedBlocks() might complicate calculation of code coverage
// percentage. Also, unreachable instructions frequently have no debug
// locations.
if (isa<UnreachableInst>(BB.getTerminator()))
return;
BasicBlock::iterator IP = BB.getFirstInsertionPt(); BasicBlock::iterator IP = BB.getFirstInsertionPt();
bool IsEntryBB = &BB == &F.getEntryBlock(); bool IsEntryBB = &BB == &F.getEntryBlock();
DebugLoc EntryLoc; DebugLoc EntryLoc;
if (IsEntryBB) { if (IsEntryBB) {
@ -660,24 +683,22 @@ void SanitizerCoverageModule::InjectCoverageAtBlock(Function &F, BasicBlock &BB,
IRBuilder<> IRB(&*IP); IRBuilder<> IRB(&*IP);
IRB.SetCurrentDebugLocation(EntryLoc); IRB.SetCurrentDebugLocation(EntryLoc);
Value *GuardP = IRB.CreateAdd(
IRB.CreatePointerCast(GuardArray, IntptrTy),
ConstantInt::get(IntptrTy, (1 + NumberOfInstrumentedBlocks()) * 4));
Type *Int32PtrTy = PointerType::getUnqual(IRB.getInt32Ty());
GuardP = IRB.CreateIntToPtr(GuardP, Int32PtrTy);
if (Options.TracePC) { if (Options.TracePC) {
IRB.CreateCall(SanCovTracePC); // gets the PC using GET_CALLER_PC. IRB.CreateCall(SanCovTracePC); // gets the PC using GET_CALLER_PC.
IRB.CreateCall(EmptyAsm, {}); // Avoids callback merge. IRB.CreateCall(EmptyAsm, {}); // Avoids callback merge.
} else if (Options.TracePCGuard) { } else if (Options.TracePCGuard) {
auto GuardVar = new GlobalVariable( //auto GuardVar = new GlobalVariable(
*F.getParent(), Int64Ty, false, GlobalVariable::LinkOnceODRLinkage, // *F.getParent(), Int64Ty, false, GlobalVariable::LinkOnceODRLinkage,
Constant::getNullValue(Int64Ty), "__sancov_guard." + F.getName()); // Constant::getNullValue(Int64Ty), "__sancov_guard." + F.getName());
if (auto Comdat = F.getComdat()) // if (auto Comdat = F.getComdat())
GuardVar->setComdat(Comdat); // GuardVar->setComdat(Comdat);
// TODO: add debug into to GuardVar. // TODO: add debug into to GuardVar.
GuardVar->setSection(SanCovTracePCGuardSection); // GuardVar->setSection(SanCovTracePCGuardSection);
HasSancovGuardsSection = true; // auto GuardPtr = IRB.CreatePointerCast(GuardVar, IntptrPtrTy);
auto GuardPtr = IRB.CreatePointerCast(GuardVar, IntptrPtrTy); auto GuardPtr = IRB.CreateIntToPtr(
IRB.CreateAdd(IRB.CreatePointerCast(FunctionGuardArray, IntptrTy),
ConstantInt::get(IntptrTy, Idx * 4)),
Int32PtrTy);
if (!UseCalls) { if (!UseCalls) {
auto GuardLoad = IRB.CreateLoad(GuardPtr); auto GuardLoad = IRB.CreateLoad(GuardPtr);
GuardLoad->setAtomic(AtomicOrdering::Monotonic); GuardLoad->setAtomic(AtomicOrdering::Monotonic);
@ -692,24 +713,30 @@ void SanitizerCoverageModule::InjectCoverageAtBlock(Function &F, BasicBlock &BB,
} }
IRB.CreateCall(SanCovTracePCGuard, GuardPtr); IRB.CreateCall(SanCovTracePCGuard, GuardPtr);
IRB.CreateCall(EmptyAsm, {}); // Avoids callback merge. IRB.CreateCall(EmptyAsm, {}); // Avoids callback merge.
} else if (Options.TraceBB) {
IRB.CreateCall(IsEntryBB ? SanCovTraceEnter : SanCovTraceBB, GuardP);
} else if (UseCalls) {
IRB.CreateCall(SanCovWithCheckFunction, GuardP);
} else { } else {
LoadInst *Load = IRB.CreateLoad(GuardP); Value *GuardP = IRB.CreateAdd(
Load->setAtomic(AtomicOrdering::Monotonic); IRB.CreatePointerCast(GuardArray, IntptrTy),
Load->setAlignment(4); ConstantInt::get(IntptrTy, (1 + NumberOfInstrumentedBlocks()) * 4));
SetNoSanitizeMetadata(Load); GuardP = IRB.CreateIntToPtr(GuardP, Int32PtrTy);
Value *Cmp = if (Options.TraceBB) {
IRB.CreateICmpSGE(Constant::getNullValue(Load->getType()), Load); IRB.CreateCall(IsEntryBB ? SanCovTraceEnter : SanCovTraceBB, GuardP);
Instruction *Ins = SplitBlockAndInsertIfThen( } else if (UseCalls) {
Cmp, &*IP, false, MDBuilder(*C).createBranchWeights(1, 100000)); IRB.CreateCall(SanCovWithCheckFunction, GuardP);
IRB.SetInsertPoint(Ins); } else {
IRB.SetCurrentDebugLocation(EntryLoc); LoadInst *Load = IRB.CreateLoad(GuardP);
// __sanitizer_cov gets the PC of the instruction using GET_CALLER_PC. Load->setAtomic(AtomicOrdering::Monotonic);
IRB.CreateCall(SanCovFunction, GuardP); Load->setAlignment(4);
IRB.CreateCall(EmptyAsm, {}); // Avoids callback merge. SetNoSanitizeMetadata(Load);
Value *Cmp =
IRB.CreateICmpSGE(Constant::getNullValue(Load->getType()), Load);
Instruction *Ins = SplitBlockAndInsertIfThen(
Cmp, &*IP, false, MDBuilder(*C).createBranchWeights(1, 100000));
IRB.SetInsertPoint(Ins);
IRB.SetCurrentDebugLocation(EntryLoc);
// __sanitizer_cov gets the PC of the instruction using GET_CALLER_PC.
IRB.CreateCall(SanCovFunction, GuardP);
IRB.CreateCall(EmptyAsm, {}); // Avoids callback merge.
}
} }
if (Options.Use8bitCounters) { if (Options.Use8bitCounters) {

View File

@ -9,5 +9,4 @@ entry:
ret void ret void
} }
; CHECK: @__sancov_guard.Foo = linkonce_odr global i64 0, section "__sancov_guards", comdat($Foo) ; CHECK: @__sancov_guard.Foo = linkonce_odr hidden global [1 x i32] zeroinitializer, section "__sancov_guards", comdat($Foo)

View File

@ -46,4 +46,4 @@ entry:
; CHECK_PC_GUARD: call void @__sanitizer_cov_trace_pc_guard ; CHECK_PC_GUARD: call void @__sanitizer_cov_trace_pc_guard
; CHECK_PC_GUARD-NOT: call void @__sanitizer_cov_trace_pc ; CHECK_PC_GUARD-NOT: call void @__sanitizer_cov_trace_pc
; CHECK_PC_GUARD: ret void ; CHECK_PC_GUARD: ret void
; CHECK_PC_GUARD: call void @__sanitizer_cov_trace_pc_guard_init(i64* bitcast (i64** @__start___sancov_guards to i64*), i64* bitcast (i64** @__stop___sancov_guards to i64*)) ; CHECK_PC_GUARD: call void @__sanitizer_cov_trace_pc_guard_init(i32* bitcast (i32** @__start___sancov_guards to i32*), i32* bitcast (i32** @__stop___sancov_guards to i32*))