1*08b48e0bSAndroid Build Coastguard Worker //===-- SanitizerCoverage.cpp - coverage instrumentation for sanitizers ---===//
2*08b48e0bSAndroid Build Coastguard Worker //
3*08b48e0bSAndroid Build Coastguard Worker // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*08b48e0bSAndroid Build Coastguard Worker // See https://llvm.org/LICENSE.txt for license information.
5*08b48e0bSAndroid Build Coastguard Worker // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*08b48e0bSAndroid Build Coastguard Worker //
7*08b48e0bSAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
8*08b48e0bSAndroid Build Coastguard Worker //
9*08b48e0bSAndroid Build Coastguard Worker // Coverage instrumentation done on LLVM IR level, works with Sanitizers.
10*08b48e0bSAndroid Build Coastguard Worker //
11*08b48e0bSAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
12*08b48e0bSAndroid Build Coastguard Worker
13*08b48e0bSAndroid Build Coastguard Worker #include "llvm/Transforms/Instrumentation/SanitizerCoverage.h"
14*08b48e0bSAndroid Build Coastguard Worker #include "llvm/ADT/ArrayRef.h"
15*08b48e0bSAndroid Build Coastguard Worker #include "llvm/ADT/SmallVector.h"
16*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 15
17*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR < 17
18*08b48e0bSAndroid Build Coastguard Worker #include "llvm/ADT/Triple.h"
19*08b48e0bSAndroid Build Coastguard Worker #endif
20*08b48e0bSAndroid Build Coastguard Worker #endif
21*08b48e0bSAndroid Build Coastguard Worker #include "llvm/Analysis/PostDominators.h"
22*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR < 15
23*08b48e0bSAndroid Build Coastguard Worker #include "llvm/IR/CFG.h"
24*08b48e0bSAndroid Build Coastguard Worker #endif
25*08b48e0bSAndroid Build Coastguard Worker #include "llvm/IR/Constant.h"
26*08b48e0bSAndroid Build Coastguard Worker #include "llvm/IR/DataLayout.h"
27*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR < 15
28*08b48e0bSAndroid Build Coastguard Worker #include "llvm/IR/DebugInfo.h"
29*08b48e0bSAndroid Build Coastguard Worker #endif
30*08b48e0bSAndroid Build Coastguard Worker #include "llvm/IR/Dominators.h"
31*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 17
32*08b48e0bSAndroid Build Coastguard Worker #include "llvm/IR/EHPersonalities.h"
33*08b48e0bSAndroid Build Coastguard Worker #else
34*08b48e0bSAndroid Build Coastguard Worker #include "llvm/Analysis/EHPersonalities.h"
35*08b48e0bSAndroid Build Coastguard Worker #endif
36*08b48e0bSAndroid Build Coastguard Worker #include "llvm/IR/Function.h"
37*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 16
38*08b48e0bSAndroid Build Coastguard Worker #include "llvm/IR/GlobalVariable.h"
39*08b48e0bSAndroid Build Coastguard Worker #endif
40*08b48e0bSAndroid Build Coastguard Worker #include "llvm/IR/IRBuilder.h"
41*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR < 15
42*08b48e0bSAndroid Build Coastguard Worker #include "llvm/IR/InlineAsm.h"
43*08b48e0bSAndroid Build Coastguard Worker #endif
44*08b48e0bSAndroid Build Coastguard Worker #include "llvm/IR/IntrinsicInst.h"
45*08b48e0bSAndroid Build Coastguard Worker #include "llvm/IR/Intrinsics.h"
46*08b48e0bSAndroid Build Coastguard Worker #include "llvm/IR/LLVMContext.h"
47*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR < 15
48*08b48e0bSAndroid Build Coastguard Worker #include "llvm/IR/MDBuilder.h"
49*08b48e0bSAndroid Build Coastguard Worker #include "llvm/IR/Mangler.h"
50*08b48e0bSAndroid Build Coastguard Worker #endif
51*08b48e0bSAndroid Build Coastguard Worker #include "llvm/IR/Module.h"
52*08b48e0bSAndroid Build Coastguard Worker #include "llvm/IR/PassManager.h"
53*08b48e0bSAndroid Build Coastguard Worker #include "llvm/Passes/PassBuilder.h"
54*08b48e0bSAndroid Build Coastguard Worker #include "llvm/Passes/PassPlugin.h"
55*08b48e0bSAndroid Build Coastguard Worker #include "llvm/IR/Type.h"
56*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR < 17
57*08b48e0bSAndroid Build Coastguard Worker #include "llvm/InitializePasses.h"
58*08b48e0bSAndroid Build Coastguard Worker #endif
59*08b48e0bSAndroid Build Coastguard Worker #include "llvm/Support/CommandLine.h"
60*08b48e0bSAndroid Build Coastguard Worker #include "llvm/Support/Debug.h"
61*08b48e0bSAndroid Build Coastguard Worker #include "llvm/Support/SpecialCaseList.h"
62*08b48e0bSAndroid Build Coastguard Worker #include "llvm/Support/VirtualFileSystem.h"
63*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR < 15
64*08b48e0bSAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
65*08b48e0bSAndroid Build Coastguard Worker #endif
66*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR < 17
67*08b48e0bSAndroid Build Coastguard Worker #include "llvm/Transforms/Instrumentation.h"
68*08b48e0bSAndroid Build Coastguard Worker #else
69*08b48e0bSAndroid Build Coastguard Worker #include "llvm/TargetParser/Triple.h"
70*08b48e0bSAndroid Build Coastguard Worker #endif
71*08b48e0bSAndroid Build Coastguard Worker #include "llvm/Transforms/Utils/BasicBlockUtils.h"
72*08b48e0bSAndroid Build Coastguard Worker #include "llvm/Transforms/Utils/ModuleUtils.h"
73*08b48e0bSAndroid Build Coastguard Worker
74*08b48e0bSAndroid Build Coastguard Worker #include "config.h"
75*08b48e0bSAndroid Build Coastguard Worker #include "debug.h"
76*08b48e0bSAndroid Build Coastguard Worker #include "afl-llvm-common.h"
77*08b48e0bSAndroid Build Coastguard Worker
78*08b48e0bSAndroid Build Coastguard Worker using namespace llvm;
79*08b48e0bSAndroid Build Coastguard Worker
80*08b48e0bSAndroid Build Coastguard Worker #define DEBUG_TYPE "sancov"
81*08b48e0bSAndroid Build Coastguard Worker
82*08b48e0bSAndroid Build Coastguard Worker static const uint64_t SanCtorAndDtorPriority = 2;
83*08b48e0bSAndroid Build Coastguard Worker
84*08b48e0bSAndroid Build Coastguard Worker const char SanCovTracePCName[] = "__sanitizer_cov_trace_pc";
85*08b48e0bSAndroid Build Coastguard Worker const char SanCovTraceCmp1[] = "__sanitizer_cov_trace_cmp1";
86*08b48e0bSAndroid Build Coastguard Worker const char SanCovTraceCmp2[] = "__sanitizer_cov_trace_cmp2";
87*08b48e0bSAndroid Build Coastguard Worker const char SanCovTraceCmp4[] = "__sanitizer_cov_trace_cmp4";
88*08b48e0bSAndroid Build Coastguard Worker const char SanCovTraceCmp8[] = "__sanitizer_cov_trace_cmp8";
89*08b48e0bSAndroid Build Coastguard Worker const char SanCovTraceConstCmp1[] = "__sanitizer_cov_trace_const_cmp1";
90*08b48e0bSAndroid Build Coastguard Worker const char SanCovTraceConstCmp2[] = "__sanitizer_cov_trace_const_cmp2";
91*08b48e0bSAndroid Build Coastguard Worker const char SanCovTraceConstCmp4[] = "__sanitizer_cov_trace_const_cmp4";
92*08b48e0bSAndroid Build Coastguard Worker const char SanCovTraceConstCmp8[] = "__sanitizer_cov_trace_const_cmp8";
93*08b48e0bSAndroid Build Coastguard Worker const char SanCovTraceSwitchName[] = "__sanitizer_cov_trace_switch";
94*08b48e0bSAndroid Build Coastguard Worker
95*08b48e0bSAndroid Build Coastguard Worker const char SanCovModuleCtorTracePcGuardName[] =
96*08b48e0bSAndroid Build Coastguard Worker "sancov.module_ctor_trace_pc_guard";
97*08b48e0bSAndroid Build Coastguard Worker const char SanCovTracePCGuardInitName[] = "__sanitizer_cov_trace_pc_guard_init";
98*08b48e0bSAndroid Build Coastguard Worker
99*08b48e0bSAndroid Build Coastguard Worker const char SanCovTracePCGuardName[] = "__sanitizer_cov_trace_pc_guard";
100*08b48e0bSAndroid Build Coastguard Worker
101*08b48e0bSAndroid Build Coastguard Worker const char SanCovGuardsSectionName[] = "sancov_guards";
102*08b48e0bSAndroid Build Coastguard Worker const char SanCovCountersSectionName[] = "sancov_cntrs";
103*08b48e0bSAndroid Build Coastguard Worker const char SanCovBoolFlagSectionName[] = "sancov_bools";
104*08b48e0bSAndroid Build Coastguard Worker const char SanCovPCsSectionName[] = "sancov_pcs";
105*08b48e0bSAndroid Build Coastguard Worker
106*08b48e0bSAndroid Build Coastguard Worker const char SanCovLowestStackName[] = "__sancov_lowest_stack";
107*08b48e0bSAndroid Build Coastguard Worker
108*08b48e0bSAndroid Build Coastguard Worker static const char *skip_nozero;
109*08b48e0bSAndroid Build Coastguard Worker static const char *use_threadsafe_counters;
110*08b48e0bSAndroid Build Coastguard Worker
111*08b48e0bSAndroid Build Coastguard Worker namespace {
112*08b48e0bSAndroid Build Coastguard Worker
OverrideFromCL(SanitizerCoverageOptions Options)113*08b48e0bSAndroid Build Coastguard Worker SanitizerCoverageOptions OverrideFromCL(SanitizerCoverageOptions Options) {
114*08b48e0bSAndroid Build Coastguard Worker
115*08b48e0bSAndroid Build Coastguard Worker Options.CoverageType = SanitizerCoverageOptions::SCK_Edge;
116*08b48e0bSAndroid Build Coastguard Worker // Options.NoPrune = true;
117*08b48e0bSAndroid Build Coastguard Worker Options.TracePCGuard = true; // TracePCGuard is default.
118*08b48e0bSAndroid Build Coastguard Worker return Options;
119*08b48e0bSAndroid Build Coastguard Worker
120*08b48e0bSAndroid Build Coastguard Worker }
121*08b48e0bSAndroid Build Coastguard Worker
122*08b48e0bSAndroid Build Coastguard Worker using DomTreeCallback = function_ref<const DominatorTree *(Function &F)>;
123*08b48e0bSAndroid Build Coastguard Worker using PostDomTreeCallback =
124*08b48e0bSAndroid Build Coastguard Worker function_ref<const PostDominatorTree *(Function &F)>;
125*08b48e0bSAndroid Build Coastguard Worker
126*08b48e0bSAndroid Build Coastguard Worker class ModuleSanitizerCoverageAFL
127*08b48e0bSAndroid Build Coastguard Worker : public PassInfoMixin<ModuleSanitizerCoverageAFL> {
128*08b48e0bSAndroid Build Coastguard Worker
129*08b48e0bSAndroid Build Coastguard Worker public:
ModuleSanitizerCoverageAFL(const SanitizerCoverageOptions & Options=SanitizerCoverageOptions ())130*08b48e0bSAndroid Build Coastguard Worker ModuleSanitizerCoverageAFL(
131*08b48e0bSAndroid Build Coastguard Worker const SanitizerCoverageOptions &Options = SanitizerCoverageOptions())
132*08b48e0bSAndroid Build Coastguard Worker : Options(OverrideFromCL(Options)) {
133*08b48e0bSAndroid Build Coastguard Worker
134*08b48e0bSAndroid Build Coastguard Worker }
135*08b48e0bSAndroid Build Coastguard Worker
136*08b48e0bSAndroid Build Coastguard Worker PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
137*08b48e0bSAndroid Build Coastguard Worker bool instrumentModule(Module &M, DomTreeCallback DTCallback,
138*08b48e0bSAndroid Build Coastguard Worker PostDomTreeCallback PDTCallback);
139*08b48e0bSAndroid Build Coastguard Worker
140*08b48e0bSAndroid Build Coastguard Worker private:
141*08b48e0bSAndroid Build Coastguard Worker void instrumentFunction(Function &F, DomTreeCallback DTCallback,
142*08b48e0bSAndroid Build Coastguard Worker PostDomTreeCallback PDTCallback);
143*08b48e0bSAndroid Build Coastguard Worker void InjectTraceForCmp(Function &F, ArrayRef<Instruction *> CmpTraceTargets);
144*08b48e0bSAndroid Build Coastguard Worker void InjectTraceForSwitch(Function &F,
145*08b48e0bSAndroid Build Coastguard Worker ArrayRef<Instruction *> SwitchTraceTargets);
146*08b48e0bSAndroid Build Coastguard Worker bool InjectCoverage(Function &F, ArrayRef<BasicBlock *> AllBlocks,
147*08b48e0bSAndroid Build Coastguard Worker bool IsLeafFunc = true);
148*08b48e0bSAndroid Build Coastguard Worker GlobalVariable *CreateFunctionLocalArrayInSection(size_t NumElements,
149*08b48e0bSAndroid Build Coastguard Worker Function &F, Type *Ty,
150*08b48e0bSAndroid Build Coastguard Worker const char *Section);
151*08b48e0bSAndroid Build Coastguard Worker GlobalVariable *CreatePCArray(Function &F, ArrayRef<BasicBlock *> AllBlocks);
152*08b48e0bSAndroid Build Coastguard Worker void CreateFunctionLocalArrays(Function &F, ArrayRef<BasicBlock *> AllBlocks,
153*08b48e0bSAndroid Build Coastguard Worker uint32_t special);
154*08b48e0bSAndroid Build Coastguard Worker void InjectCoverageAtBlock(Function &F, BasicBlock &BB, size_t Idx,
155*08b48e0bSAndroid Build Coastguard Worker bool IsLeafFunc = true);
156*08b48e0bSAndroid Build Coastguard Worker Function *CreateInitCallsForSections(Module &M, const char *CtorName,
157*08b48e0bSAndroid Build Coastguard Worker const char *InitFunctionName, Type *Ty,
158*08b48e0bSAndroid Build Coastguard Worker const char *Section);
159*08b48e0bSAndroid Build Coastguard Worker std::pair<Value *, Value *> CreateSecStartEnd(Module &M, const char *Section,
160*08b48e0bSAndroid Build Coastguard Worker Type *Ty);
161*08b48e0bSAndroid Build Coastguard Worker
SetNoSanitizeMetadata(Instruction * I)162*08b48e0bSAndroid Build Coastguard Worker void SetNoSanitizeMetadata(Instruction *I) {
163*08b48e0bSAndroid Build Coastguard Worker
164*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 16
165*08b48e0bSAndroid Build Coastguard Worker I->setMetadata(LLVMContext::MD_nosanitize, MDNode::get(*C, std::nullopt));
166*08b48e0bSAndroid Build Coastguard Worker #else
167*08b48e0bSAndroid Build Coastguard Worker I->setMetadata(I->getModule()->getMDKindID("nosanitize"),
168*08b48e0bSAndroid Build Coastguard Worker MDNode::get(*C, None));
169*08b48e0bSAndroid Build Coastguard Worker #endif
170*08b48e0bSAndroid Build Coastguard Worker
171*08b48e0bSAndroid Build Coastguard Worker }
172*08b48e0bSAndroid Build Coastguard Worker
173*08b48e0bSAndroid Build Coastguard Worker std::string getSectionName(const std::string &Section) const;
174*08b48e0bSAndroid Build Coastguard Worker std::string getSectionStart(const std::string &Section) const;
175*08b48e0bSAndroid Build Coastguard Worker std::string getSectionEnd(const std::string &Section) const;
176*08b48e0bSAndroid Build Coastguard Worker FunctionCallee SanCovTracePC, SanCovTracePCGuard;
177*08b48e0bSAndroid Build Coastguard Worker FunctionCallee SanCovTraceCmpFunction[4];
178*08b48e0bSAndroid Build Coastguard Worker FunctionCallee SanCovTraceConstCmpFunction[4];
179*08b48e0bSAndroid Build Coastguard Worker FunctionCallee SanCovTraceSwitchFunction;
180*08b48e0bSAndroid Build Coastguard Worker GlobalVariable *SanCovLowestStack;
181*08b48e0bSAndroid Build Coastguard Worker Type *IntptrTy, *IntptrPtrTy, *Int64Ty, *Int64PtrTy, *Int32Ty, *Int32PtrTy,
182*08b48e0bSAndroid Build Coastguard Worker *Int16Ty, *Int8Ty, *Int8PtrTy, *Int1Ty, *Int1PtrTy;
183*08b48e0bSAndroid Build Coastguard Worker Module *CurModule;
184*08b48e0bSAndroid Build Coastguard Worker std::string CurModuleUniqueId;
185*08b48e0bSAndroid Build Coastguard Worker Triple TargetTriple;
186*08b48e0bSAndroid Build Coastguard Worker LLVMContext *C;
187*08b48e0bSAndroid Build Coastguard Worker const DataLayout *DL;
188*08b48e0bSAndroid Build Coastguard Worker
189*08b48e0bSAndroid Build Coastguard Worker GlobalVariable *FunctionGuardArray; // for trace-pc-guard.
190*08b48e0bSAndroid Build Coastguard Worker GlobalVariable *Function8bitCounterArray; // for inline-8bit-counters.
191*08b48e0bSAndroid Build Coastguard Worker GlobalVariable *FunctionBoolArray; // for inline-bool-flag.
192*08b48e0bSAndroid Build Coastguard Worker GlobalVariable *FunctionPCsArray; // for pc-table.
193*08b48e0bSAndroid Build Coastguard Worker SmallVector<GlobalValue *, 20> GlobalsToAppendToUsed;
194*08b48e0bSAndroid Build Coastguard Worker SmallVector<GlobalValue *, 20> GlobalsToAppendToCompilerUsed;
195*08b48e0bSAndroid Build Coastguard Worker
196*08b48e0bSAndroid Build Coastguard Worker SanitizerCoverageOptions Options;
197*08b48e0bSAndroid Build Coastguard Worker
198*08b48e0bSAndroid Build Coastguard Worker uint32_t instr = 0, selects = 0, unhandled = 0;
199*08b48e0bSAndroid Build Coastguard Worker GlobalVariable *AFLMapPtr = NULL;
200*08b48e0bSAndroid Build Coastguard Worker ConstantInt *One = NULL;
201*08b48e0bSAndroid Build Coastguard Worker ConstantInt *Zero = NULL;
202*08b48e0bSAndroid Build Coastguard Worker
203*08b48e0bSAndroid Build Coastguard Worker };
204*08b48e0bSAndroid Build Coastguard Worker
205*08b48e0bSAndroid Build Coastguard Worker } // namespace
206*08b48e0bSAndroid Build Coastguard Worker
207*08b48e0bSAndroid Build Coastguard Worker extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK
llvmGetPassPluginInfo()208*08b48e0bSAndroid Build Coastguard Worker llvmGetPassPluginInfo() {
209*08b48e0bSAndroid Build Coastguard Worker
210*08b48e0bSAndroid Build Coastguard Worker return {LLVM_PLUGIN_API_VERSION, "SanitizerCoveragePCGUARD", "v0.2",
211*08b48e0bSAndroid Build Coastguard Worker /* lambda to insert our pass into the pass pipeline. */
212*08b48e0bSAndroid Build Coastguard Worker [](PassBuilder &PB) {
213*08b48e0bSAndroid Build Coastguard Worker
214*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR == 13
215*08b48e0bSAndroid Build Coastguard Worker using OptimizationLevel = typename PassBuilder::OptimizationLevel;
216*08b48e0bSAndroid Build Coastguard Worker #endif
217*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 16
218*08b48e0bSAndroid Build Coastguard Worker PB.registerOptimizerEarlyEPCallback(
219*08b48e0bSAndroid Build Coastguard Worker #else
220*08b48e0bSAndroid Build Coastguard Worker PB.registerOptimizerLastEPCallback(
221*08b48e0bSAndroid Build Coastguard Worker #endif
222*08b48e0bSAndroid Build Coastguard Worker [](ModulePassManager &MPM, OptimizationLevel OL) {
223*08b48e0bSAndroid Build Coastguard Worker
224*08b48e0bSAndroid Build Coastguard Worker MPM.addPass(ModuleSanitizerCoverageAFL());
225*08b48e0bSAndroid Build Coastguard Worker
226*08b48e0bSAndroid Build Coastguard Worker });
227*08b48e0bSAndroid Build Coastguard Worker
228*08b48e0bSAndroid Build Coastguard Worker }};
229*08b48e0bSAndroid Build Coastguard Worker
230*08b48e0bSAndroid Build Coastguard Worker }
231*08b48e0bSAndroid Build Coastguard Worker
run(Module & M,ModuleAnalysisManager & MAM)232*08b48e0bSAndroid Build Coastguard Worker PreservedAnalyses ModuleSanitizerCoverageAFL::run(Module &M,
233*08b48e0bSAndroid Build Coastguard Worker ModuleAnalysisManager &MAM) {
234*08b48e0bSAndroid Build Coastguard Worker
235*08b48e0bSAndroid Build Coastguard Worker ModuleSanitizerCoverageAFL ModuleSancov(Options);
236*08b48e0bSAndroid Build Coastguard Worker auto &FAM = MAM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
237*08b48e0bSAndroid Build Coastguard Worker auto DTCallback = [&FAM](Function &F) -> const DominatorTree *{
238*08b48e0bSAndroid Build Coastguard Worker
239*08b48e0bSAndroid Build Coastguard Worker return &FAM.getResult<DominatorTreeAnalysis>(F);
240*08b48e0bSAndroid Build Coastguard Worker
241*08b48e0bSAndroid Build Coastguard Worker };
242*08b48e0bSAndroid Build Coastguard Worker
243*08b48e0bSAndroid Build Coastguard Worker auto PDTCallback = [&FAM](Function &F) -> const PostDominatorTree * {
244*08b48e0bSAndroid Build Coastguard Worker
245*08b48e0bSAndroid Build Coastguard Worker return &FAM.getResult<PostDominatorTreeAnalysis>(F);
246*08b48e0bSAndroid Build Coastguard Worker
247*08b48e0bSAndroid Build Coastguard Worker };
248*08b48e0bSAndroid Build Coastguard Worker
249*08b48e0bSAndroid Build Coastguard Worker if (ModuleSancov.instrumentModule(M, DTCallback, PDTCallback))
250*08b48e0bSAndroid Build Coastguard Worker return PreservedAnalyses::none();
251*08b48e0bSAndroid Build Coastguard Worker return PreservedAnalyses::all();
252*08b48e0bSAndroid Build Coastguard Worker
253*08b48e0bSAndroid Build Coastguard Worker }
254*08b48e0bSAndroid Build Coastguard Worker
CreateSecStartEnd(Module & M,const char * Section,Type * Ty)255*08b48e0bSAndroid Build Coastguard Worker std::pair<Value *, Value *> ModuleSanitizerCoverageAFL::CreateSecStartEnd(
256*08b48e0bSAndroid Build Coastguard Worker Module &M, const char *Section, Type *Ty) {
257*08b48e0bSAndroid Build Coastguard Worker
258*08b48e0bSAndroid Build Coastguard Worker // Use ExternalWeak so that if all sections are discarded due to section
259*08b48e0bSAndroid Build Coastguard Worker // garbage collection, the linker will not report undefined symbol errors.
260*08b48e0bSAndroid Build Coastguard Worker // Windows defines the start/stop symbols in compiler-rt so no need for
261*08b48e0bSAndroid Build Coastguard Worker // ExternalWeak.
262*08b48e0bSAndroid Build Coastguard Worker GlobalValue::LinkageTypes Linkage = TargetTriple.isOSBinFormatCOFF()
263*08b48e0bSAndroid Build Coastguard Worker ? GlobalVariable::ExternalLinkage
264*08b48e0bSAndroid Build Coastguard Worker : GlobalVariable::ExternalWeakLinkage;
265*08b48e0bSAndroid Build Coastguard Worker GlobalVariable *SecStart = new GlobalVariable(M, Ty, false, Linkage, nullptr,
266*08b48e0bSAndroid Build Coastguard Worker getSectionStart(Section));
267*08b48e0bSAndroid Build Coastguard Worker SecStart->setVisibility(GlobalValue::HiddenVisibility);
268*08b48e0bSAndroid Build Coastguard Worker GlobalVariable *SecEnd = new GlobalVariable(M, Ty, false, Linkage, nullptr,
269*08b48e0bSAndroid Build Coastguard Worker getSectionEnd(Section));
270*08b48e0bSAndroid Build Coastguard Worker SecEnd->setVisibility(GlobalValue::HiddenVisibility);
271*08b48e0bSAndroid Build Coastguard Worker IRBuilder<> IRB(M.getContext());
272*08b48e0bSAndroid Build Coastguard Worker if (!TargetTriple.isOSBinFormatCOFF())
273*08b48e0bSAndroid Build Coastguard Worker return std::make_pair(SecStart, SecEnd);
274*08b48e0bSAndroid Build Coastguard Worker
275*08b48e0bSAndroid Build Coastguard Worker // Account for the fact that on windows-msvc __start_* symbols actually
276*08b48e0bSAndroid Build Coastguard Worker // point to a uint64_t before the start of the array.
277*08b48e0bSAndroid Build Coastguard Worker auto SecStartI8Ptr = IRB.CreatePointerCast(SecStart, Int8PtrTy);
278*08b48e0bSAndroid Build Coastguard Worker auto GEP = IRB.CreateGEP(Int8Ty, SecStartI8Ptr,
279*08b48e0bSAndroid Build Coastguard Worker ConstantInt::get(IntptrTy, sizeof(uint64_t)));
280*08b48e0bSAndroid Build Coastguard Worker return std::make_pair(IRB.CreatePointerCast(GEP, PointerType::getUnqual(Ty)),
281*08b48e0bSAndroid Build Coastguard Worker SecEnd);
282*08b48e0bSAndroid Build Coastguard Worker
283*08b48e0bSAndroid Build Coastguard Worker }
284*08b48e0bSAndroid Build Coastguard Worker
CreateInitCallsForSections(Module & M,const char * CtorName,const char * InitFunctionName,Type * Ty,const char * Section)285*08b48e0bSAndroid Build Coastguard Worker Function *ModuleSanitizerCoverageAFL::CreateInitCallsForSections(
286*08b48e0bSAndroid Build Coastguard Worker Module &M, const char *CtorName, const char *InitFunctionName, Type *Ty,
287*08b48e0bSAndroid Build Coastguard Worker const char *Section) {
288*08b48e0bSAndroid Build Coastguard Worker
289*08b48e0bSAndroid Build Coastguard Worker auto SecStartEnd = CreateSecStartEnd(M, Section, Ty);
290*08b48e0bSAndroid Build Coastguard Worker auto SecStart = SecStartEnd.first;
291*08b48e0bSAndroid Build Coastguard Worker auto SecEnd = SecStartEnd.second;
292*08b48e0bSAndroid Build Coastguard Worker Function *CtorFunc;
293*08b48e0bSAndroid Build Coastguard Worker Type *PtrTy = PointerType::getUnqual(Ty);
294*08b48e0bSAndroid Build Coastguard Worker std::tie(CtorFunc, std::ignore) = createSanitizerCtorAndInitFunctions(
295*08b48e0bSAndroid Build Coastguard Worker M, CtorName, InitFunctionName, {PtrTy, PtrTy}, {SecStart, SecEnd});
296*08b48e0bSAndroid Build Coastguard Worker assert(CtorFunc->getName() == CtorName);
297*08b48e0bSAndroid Build Coastguard Worker
298*08b48e0bSAndroid Build Coastguard Worker if (TargetTriple.supportsCOMDAT()) {
299*08b48e0bSAndroid Build Coastguard Worker
300*08b48e0bSAndroid Build Coastguard Worker // Use comdat to dedup CtorFunc.
301*08b48e0bSAndroid Build Coastguard Worker CtorFunc->setComdat(M.getOrInsertComdat(CtorName));
302*08b48e0bSAndroid Build Coastguard Worker appendToGlobalCtors(M, CtorFunc, SanCtorAndDtorPriority, CtorFunc);
303*08b48e0bSAndroid Build Coastguard Worker
304*08b48e0bSAndroid Build Coastguard Worker } else {
305*08b48e0bSAndroid Build Coastguard Worker
306*08b48e0bSAndroid Build Coastguard Worker appendToGlobalCtors(M, CtorFunc, SanCtorAndDtorPriority);
307*08b48e0bSAndroid Build Coastguard Worker
308*08b48e0bSAndroid Build Coastguard Worker }
309*08b48e0bSAndroid Build Coastguard Worker
310*08b48e0bSAndroid Build Coastguard Worker if (TargetTriple.isOSBinFormatCOFF()) {
311*08b48e0bSAndroid Build Coastguard Worker
312*08b48e0bSAndroid Build Coastguard Worker // In COFF files, if the contructors are set as COMDAT (they are because
313*08b48e0bSAndroid Build Coastguard Worker // COFF supports COMDAT) and the linker flag /OPT:REF (strip unreferenced
314*08b48e0bSAndroid Build Coastguard Worker // functions and data) is used, the constructors get stripped. To prevent
315*08b48e0bSAndroid Build Coastguard Worker // this, give the constructors weak ODR linkage and ensure the linker knows
316*08b48e0bSAndroid Build Coastguard Worker // to include the sancov constructor. This way the linker can deduplicate
317*08b48e0bSAndroid Build Coastguard Worker // the constructors but always leave one copy.
318*08b48e0bSAndroid Build Coastguard Worker CtorFunc->setLinkage(GlobalValue::WeakODRLinkage);
319*08b48e0bSAndroid Build Coastguard Worker
320*08b48e0bSAndroid Build Coastguard Worker }
321*08b48e0bSAndroid Build Coastguard Worker
322*08b48e0bSAndroid Build Coastguard Worker return CtorFunc;
323*08b48e0bSAndroid Build Coastguard Worker
324*08b48e0bSAndroid Build Coastguard Worker }
325*08b48e0bSAndroid Build Coastguard Worker
instrumentModule(Module & M,DomTreeCallback DTCallback,PostDomTreeCallback PDTCallback)326*08b48e0bSAndroid Build Coastguard Worker bool ModuleSanitizerCoverageAFL::instrumentModule(
327*08b48e0bSAndroid Build Coastguard Worker Module &M, DomTreeCallback DTCallback, PostDomTreeCallback PDTCallback) {
328*08b48e0bSAndroid Build Coastguard Worker
329*08b48e0bSAndroid Build Coastguard Worker setvbuf(stdout, NULL, _IONBF, 0);
330*08b48e0bSAndroid Build Coastguard Worker
331*08b48e0bSAndroid Build Coastguard Worker if (getenv("AFL_DEBUG")) { debug = 1; }
332*08b48e0bSAndroid Build Coastguard Worker
333*08b48e0bSAndroid Build Coastguard Worker if ((isatty(2) && !getenv("AFL_QUIET")) || debug) {
334*08b48e0bSAndroid Build Coastguard Worker
335*08b48e0bSAndroid Build Coastguard Worker SAYF(cCYA "SanitizerCoveragePCGUARD" VERSION cRST "\n");
336*08b48e0bSAndroid Build Coastguard Worker
337*08b48e0bSAndroid Build Coastguard Worker } else {
338*08b48e0bSAndroid Build Coastguard Worker
339*08b48e0bSAndroid Build Coastguard Worker be_quiet = 1;
340*08b48e0bSAndroid Build Coastguard Worker
341*08b48e0bSAndroid Build Coastguard Worker }
342*08b48e0bSAndroid Build Coastguard Worker
343*08b48e0bSAndroid Build Coastguard Worker skip_nozero = getenv("AFL_LLVM_SKIP_NEVERZERO");
344*08b48e0bSAndroid Build Coastguard Worker use_threadsafe_counters = getenv("AFL_LLVM_THREADSAFE_INST");
345*08b48e0bSAndroid Build Coastguard Worker
346*08b48e0bSAndroid Build Coastguard Worker initInstrumentList();
347*08b48e0bSAndroid Build Coastguard Worker scanForDangerousFunctions(&M);
348*08b48e0bSAndroid Build Coastguard Worker
349*08b48e0bSAndroid Build Coastguard Worker C = &(M.getContext());
350*08b48e0bSAndroid Build Coastguard Worker DL = &M.getDataLayout();
351*08b48e0bSAndroid Build Coastguard Worker CurModule = &M;
352*08b48e0bSAndroid Build Coastguard Worker CurModuleUniqueId = getUniqueModuleId(CurModule);
353*08b48e0bSAndroid Build Coastguard Worker TargetTriple = Triple(M.getTargetTriple());
354*08b48e0bSAndroid Build Coastguard Worker FunctionGuardArray = nullptr;
355*08b48e0bSAndroid Build Coastguard Worker Function8bitCounterArray = nullptr;
356*08b48e0bSAndroid Build Coastguard Worker FunctionBoolArray = nullptr;
357*08b48e0bSAndroid Build Coastguard Worker FunctionPCsArray = nullptr;
358*08b48e0bSAndroid Build Coastguard Worker IntptrTy = Type::getIntNTy(*C, DL->getPointerSizeInBits());
359*08b48e0bSAndroid Build Coastguard Worker IntptrPtrTy = PointerType::getUnqual(IntptrTy);
360*08b48e0bSAndroid Build Coastguard Worker Type *VoidTy = Type::getVoidTy(*C);
361*08b48e0bSAndroid Build Coastguard Worker IRBuilder<> IRB(*C);
362*08b48e0bSAndroid Build Coastguard Worker Int64PtrTy = PointerType::getUnqual(IRB.getInt64Ty());
363*08b48e0bSAndroid Build Coastguard Worker Int32PtrTy = PointerType::getUnqual(IRB.getInt32Ty());
364*08b48e0bSAndroid Build Coastguard Worker Int8PtrTy = PointerType::getUnqual(IRB.getInt8Ty());
365*08b48e0bSAndroid Build Coastguard Worker Int1PtrTy = PointerType::getUnqual(IRB.getInt1Ty());
366*08b48e0bSAndroid Build Coastguard Worker Int64Ty = IRB.getInt64Ty();
367*08b48e0bSAndroid Build Coastguard Worker Int32Ty = IRB.getInt32Ty();
368*08b48e0bSAndroid Build Coastguard Worker Int16Ty = IRB.getInt16Ty();
369*08b48e0bSAndroid Build Coastguard Worker Int8Ty = IRB.getInt8Ty();
370*08b48e0bSAndroid Build Coastguard Worker Int1Ty = IRB.getInt1Ty();
371*08b48e0bSAndroid Build Coastguard Worker
372*08b48e0bSAndroid Build Coastguard Worker LLVMContext &Ctx = M.getContext();
373*08b48e0bSAndroid Build Coastguard Worker AFLMapPtr =
374*08b48e0bSAndroid Build Coastguard Worker new GlobalVariable(M, PointerType::get(Int8Ty, 0), false,
375*08b48e0bSAndroid Build Coastguard Worker GlobalValue::ExternalLinkage, 0, "__afl_area_ptr");
376*08b48e0bSAndroid Build Coastguard Worker One = ConstantInt::get(IntegerType::getInt8Ty(Ctx), 1);
377*08b48e0bSAndroid Build Coastguard Worker Zero = ConstantInt::get(IntegerType::getInt8Ty(Ctx), 0);
378*08b48e0bSAndroid Build Coastguard Worker
379*08b48e0bSAndroid Build Coastguard Worker // Make sure smaller parameters are zero-extended to i64 if required by the
380*08b48e0bSAndroid Build Coastguard Worker // target ABI.
381*08b48e0bSAndroid Build Coastguard Worker AttributeList SanCovTraceCmpZeroExtAL;
382*08b48e0bSAndroid Build Coastguard Worker SanCovTraceCmpZeroExtAL =
383*08b48e0bSAndroid Build Coastguard Worker SanCovTraceCmpZeroExtAL.addParamAttribute(*C, 0, Attribute::ZExt);
384*08b48e0bSAndroid Build Coastguard Worker SanCovTraceCmpZeroExtAL =
385*08b48e0bSAndroid Build Coastguard Worker SanCovTraceCmpZeroExtAL.addParamAttribute(*C, 1, Attribute::ZExt);
386*08b48e0bSAndroid Build Coastguard Worker
387*08b48e0bSAndroid Build Coastguard Worker SanCovTraceCmpFunction[0] =
388*08b48e0bSAndroid Build Coastguard Worker M.getOrInsertFunction(SanCovTraceCmp1, SanCovTraceCmpZeroExtAL, VoidTy,
389*08b48e0bSAndroid Build Coastguard Worker IRB.getInt8Ty(), IRB.getInt8Ty());
390*08b48e0bSAndroid Build Coastguard Worker SanCovTraceCmpFunction[1] =
391*08b48e0bSAndroid Build Coastguard Worker M.getOrInsertFunction(SanCovTraceCmp2, SanCovTraceCmpZeroExtAL, VoidTy,
392*08b48e0bSAndroid Build Coastguard Worker IRB.getInt16Ty(), IRB.getInt16Ty());
393*08b48e0bSAndroid Build Coastguard Worker SanCovTraceCmpFunction[2] =
394*08b48e0bSAndroid Build Coastguard Worker M.getOrInsertFunction(SanCovTraceCmp4, SanCovTraceCmpZeroExtAL, VoidTy,
395*08b48e0bSAndroid Build Coastguard Worker IRB.getInt32Ty(), IRB.getInt32Ty());
396*08b48e0bSAndroid Build Coastguard Worker SanCovTraceCmpFunction[3] =
397*08b48e0bSAndroid Build Coastguard Worker M.getOrInsertFunction(SanCovTraceCmp8, VoidTy, Int64Ty, Int64Ty);
398*08b48e0bSAndroid Build Coastguard Worker
399*08b48e0bSAndroid Build Coastguard Worker SanCovTraceConstCmpFunction[0] = M.getOrInsertFunction(
400*08b48e0bSAndroid Build Coastguard Worker SanCovTraceConstCmp1, SanCovTraceCmpZeroExtAL, VoidTy, Int8Ty, Int8Ty);
401*08b48e0bSAndroid Build Coastguard Worker SanCovTraceConstCmpFunction[1] = M.getOrInsertFunction(
402*08b48e0bSAndroid Build Coastguard Worker SanCovTraceConstCmp2, SanCovTraceCmpZeroExtAL, VoidTy, Int16Ty, Int16Ty);
403*08b48e0bSAndroid Build Coastguard Worker SanCovTraceConstCmpFunction[2] = M.getOrInsertFunction(
404*08b48e0bSAndroid Build Coastguard Worker SanCovTraceConstCmp4, SanCovTraceCmpZeroExtAL, VoidTy, Int32Ty, Int32Ty);
405*08b48e0bSAndroid Build Coastguard Worker SanCovTraceConstCmpFunction[3] =
406*08b48e0bSAndroid Build Coastguard Worker M.getOrInsertFunction(SanCovTraceConstCmp8, VoidTy, Int64Ty, Int64Ty);
407*08b48e0bSAndroid Build Coastguard Worker
408*08b48e0bSAndroid Build Coastguard Worker SanCovTraceSwitchFunction =
409*08b48e0bSAndroid Build Coastguard Worker M.getOrInsertFunction(SanCovTraceSwitchName, VoidTy, Int64Ty, Int64PtrTy);
410*08b48e0bSAndroid Build Coastguard Worker
411*08b48e0bSAndroid Build Coastguard Worker Constant *SanCovLowestStackConstant =
412*08b48e0bSAndroid Build Coastguard Worker M.getOrInsertGlobal(SanCovLowestStackName, IntptrTy);
413*08b48e0bSAndroid Build Coastguard Worker SanCovLowestStack = dyn_cast<GlobalVariable>(SanCovLowestStackConstant);
414*08b48e0bSAndroid Build Coastguard Worker if (!SanCovLowestStack || SanCovLowestStack->getValueType() != IntptrTy) {
415*08b48e0bSAndroid Build Coastguard Worker
416*08b48e0bSAndroid Build Coastguard Worker C->emitError(StringRef("'") + SanCovLowestStackName +
417*08b48e0bSAndroid Build Coastguard Worker "' should not be declared by the user");
418*08b48e0bSAndroid Build Coastguard Worker return true;
419*08b48e0bSAndroid Build Coastguard Worker
420*08b48e0bSAndroid Build Coastguard Worker }
421*08b48e0bSAndroid Build Coastguard Worker
422*08b48e0bSAndroid Build Coastguard Worker SanCovLowestStack->setThreadLocalMode(
423*08b48e0bSAndroid Build Coastguard Worker GlobalValue::ThreadLocalMode::InitialExecTLSModel);
424*08b48e0bSAndroid Build Coastguard Worker
425*08b48e0bSAndroid Build Coastguard Worker SanCovTracePC = M.getOrInsertFunction(SanCovTracePCName, VoidTy);
426*08b48e0bSAndroid Build Coastguard Worker SanCovTracePCGuard =
427*08b48e0bSAndroid Build Coastguard Worker M.getOrInsertFunction(SanCovTracePCGuardName, VoidTy, Int32PtrTy);
428*08b48e0bSAndroid Build Coastguard Worker
429*08b48e0bSAndroid Build Coastguard Worker for (auto &F : M)
430*08b48e0bSAndroid Build Coastguard Worker instrumentFunction(F, DTCallback, PDTCallback);
431*08b48e0bSAndroid Build Coastguard Worker
432*08b48e0bSAndroid Build Coastguard Worker Function *Ctor = nullptr;
433*08b48e0bSAndroid Build Coastguard Worker
434*08b48e0bSAndroid Build Coastguard Worker if (FunctionGuardArray)
435*08b48e0bSAndroid Build Coastguard Worker Ctor = CreateInitCallsForSections(M, SanCovModuleCtorTracePcGuardName,
436*08b48e0bSAndroid Build Coastguard Worker SanCovTracePCGuardInitName, Int32PtrTy,
437*08b48e0bSAndroid Build Coastguard Worker SanCovGuardsSectionName);
438*08b48e0bSAndroid Build Coastguard Worker
439*08b48e0bSAndroid Build Coastguard Worker if (Ctor && debug) {
440*08b48e0bSAndroid Build Coastguard Worker
441*08b48e0bSAndroid Build Coastguard Worker fprintf(stderr, "SANCOV: installed pcguard_init in ctor\n");
442*08b48e0bSAndroid Build Coastguard Worker
443*08b48e0bSAndroid Build Coastguard Worker }
444*08b48e0bSAndroid Build Coastguard Worker
445*08b48e0bSAndroid Build Coastguard Worker appendToUsed(M, GlobalsToAppendToUsed);
446*08b48e0bSAndroid Build Coastguard Worker appendToCompilerUsed(M, GlobalsToAppendToCompilerUsed);
447*08b48e0bSAndroid Build Coastguard Worker
448*08b48e0bSAndroid Build Coastguard Worker if (!be_quiet) {
449*08b48e0bSAndroid Build Coastguard Worker
450*08b48e0bSAndroid Build Coastguard Worker if (!instr) {
451*08b48e0bSAndroid Build Coastguard Worker
452*08b48e0bSAndroid Build Coastguard Worker WARNF("No instrumentation targets found.");
453*08b48e0bSAndroid Build Coastguard Worker
454*08b48e0bSAndroid Build Coastguard Worker } else {
455*08b48e0bSAndroid Build Coastguard Worker
456*08b48e0bSAndroid Build Coastguard Worker char modeline[128];
457*08b48e0bSAndroid Build Coastguard Worker snprintf(modeline, sizeof(modeline), "%s%s%s%s%s%s",
458*08b48e0bSAndroid Build Coastguard Worker getenv("AFL_HARDEN") ? "hardened" : "non-hardened",
459*08b48e0bSAndroid Build Coastguard Worker getenv("AFL_USE_ASAN") ? ", ASAN" : "",
460*08b48e0bSAndroid Build Coastguard Worker getenv("AFL_USE_MSAN") ? ", MSAN" : "",
461*08b48e0bSAndroid Build Coastguard Worker getenv("AFL_USE_TSAN") ? ", TSAN" : "",
462*08b48e0bSAndroid Build Coastguard Worker getenv("AFL_USE_CFISAN") ? ", CFISAN" : "",
463*08b48e0bSAndroid Build Coastguard Worker getenv("AFL_USE_UBSAN") ? ", UBSAN" : "");
464*08b48e0bSAndroid Build Coastguard Worker OKF("Instrumented %u locations with no collisions (%s mode) of which are "
465*08b48e0bSAndroid Build Coastguard Worker "%u handled and %u unhandled selects.",
466*08b48e0bSAndroid Build Coastguard Worker instr, modeline, selects, unhandled);
467*08b48e0bSAndroid Build Coastguard Worker
468*08b48e0bSAndroid Build Coastguard Worker }
469*08b48e0bSAndroid Build Coastguard Worker
470*08b48e0bSAndroid Build Coastguard Worker }
471*08b48e0bSAndroid Build Coastguard Worker
472*08b48e0bSAndroid Build Coastguard Worker return true;
473*08b48e0bSAndroid Build Coastguard Worker
474*08b48e0bSAndroid Build Coastguard Worker }
475*08b48e0bSAndroid Build Coastguard Worker
476*08b48e0bSAndroid Build Coastguard Worker // True if block has successors and it dominates all of them.
isFullDominator(const BasicBlock * BB,const DominatorTree * DT)477*08b48e0bSAndroid Build Coastguard Worker static bool isFullDominator(const BasicBlock *BB, const DominatorTree *DT) {
478*08b48e0bSAndroid Build Coastguard Worker
479*08b48e0bSAndroid Build Coastguard Worker if (succ_empty(BB)) return false;
480*08b48e0bSAndroid Build Coastguard Worker
481*08b48e0bSAndroid Build Coastguard Worker return llvm::all_of(successors(BB), [&](const BasicBlock *SUCC) {
482*08b48e0bSAndroid Build Coastguard Worker
483*08b48e0bSAndroid Build Coastguard Worker return DT->dominates(BB, SUCC);
484*08b48e0bSAndroid Build Coastguard Worker
485*08b48e0bSAndroid Build Coastguard Worker });
486*08b48e0bSAndroid Build Coastguard Worker
487*08b48e0bSAndroid Build Coastguard Worker }
488*08b48e0bSAndroid Build Coastguard Worker
489*08b48e0bSAndroid Build Coastguard Worker // True if block has predecessors and it postdominates all of them.
isFullPostDominator(const BasicBlock * BB,const PostDominatorTree * PDT)490*08b48e0bSAndroid Build Coastguard Worker static bool isFullPostDominator(const BasicBlock *BB,
491*08b48e0bSAndroid Build Coastguard Worker const PostDominatorTree *PDT) {
492*08b48e0bSAndroid Build Coastguard Worker
493*08b48e0bSAndroid Build Coastguard Worker if (pred_empty(BB)) return false;
494*08b48e0bSAndroid Build Coastguard Worker
495*08b48e0bSAndroid Build Coastguard Worker return llvm::all_of(predecessors(BB), [&](const BasicBlock *PRED) {
496*08b48e0bSAndroid Build Coastguard Worker
497*08b48e0bSAndroid Build Coastguard Worker return PDT->dominates(BB, PRED);
498*08b48e0bSAndroid Build Coastguard Worker
499*08b48e0bSAndroid Build Coastguard Worker });
500*08b48e0bSAndroid Build Coastguard Worker
501*08b48e0bSAndroid Build Coastguard Worker }
502*08b48e0bSAndroid Build Coastguard Worker
shouldInstrumentBlock(const Function & F,const BasicBlock * BB,const DominatorTree * DT,const PostDominatorTree * PDT,const SanitizerCoverageOptions & Options)503*08b48e0bSAndroid Build Coastguard Worker static bool shouldInstrumentBlock(const Function &F, const BasicBlock *BB,
504*08b48e0bSAndroid Build Coastguard Worker const DominatorTree *DT,
505*08b48e0bSAndroid Build Coastguard Worker const PostDominatorTree *PDT,
506*08b48e0bSAndroid Build Coastguard Worker const SanitizerCoverageOptions &Options) {
507*08b48e0bSAndroid Build Coastguard Worker
508*08b48e0bSAndroid Build Coastguard Worker // Don't insert coverage for blocks containing nothing but unreachable: we
509*08b48e0bSAndroid Build Coastguard Worker // will never call __sanitizer_cov() for them, so counting them in
510*08b48e0bSAndroid Build Coastguard Worker // NumberOfInstrumentedBlocks() might complicate calculation of code coverage
511*08b48e0bSAndroid Build Coastguard Worker // percentage. Also, unreachable instructions frequently have no debug
512*08b48e0bSAndroid Build Coastguard Worker // locations.
513*08b48e0bSAndroid Build Coastguard Worker if (isa<UnreachableInst>(BB->getFirstNonPHIOrDbgOrLifetime())) return false;
514*08b48e0bSAndroid Build Coastguard Worker
515*08b48e0bSAndroid Build Coastguard Worker // Don't insert coverage into blocks without a valid insertion point
516*08b48e0bSAndroid Build Coastguard Worker // (catchswitch blocks).
517*08b48e0bSAndroid Build Coastguard Worker if (BB->getFirstInsertionPt() == BB->end()) return false;
518*08b48e0bSAndroid Build Coastguard Worker
519*08b48e0bSAndroid Build Coastguard Worker if (Options.NoPrune || &F.getEntryBlock() == BB) return true;
520*08b48e0bSAndroid Build Coastguard Worker
521*08b48e0bSAndroid Build Coastguard Worker // Do not instrument full dominators, or full post-dominators with multiple
522*08b48e0bSAndroid Build Coastguard Worker // predecessors.
523*08b48e0bSAndroid Build Coastguard Worker return !isFullDominator(BB, DT) &&
524*08b48e0bSAndroid Build Coastguard Worker !(isFullPostDominator(BB, PDT) && !BB->getSinglePredecessor());
525*08b48e0bSAndroid Build Coastguard Worker
526*08b48e0bSAndroid Build Coastguard Worker }
527*08b48e0bSAndroid Build Coastguard Worker
528*08b48e0bSAndroid Build Coastguard Worker // Returns true iff From->To is a backedge.
529*08b48e0bSAndroid Build Coastguard Worker // A twist here is that we treat From->To as a backedge if
530*08b48e0bSAndroid Build Coastguard Worker // * To dominates From or
531*08b48e0bSAndroid Build Coastguard Worker // * To->UniqueSuccessor dominates From
532*08b48e0bSAndroid Build Coastguard Worker #if 0
533*08b48e0bSAndroid Build Coastguard Worker static bool IsBackEdge(BasicBlock *From, BasicBlock *To,
534*08b48e0bSAndroid Build Coastguard Worker const DominatorTree *DT) {
535*08b48e0bSAndroid Build Coastguard Worker
536*08b48e0bSAndroid Build Coastguard Worker if (DT->dominates(To, From))
537*08b48e0bSAndroid Build Coastguard Worker return true;
538*08b48e0bSAndroid Build Coastguard Worker if (auto Next = To->getUniqueSuccessor())
539*08b48e0bSAndroid Build Coastguard Worker if (DT->dominates(Next, From))
540*08b48e0bSAndroid Build Coastguard Worker return true;
541*08b48e0bSAndroid Build Coastguard Worker return false;
542*08b48e0bSAndroid Build Coastguard Worker
543*08b48e0bSAndroid Build Coastguard Worker }
544*08b48e0bSAndroid Build Coastguard Worker
545*08b48e0bSAndroid Build Coastguard Worker #endif
546*08b48e0bSAndroid Build Coastguard Worker
547*08b48e0bSAndroid Build Coastguard Worker // Prunes uninteresting Cmp instrumentation:
548*08b48e0bSAndroid Build Coastguard Worker // * CMP instructions that feed into loop backedge branch.
549*08b48e0bSAndroid Build Coastguard Worker //
550*08b48e0bSAndroid Build Coastguard Worker // Note that Cmp pruning is controlled by the same flag as the
551*08b48e0bSAndroid Build Coastguard Worker // BB pruning.
552*08b48e0bSAndroid Build Coastguard Worker #if 0
553*08b48e0bSAndroid Build Coastguard Worker static bool IsInterestingCmp(ICmpInst *CMP, const DominatorTree *DT,
554*08b48e0bSAndroid Build Coastguard Worker const SanitizerCoverageOptions &Options) {
555*08b48e0bSAndroid Build Coastguard Worker
556*08b48e0bSAndroid Build Coastguard Worker if (!Options.NoPrune)
557*08b48e0bSAndroid Build Coastguard Worker if (CMP->hasOneUse())
558*08b48e0bSAndroid Build Coastguard Worker if (auto BR = dyn_cast<BranchInst>(CMP->user_back()))
559*08b48e0bSAndroid Build Coastguard Worker for (BasicBlock *B : BR->successors())
560*08b48e0bSAndroid Build Coastguard Worker if (IsBackEdge(BR->getParent(), B, DT))
561*08b48e0bSAndroid Build Coastguard Worker return false;
562*08b48e0bSAndroid Build Coastguard Worker return true;
563*08b48e0bSAndroid Build Coastguard Worker
564*08b48e0bSAndroid Build Coastguard Worker }
565*08b48e0bSAndroid Build Coastguard Worker
566*08b48e0bSAndroid Build Coastguard Worker #endif
567*08b48e0bSAndroid Build Coastguard Worker
instrumentFunction(Function & F,DomTreeCallback DTCallback,PostDomTreeCallback PDTCallback)568*08b48e0bSAndroid Build Coastguard Worker void ModuleSanitizerCoverageAFL::instrumentFunction(
569*08b48e0bSAndroid Build Coastguard Worker Function &F, DomTreeCallback DTCallback, PostDomTreeCallback PDTCallback) {
570*08b48e0bSAndroid Build Coastguard Worker
571*08b48e0bSAndroid Build Coastguard Worker if (F.empty()) return;
572*08b48e0bSAndroid Build Coastguard Worker if (!isInInstrumentList(&F, FMNAME)) return;
573*08b48e0bSAndroid Build Coastguard Worker if (F.getName().find(".module_ctor") != std::string::npos)
574*08b48e0bSAndroid Build Coastguard Worker return; // Should not instrument sanitizer init functions.
575*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 18
576*08b48e0bSAndroid Build Coastguard Worker if (F.getName().starts_with("__sanitizer_"))
577*08b48e0bSAndroid Build Coastguard Worker #else
578*08b48e0bSAndroid Build Coastguard Worker if (F.getName().startswith("__sanitizer_"))
579*08b48e0bSAndroid Build Coastguard Worker #endif
580*08b48e0bSAndroid Build Coastguard Worker return; // Don't instrument __sanitizer_* callbacks.
581*08b48e0bSAndroid Build Coastguard Worker // Don't touch available_externally functions, their actual body is elewhere.
582*08b48e0bSAndroid Build Coastguard Worker if (F.getLinkage() == GlobalValue::AvailableExternallyLinkage) return;
583*08b48e0bSAndroid Build Coastguard Worker // Don't instrument MSVC CRT configuration helpers. They may run before normal
584*08b48e0bSAndroid Build Coastguard Worker // initialization.
585*08b48e0bSAndroid Build Coastguard Worker if (F.getName() == "__local_stdio_printf_options" ||
586*08b48e0bSAndroid Build Coastguard Worker F.getName() == "__local_stdio_scanf_options")
587*08b48e0bSAndroid Build Coastguard Worker return;
588*08b48e0bSAndroid Build Coastguard Worker if (isa<UnreachableInst>(F.getEntryBlock().getTerminator())) return;
589*08b48e0bSAndroid Build Coastguard Worker // Don't instrument functions using SEH for now. Splitting basic blocks like
590*08b48e0bSAndroid Build Coastguard Worker // we do for coverage breaks WinEHPrepare.
591*08b48e0bSAndroid Build Coastguard Worker // FIXME: Remove this when SEH no longer uses landingpad pattern matching.
592*08b48e0bSAndroid Build Coastguard Worker if (F.hasPersonalityFn() &&
593*08b48e0bSAndroid Build Coastguard Worker isAsynchronousEHPersonality(classifyEHPersonality(F.getPersonalityFn())))
594*08b48e0bSAndroid Build Coastguard Worker return;
595*08b48e0bSAndroid Build Coastguard Worker if (F.hasFnAttribute(Attribute::NoSanitizeCoverage)) return;
596*08b48e0bSAndroid Build Coastguard Worker if (Options.CoverageType >= SanitizerCoverageOptions::SCK_Edge)
597*08b48e0bSAndroid Build Coastguard Worker SplitAllCriticalEdges(
598*08b48e0bSAndroid Build Coastguard Worker F, CriticalEdgeSplittingOptions().setIgnoreUnreachableDests());
599*08b48e0bSAndroid Build Coastguard Worker SmallVector<BasicBlock *, 16> BlocksToInstrument;
600*08b48e0bSAndroid Build Coastguard Worker SmallVector<Instruction *, 8> CmpTraceTargets;
601*08b48e0bSAndroid Build Coastguard Worker SmallVector<Instruction *, 8> SwitchTraceTargets;
602*08b48e0bSAndroid Build Coastguard Worker
603*08b48e0bSAndroid Build Coastguard Worker const DominatorTree *DT = DTCallback(F);
604*08b48e0bSAndroid Build Coastguard Worker const PostDominatorTree *PDT = PDTCallback(F);
605*08b48e0bSAndroid Build Coastguard Worker bool IsLeafFunc = true;
606*08b48e0bSAndroid Build Coastguard Worker
607*08b48e0bSAndroid Build Coastguard Worker for (auto &BB : F) {
608*08b48e0bSAndroid Build Coastguard Worker
609*08b48e0bSAndroid Build Coastguard Worker if (shouldInstrumentBlock(F, &BB, DT, PDT, Options))
610*08b48e0bSAndroid Build Coastguard Worker BlocksToInstrument.push_back(&BB);
611*08b48e0bSAndroid Build Coastguard Worker /*
612*08b48e0bSAndroid Build Coastguard Worker for (auto &Inst : BB) {
613*08b48e0bSAndroid Build Coastguard Worker
614*08b48e0bSAndroid Build Coastguard Worker if (Options.TraceCmp) {
615*08b48e0bSAndroid Build Coastguard Worker
616*08b48e0bSAndroid Build Coastguard Worker if (ICmpInst *CMP = dyn_cast<ICmpInst>(&Inst))
617*08b48e0bSAndroid Build Coastguard Worker if (IsInterestingCmp(CMP, DT, Options))
618*08b48e0bSAndroid Build Coastguard Worker CmpTraceTargets.push_back(&Inst);
619*08b48e0bSAndroid Build Coastguard Worker if (isa<SwitchInst>(&Inst))
620*08b48e0bSAndroid Build Coastguard Worker SwitchTraceTargets.push_back(&Inst);
621*08b48e0bSAndroid Build Coastguard Worker
622*08b48e0bSAndroid Build Coastguard Worker }
623*08b48e0bSAndroid Build Coastguard Worker
624*08b48e0bSAndroid Build Coastguard Worker }
625*08b48e0bSAndroid Build Coastguard Worker
626*08b48e0bSAndroid Build Coastguard Worker */
627*08b48e0bSAndroid Build Coastguard Worker
628*08b48e0bSAndroid Build Coastguard Worker }
629*08b48e0bSAndroid Build Coastguard Worker
630*08b48e0bSAndroid Build Coastguard Worker if (debug) {
631*08b48e0bSAndroid Build Coastguard Worker
632*08b48e0bSAndroid Build Coastguard Worker fprintf(stderr, "SanitizerCoveragePCGUARD: instrumenting %s in %s\n",
633*08b48e0bSAndroid Build Coastguard Worker F.getName().str().c_str(), F.getParent()->getName().str().c_str());
634*08b48e0bSAndroid Build Coastguard Worker
635*08b48e0bSAndroid Build Coastguard Worker }
636*08b48e0bSAndroid Build Coastguard Worker
637*08b48e0bSAndroid Build Coastguard Worker InjectCoverage(F, BlocksToInstrument, IsLeafFunc);
638*08b48e0bSAndroid Build Coastguard Worker // InjectTraceForCmp(F, CmpTraceTargets);
639*08b48e0bSAndroid Build Coastguard Worker // InjectTraceForSwitch(F, SwitchTraceTargets);
640*08b48e0bSAndroid Build Coastguard Worker
641*08b48e0bSAndroid Build Coastguard Worker }
642*08b48e0bSAndroid Build Coastguard Worker
CreateFunctionLocalArrayInSection(size_t NumElements,Function & F,Type * Ty,const char * Section)643*08b48e0bSAndroid Build Coastguard Worker GlobalVariable *ModuleSanitizerCoverageAFL::CreateFunctionLocalArrayInSection(
644*08b48e0bSAndroid Build Coastguard Worker size_t NumElements, Function &F, Type *Ty, const char *Section) {
645*08b48e0bSAndroid Build Coastguard Worker
646*08b48e0bSAndroid Build Coastguard Worker ArrayType *ArrayTy = ArrayType::get(Ty, NumElements);
647*08b48e0bSAndroid Build Coastguard Worker auto Array = new GlobalVariable(
648*08b48e0bSAndroid Build Coastguard Worker *CurModule, ArrayTy, false, GlobalVariable::PrivateLinkage,
649*08b48e0bSAndroid Build Coastguard Worker Constant::getNullValue(ArrayTy), "__sancov_gen_");
650*08b48e0bSAndroid Build Coastguard Worker
651*08b48e0bSAndroid Build Coastguard Worker if (TargetTriple.supportsCOMDAT() &&
652*08b48e0bSAndroid Build Coastguard Worker (TargetTriple.isOSBinFormatELF() || !F.isInterposable()))
653*08b48e0bSAndroid Build Coastguard Worker if (auto Comdat = getOrCreateFunctionComdat(F, TargetTriple))
654*08b48e0bSAndroid Build Coastguard Worker Array->setComdat(Comdat);
655*08b48e0bSAndroid Build Coastguard Worker Array->setSection(getSectionName(Section));
656*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 16
657*08b48e0bSAndroid Build Coastguard Worker Array->setAlignment(Align(DL->getTypeStoreSize(Ty).getFixedValue()));
658*08b48e0bSAndroid Build Coastguard Worker #else
659*08b48e0bSAndroid Build Coastguard Worker Array->setAlignment(Align(DL->getTypeStoreSize(Ty).getFixedSize()));
660*08b48e0bSAndroid Build Coastguard Worker #endif
661*08b48e0bSAndroid Build Coastguard Worker
662*08b48e0bSAndroid Build Coastguard Worker // sancov_pcs parallels the other metadata section(s). Optimizers (e.g.
663*08b48e0bSAndroid Build Coastguard Worker // GlobalOpt/ConstantMerge) may not discard sancov_pcs and the other
664*08b48e0bSAndroid Build Coastguard Worker // section(s) as a unit, so we conservatively retain all unconditionally in
665*08b48e0bSAndroid Build Coastguard Worker // the compiler.
666*08b48e0bSAndroid Build Coastguard Worker //
667*08b48e0bSAndroid Build Coastguard Worker // With comdat (COFF/ELF), the linker can guarantee the associated sections
668*08b48e0bSAndroid Build Coastguard Worker // will be retained or discarded as a unit, so llvm.compiler.used is
669*08b48e0bSAndroid Build Coastguard Worker // sufficient. Otherwise, conservatively make all of them retained by the
670*08b48e0bSAndroid Build Coastguard Worker // linker.
671*08b48e0bSAndroid Build Coastguard Worker if (Array->hasComdat())
672*08b48e0bSAndroid Build Coastguard Worker GlobalsToAppendToCompilerUsed.push_back(Array);
673*08b48e0bSAndroid Build Coastguard Worker else
674*08b48e0bSAndroid Build Coastguard Worker GlobalsToAppendToUsed.push_back(Array);
675*08b48e0bSAndroid Build Coastguard Worker
676*08b48e0bSAndroid Build Coastguard Worker return Array;
677*08b48e0bSAndroid Build Coastguard Worker
678*08b48e0bSAndroid Build Coastguard Worker }
679*08b48e0bSAndroid Build Coastguard Worker
CreatePCArray(Function & F,ArrayRef<BasicBlock * > AllBlocks)680*08b48e0bSAndroid Build Coastguard Worker GlobalVariable *ModuleSanitizerCoverageAFL::CreatePCArray(
681*08b48e0bSAndroid Build Coastguard Worker Function &F, ArrayRef<BasicBlock *> AllBlocks) {
682*08b48e0bSAndroid Build Coastguard Worker
683*08b48e0bSAndroid Build Coastguard Worker size_t N = AllBlocks.size();
684*08b48e0bSAndroid Build Coastguard Worker assert(N);
685*08b48e0bSAndroid Build Coastguard Worker SmallVector<Constant *, 32> PCs;
686*08b48e0bSAndroid Build Coastguard Worker IRBuilder<> IRB(&*F.getEntryBlock().getFirstInsertionPt());
687*08b48e0bSAndroid Build Coastguard Worker for (size_t i = 0; i < N; i++) {
688*08b48e0bSAndroid Build Coastguard Worker
689*08b48e0bSAndroid Build Coastguard Worker if (&F.getEntryBlock() == AllBlocks[i]) {
690*08b48e0bSAndroid Build Coastguard Worker
691*08b48e0bSAndroid Build Coastguard Worker PCs.push_back((Constant *)IRB.CreatePointerCast(&F, IntptrPtrTy));
692*08b48e0bSAndroid Build Coastguard Worker PCs.push_back((Constant *)IRB.CreateIntToPtr(
693*08b48e0bSAndroid Build Coastguard Worker ConstantInt::get(IntptrTy, 1), IntptrPtrTy));
694*08b48e0bSAndroid Build Coastguard Worker
695*08b48e0bSAndroid Build Coastguard Worker } else {
696*08b48e0bSAndroid Build Coastguard Worker
697*08b48e0bSAndroid Build Coastguard Worker PCs.push_back((Constant *)IRB.CreatePointerCast(
698*08b48e0bSAndroid Build Coastguard Worker BlockAddress::get(AllBlocks[i]), IntptrPtrTy));
699*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 16
700*08b48e0bSAndroid Build Coastguard Worker PCs.push_back(Constant::getNullValue(IntptrPtrTy));
701*08b48e0bSAndroid Build Coastguard Worker #else
702*08b48e0bSAndroid Build Coastguard Worker PCs.push_back((Constant *)IRB.CreateIntToPtr(
703*08b48e0bSAndroid Build Coastguard Worker ConstantInt::get(IntptrTy, 0), IntptrPtrTy));
704*08b48e0bSAndroid Build Coastguard Worker #endif
705*08b48e0bSAndroid Build Coastguard Worker
706*08b48e0bSAndroid Build Coastguard Worker }
707*08b48e0bSAndroid Build Coastguard Worker
708*08b48e0bSAndroid Build Coastguard Worker }
709*08b48e0bSAndroid Build Coastguard Worker
710*08b48e0bSAndroid Build Coastguard Worker auto *PCArray = CreateFunctionLocalArrayInSection(N * 2, F, IntptrPtrTy,
711*08b48e0bSAndroid Build Coastguard Worker SanCovPCsSectionName);
712*08b48e0bSAndroid Build Coastguard Worker PCArray->setInitializer(
713*08b48e0bSAndroid Build Coastguard Worker ConstantArray::get(ArrayType::get(IntptrPtrTy, N * 2), PCs));
714*08b48e0bSAndroid Build Coastguard Worker PCArray->setConstant(true);
715*08b48e0bSAndroid Build Coastguard Worker
716*08b48e0bSAndroid Build Coastguard Worker return PCArray;
717*08b48e0bSAndroid Build Coastguard Worker
718*08b48e0bSAndroid Build Coastguard Worker }
719*08b48e0bSAndroid Build Coastguard Worker
CreateFunctionLocalArrays(Function & F,ArrayRef<BasicBlock * > AllBlocks,uint32_t special)720*08b48e0bSAndroid Build Coastguard Worker void ModuleSanitizerCoverageAFL::CreateFunctionLocalArrays(
721*08b48e0bSAndroid Build Coastguard Worker Function &F, ArrayRef<BasicBlock *> AllBlocks, uint32_t special) {
722*08b48e0bSAndroid Build Coastguard Worker
723*08b48e0bSAndroid Build Coastguard Worker if (Options.TracePCGuard)
724*08b48e0bSAndroid Build Coastguard Worker FunctionGuardArray = CreateFunctionLocalArrayInSection(
725*08b48e0bSAndroid Build Coastguard Worker AllBlocks.size() + special, F, Int32Ty, SanCovGuardsSectionName);
726*08b48e0bSAndroid Build Coastguard Worker
727*08b48e0bSAndroid Build Coastguard Worker }
728*08b48e0bSAndroid Build Coastguard Worker
InjectCoverage(Function & F,ArrayRef<BasicBlock * > AllBlocks,bool IsLeafFunc)729*08b48e0bSAndroid Build Coastguard Worker bool ModuleSanitizerCoverageAFL::InjectCoverage(
730*08b48e0bSAndroid Build Coastguard Worker Function &F, ArrayRef<BasicBlock *> AllBlocks, bool IsLeafFunc) {
731*08b48e0bSAndroid Build Coastguard Worker
732*08b48e0bSAndroid Build Coastguard Worker if (AllBlocks.empty()) return false;
733*08b48e0bSAndroid Build Coastguard Worker
734*08b48e0bSAndroid Build Coastguard Worker uint32_t cnt_cov = 0, cnt_sel = 0, cnt_sel_inc = 0;
735*08b48e0bSAndroid Build Coastguard Worker static uint32_t first = 1;
736*08b48e0bSAndroid Build Coastguard Worker
737*08b48e0bSAndroid Build Coastguard Worker for (auto &BB : F) {
738*08b48e0bSAndroid Build Coastguard Worker
739*08b48e0bSAndroid Build Coastguard Worker for (auto &IN : BB) {
740*08b48e0bSAndroid Build Coastguard Worker
741*08b48e0bSAndroid Build Coastguard Worker CallInst *callInst = nullptr;
742*08b48e0bSAndroid Build Coastguard Worker
743*08b48e0bSAndroid Build Coastguard Worker if ((callInst = dyn_cast<CallInst>(&IN))) {
744*08b48e0bSAndroid Build Coastguard Worker
745*08b48e0bSAndroid Build Coastguard Worker Function *Callee = callInst->getCalledFunction();
746*08b48e0bSAndroid Build Coastguard Worker if (!Callee) continue;
747*08b48e0bSAndroid Build Coastguard Worker if (callInst->getCallingConv() != llvm::CallingConv::C) continue;
748*08b48e0bSAndroid Build Coastguard Worker StringRef FuncName = Callee->getName();
749*08b48e0bSAndroid Build Coastguard Worker if (!FuncName.compare(StringRef("dlopen")) ||
750*08b48e0bSAndroid Build Coastguard Worker !FuncName.compare(StringRef("_dlopen"))) {
751*08b48e0bSAndroid Build Coastguard Worker
752*08b48e0bSAndroid Build Coastguard Worker fprintf(stderr,
753*08b48e0bSAndroid Build Coastguard Worker "WARNING: dlopen() detected. To have coverage for a library "
754*08b48e0bSAndroid Build Coastguard Worker "that your target dlopen()'s this must either happen before "
755*08b48e0bSAndroid Build Coastguard Worker "__AFL_INIT() or you must use AFL_PRELOAD to preload all "
756*08b48e0bSAndroid Build Coastguard Worker "dlopen()'ed libraries!\n");
757*08b48e0bSAndroid Build Coastguard Worker continue;
758*08b48e0bSAndroid Build Coastguard Worker
759*08b48e0bSAndroid Build Coastguard Worker }
760*08b48e0bSAndroid Build Coastguard Worker
761*08b48e0bSAndroid Build Coastguard Worker if (!FuncName.compare(StringRef("__afl_coverage_interesting"))) {
762*08b48e0bSAndroid Build Coastguard Worker
763*08b48e0bSAndroid Build Coastguard Worker cnt_cov++;
764*08b48e0bSAndroid Build Coastguard Worker
765*08b48e0bSAndroid Build Coastguard Worker }
766*08b48e0bSAndroid Build Coastguard Worker
767*08b48e0bSAndroid Build Coastguard Worker }
768*08b48e0bSAndroid Build Coastguard Worker
769*08b48e0bSAndroid Build Coastguard Worker SelectInst *selectInst = nullptr;
770*08b48e0bSAndroid Build Coastguard Worker
771*08b48e0bSAndroid Build Coastguard Worker if ((selectInst = dyn_cast<SelectInst>(&IN))) {
772*08b48e0bSAndroid Build Coastguard Worker
773*08b48e0bSAndroid Build Coastguard Worker Value *c = selectInst->getCondition();
774*08b48e0bSAndroid Build Coastguard Worker auto t = c->getType();
775*08b48e0bSAndroid Build Coastguard Worker if (t->getTypeID() == llvm::Type::IntegerTyID) {
776*08b48e0bSAndroid Build Coastguard Worker
777*08b48e0bSAndroid Build Coastguard Worker cnt_sel++;
778*08b48e0bSAndroid Build Coastguard Worker cnt_sel_inc += 2;
779*08b48e0bSAndroid Build Coastguard Worker
780*08b48e0bSAndroid Build Coastguard Worker }
781*08b48e0bSAndroid Build Coastguard Worker
782*08b48e0bSAndroid Build Coastguard Worker else if (t->getTypeID() == llvm::Type::FixedVectorTyID) {
783*08b48e0bSAndroid Build Coastguard Worker
784*08b48e0bSAndroid Build Coastguard Worker FixedVectorType *tt = dyn_cast<FixedVectorType>(t);
785*08b48e0bSAndroid Build Coastguard Worker if (tt) {
786*08b48e0bSAndroid Build Coastguard Worker
787*08b48e0bSAndroid Build Coastguard Worker cnt_sel++;
788*08b48e0bSAndroid Build Coastguard Worker cnt_sel_inc += (tt->getElementCount().getKnownMinValue() * 2);
789*08b48e0bSAndroid Build Coastguard Worker
790*08b48e0bSAndroid Build Coastguard Worker }
791*08b48e0bSAndroid Build Coastguard Worker
792*08b48e0bSAndroid Build Coastguard Worker }
793*08b48e0bSAndroid Build Coastguard Worker
794*08b48e0bSAndroid Build Coastguard Worker }
795*08b48e0bSAndroid Build Coastguard Worker
796*08b48e0bSAndroid Build Coastguard Worker }
797*08b48e0bSAndroid Build Coastguard Worker
798*08b48e0bSAndroid Build Coastguard Worker }
799*08b48e0bSAndroid Build Coastguard Worker
800*08b48e0bSAndroid Build Coastguard Worker CreateFunctionLocalArrays(F, AllBlocks, first + cnt_cov + cnt_sel_inc);
801*08b48e0bSAndroid Build Coastguard Worker
802*08b48e0bSAndroid Build Coastguard Worker if (first) { first = 0; }
803*08b48e0bSAndroid Build Coastguard Worker selects += cnt_sel;
804*08b48e0bSAndroid Build Coastguard Worker
805*08b48e0bSAndroid Build Coastguard Worker uint32_t special = 0, local_selects = 0, skip_next = 0;
806*08b48e0bSAndroid Build Coastguard Worker
807*08b48e0bSAndroid Build Coastguard Worker for (auto &BB : F) {
808*08b48e0bSAndroid Build Coastguard Worker
809*08b48e0bSAndroid Build Coastguard Worker for (auto &IN : BB) {
810*08b48e0bSAndroid Build Coastguard Worker
811*08b48e0bSAndroid Build Coastguard Worker CallInst *callInst = nullptr;
812*08b48e0bSAndroid Build Coastguard Worker
813*08b48e0bSAndroid Build Coastguard Worker if ((callInst = dyn_cast<CallInst>(&IN))) {
814*08b48e0bSAndroid Build Coastguard Worker
815*08b48e0bSAndroid Build Coastguard Worker Function *Callee = callInst->getCalledFunction();
816*08b48e0bSAndroid Build Coastguard Worker if (!Callee) continue;
817*08b48e0bSAndroid Build Coastguard Worker if (callInst->getCallingConv() != llvm::CallingConv::C) continue;
818*08b48e0bSAndroid Build Coastguard Worker StringRef FuncName = Callee->getName();
819*08b48e0bSAndroid Build Coastguard Worker if (FuncName.compare(StringRef("__afl_coverage_interesting"))) continue;
820*08b48e0bSAndroid Build Coastguard Worker
821*08b48e0bSAndroid Build Coastguard Worker IRBuilder<> IRB(callInst);
822*08b48e0bSAndroid Build Coastguard Worker
823*08b48e0bSAndroid Build Coastguard Worker if (!FunctionGuardArray) {
824*08b48e0bSAndroid Build Coastguard Worker
825*08b48e0bSAndroid Build Coastguard Worker fprintf(stderr,
826*08b48e0bSAndroid Build Coastguard Worker "SANCOV: FunctionGuardArray is NULL, failed to emit "
827*08b48e0bSAndroid Build Coastguard Worker "instrumentation.");
828*08b48e0bSAndroid Build Coastguard Worker continue;
829*08b48e0bSAndroid Build Coastguard Worker
830*08b48e0bSAndroid Build Coastguard Worker }
831*08b48e0bSAndroid Build Coastguard Worker
832*08b48e0bSAndroid Build Coastguard Worker Value *GuardPtr = IRB.CreateIntToPtr(
833*08b48e0bSAndroid Build Coastguard Worker IRB.CreateAdd(
834*08b48e0bSAndroid Build Coastguard Worker IRB.CreatePointerCast(FunctionGuardArray, IntptrTy),
835*08b48e0bSAndroid Build Coastguard Worker ConstantInt::get(IntptrTy, (++special + AllBlocks.size()) * 4)),
836*08b48e0bSAndroid Build Coastguard Worker Int32PtrTy);
837*08b48e0bSAndroid Build Coastguard Worker
838*08b48e0bSAndroid Build Coastguard Worker LoadInst *Idx = IRB.CreateLoad(IRB.getInt32Ty(), GuardPtr);
839*08b48e0bSAndroid Build Coastguard Worker ModuleSanitizerCoverageAFL::SetNoSanitizeMetadata(Idx);
840*08b48e0bSAndroid Build Coastguard Worker
841*08b48e0bSAndroid Build Coastguard Worker callInst->setOperand(1, Idx);
842*08b48e0bSAndroid Build Coastguard Worker
843*08b48e0bSAndroid Build Coastguard Worker }
844*08b48e0bSAndroid Build Coastguard Worker
845*08b48e0bSAndroid Build Coastguard Worker SelectInst *selectInst = nullptr;
846*08b48e0bSAndroid Build Coastguard Worker
847*08b48e0bSAndroid Build Coastguard Worker if (!skip_next && (selectInst = dyn_cast<SelectInst>(&IN))) {
848*08b48e0bSAndroid Build Coastguard Worker
849*08b48e0bSAndroid Build Coastguard Worker uint32_t vector_cnt = 0;
850*08b48e0bSAndroid Build Coastguard Worker Value *condition = selectInst->getCondition();
851*08b48e0bSAndroid Build Coastguard Worker Value *result;
852*08b48e0bSAndroid Build Coastguard Worker auto t = condition->getType();
853*08b48e0bSAndroid Build Coastguard Worker IRBuilder<> IRB(selectInst->getNextNode());
854*08b48e0bSAndroid Build Coastguard Worker
855*08b48e0bSAndroid Build Coastguard Worker if (t->getTypeID() == llvm::Type::IntegerTyID) {
856*08b48e0bSAndroid Build Coastguard Worker
857*08b48e0bSAndroid Build Coastguard Worker if (!FunctionGuardArray) {
858*08b48e0bSAndroid Build Coastguard Worker
859*08b48e0bSAndroid Build Coastguard Worker fprintf(stderr,
860*08b48e0bSAndroid Build Coastguard Worker "SANCOV: FunctionGuardArray is NULL, failed to emit "
861*08b48e0bSAndroid Build Coastguard Worker "instrumentation.");
862*08b48e0bSAndroid Build Coastguard Worker continue;
863*08b48e0bSAndroid Build Coastguard Worker
864*08b48e0bSAndroid Build Coastguard Worker }
865*08b48e0bSAndroid Build Coastguard Worker
866*08b48e0bSAndroid Build Coastguard Worker auto GuardPtr1 = IRB.CreateIntToPtr(
867*08b48e0bSAndroid Build Coastguard Worker IRB.CreateAdd(
868*08b48e0bSAndroid Build Coastguard Worker IRB.CreatePointerCast(FunctionGuardArray, IntptrTy),
869*08b48e0bSAndroid Build Coastguard Worker ConstantInt::get(
870*08b48e0bSAndroid Build Coastguard Worker IntptrTy,
871*08b48e0bSAndroid Build Coastguard Worker (cnt_cov + local_selects++ + AllBlocks.size()) * 4)),
872*08b48e0bSAndroid Build Coastguard Worker Int32PtrTy);
873*08b48e0bSAndroid Build Coastguard Worker
874*08b48e0bSAndroid Build Coastguard Worker auto GuardPtr2 = IRB.CreateIntToPtr(
875*08b48e0bSAndroid Build Coastguard Worker IRB.CreateAdd(
876*08b48e0bSAndroid Build Coastguard Worker IRB.CreatePointerCast(FunctionGuardArray, IntptrTy),
877*08b48e0bSAndroid Build Coastguard Worker ConstantInt::get(
878*08b48e0bSAndroid Build Coastguard Worker IntptrTy,
879*08b48e0bSAndroid Build Coastguard Worker (cnt_cov + local_selects++ + AllBlocks.size()) * 4)),
880*08b48e0bSAndroid Build Coastguard Worker Int32PtrTy);
881*08b48e0bSAndroid Build Coastguard Worker
882*08b48e0bSAndroid Build Coastguard Worker result = IRB.CreateSelect(condition, GuardPtr1, GuardPtr2);
883*08b48e0bSAndroid Build Coastguard Worker
884*08b48e0bSAndroid Build Coastguard Worker } else
885*08b48e0bSAndroid Build Coastguard Worker
886*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 14
887*08b48e0bSAndroid Build Coastguard Worker if (t->getTypeID() == llvm::Type::FixedVectorTyID) {
888*08b48e0bSAndroid Build Coastguard Worker
889*08b48e0bSAndroid Build Coastguard Worker FixedVectorType *tt = dyn_cast<FixedVectorType>(t);
890*08b48e0bSAndroid Build Coastguard Worker if (tt) {
891*08b48e0bSAndroid Build Coastguard Worker
892*08b48e0bSAndroid Build Coastguard Worker uint32_t elements = tt->getElementCount().getFixedValue();
893*08b48e0bSAndroid Build Coastguard Worker vector_cnt = elements;
894*08b48e0bSAndroid Build Coastguard Worker if (elements) {
895*08b48e0bSAndroid Build Coastguard Worker
896*08b48e0bSAndroid Build Coastguard Worker FixedVectorType *GuardPtr1 =
897*08b48e0bSAndroid Build Coastguard Worker FixedVectorType::get(Int32PtrTy, elements);
898*08b48e0bSAndroid Build Coastguard Worker FixedVectorType *GuardPtr2 =
899*08b48e0bSAndroid Build Coastguard Worker FixedVectorType::get(Int32PtrTy, elements);
900*08b48e0bSAndroid Build Coastguard Worker Value *x, *y;
901*08b48e0bSAndroid Build Coastguard Worker
902*08b48e0bSAndroid Build Coastguard Worker if (!FunctionGuardArray) {
903*08b48e0bSAndroid Build Coastguard Worker
904*08b48e0bSAndroid Build Coastguard Worker fprintf(stderr,
905*08b48e0bSAndroid Build Coastguard Worker "SANCOV: FunctionGuardArray is NULL, failed to emit "
906*08b48e0bSAndroid Build Coastguard Worker "instrumentation.");
907*08b48e0bSAndroid Build Coastguard Worker continue;
908*08b48e0bSAndroid Build Coastguard Worker
909*08b48e0bSAndroid Build Coastguard Worker }
910*08b48e0bSAndroid Build Coastguard Worker
911*08b48e0bSAndroid Build Coastguard Worker Value *val1 = IRB.CreateIntToPtr(
912*08b48e0bSAndroid Build Coastguard Worker IRB.CreateAdd(
913*08b48e0bSAndroid Build Coastguard Worker IRB.CreatePointerCast(FunctionGuardArray, IntptrTy),
914*08b48e0bSAndroid Build Coastguard Worker ConstantInt::get(
915*08b48e0bSAndroid Build Coastguard Worker IntptrTy,
916*08b48e0bSAndroid Build Coastguard Worker (cnt_cov + local_selects++ + AllBlocks.size()) * 4)),
917*08b48e0bSAndroid Build Coastguard Worker Int32PtrTy);
918*08b48e0bSAndroid Build Coastguard Worker x = IRB.CreateInsertElement(GuardPtr1, val1, (uint64_t)0);
919*08b48e0bSAndroid Build Coastguard Worker
920*08b48e0bSAndroid Build Coastguard Worker Value *val2 = IRB.CreateIntToPtr(
921*08b48e0bSAndroid Build Coastguard Worker IRB.CreateAdd(
922*08b48e0bSAndroid Build Coastguard Worker IRB.CreatePointerCast(FunctionGuardArray, IntptrTy),
923*08b48e0bSAndroid Build Coastguard Worker ConstantInt::get(
924*08b48e0bSAndroid Build Coastguard Worker IntptrTy,
925*08b48e0bSAndroid Build Coastguard Worker (cnt_cov + local_selects++ + AllBlocks.size()) * 4)),
926*08b48e0bSAndroid Build Coastguard Worker Int32PtrTy);
927*08b48e0bSAndroid Build Coastguard Worker y = IRB.CreateInsertElement(GuardPtr2, val2, (uint64_t)0);
928*08b48e0bSAndroid Build Coastguard Worker
929*08b48e0bSAndroid Build Coastguard Worker for (uint64_t i = 1; i < elements; i++) {
930*08b48e0bSAndroid Build Coastguard Worker
931*08b48e0bSAndroid Build Coastguard Worker val1 = IRB.CreateIntToPtr(
932*08b48e0bSAndroid Build Coastguard Worker IRB.CreateAdd(
933*08b48e0bSAndroid Build Coastguard Worker IRB.CreatePointerCast(FunctionGuardArray, IntptrTy),
934*08b48e0bSAndroid Build Coastguard Worker ConstantInt::get(IntptrTy, (cnt_cov + local_selects++ +
935*08b48e0bSAndroid Build Coastguard Worker AllBlocks.size()) *
936*08b48e0bSAndroid Build Coastguard Worker 4)),
937*08b48e0bSAndroid Build Coastguard Worker Int32PtrTy);
938*08b48e0bSAndroid Build Coastguard Worker x = IRB.CreateInsertElement(x, val1, i);
939*08b48e0bSAndroid Build Coastguard Worker
940*08b48e0bSAndroid Build Coastguard Worker val2 = IRB.CreateIntToPtr(
941*08b48e0bSAndroid Build Coastguard Worker IRB.CreateAdd(
942*08b48e0bSAndroid Build Coastguard Worker IRB.CreatePointerCast(FunctionGuardArray, IntptrTy),
943*08b48e0bSAndroid Build Coastguard Worker ConstantInt::get(IntptrTy, (cnt_cov + local_selects++ +
944*08b48e0bSAndroid Build Coastguard Worker AllBlocks.size()) *
945*08b48e0bSAndroid Build Coastguard Worker 4)),
946*08b48e0bSAndroid Build Coastguard Worker Int32PtrTy);
947*08b48e0bSAndroid Build Coastguard Worker y = IRB.CreateInsertElement(y, val2, i);
948*08b48e0bSAndroid Build Coastguard Worker
949*08b48e0bSAndroid Build Coastguard Worker }
950*08b48e0bSAndroid Build Coastguard Worker
951*08b48e0bSAndroid Build Coastguard Worker result = IRB.CreateSelect(condition, x, y);
952*08b48e0bSAndroid Build Coastguard Worker
953*08b48e0bSAndroid Build Coastguard Worker }
954*08b48e0bSAndroid Build Coastguard Worker
955*08b48e0bSAndroid Build Coastguard Worker }
956*08b48e0bSAndroid Build Coastguard Worker
957*08b48e0bSAndroid Build Coastguard Worker } else
958*08b48e0bSAndroid Build Coastguard Worker
959*08b48e0bSAndroid Build Coastguard Worker #endif
960*08b48e0bSAndroid Build Coastguard Worker {
961*08b48e0bSAndroid Build Coastguard Worker
962*08b48e0bSAndroid Build Coastguard Worker // fprintf(stderr, "UNHANDLED: %u\n", t->getTypeID());
963*08b48e0bSAndroid Build Coastguard Worker unhandled++;
964*08b48e0bSAndroid Build Coastguard Worker continue;
965*08b48e0bSAndroid Build Coastguard Worker
966*08b48e0bSAndroid Build Coastguard Worker }
967*08b48e0bSAndroid Build Coastguard Worker
968*08b48e0bSAndroid Build Coastguard Worker uint32_t vector_cur = 0;
969*08b48e0bSAndroid Build Coastguard Worker
970*08b48e0bSAndroid Build Coastguard Worker /* Load SHM pointer */
971*08b48e0bSAndroid Build Coastguard Worker
972*08b48e0bSAndroid Build Coastguard Worker LoadInst *MapPtr =
973*08b48e0bSAndroid Build Coastguard Worker IRB.CreateLoad(PointerType::get(Int8Ty, 0), AFLMapPtr);
974*08b48e0bSAndroid Build Coastguard Worker ModuleSanitizerCoverageAFL::SetNoSanitizeMetadata(MapPtr);
975*08b48e0bSAndroid Build Coastguard Worker
976*08b48e0bSAndroid Build Coastguard Worker while (1) {
977*08b48e0bSAndroid Build Coastguard Worker
978*08b48e0bSAndroid Build Coastguard Worker /* Get CurLoc */
979*08b48e0bSAndroid Build Coastguard Worker LoadInst *CurLoc = nullptr;
980*08b48e0bSAndroid Build Coastguard Worker Value *MapPtrIdx = nullptr;
981*08b48e0bSAndroid Build Coastguard Worker
982*08b48e0bSAndroid Build Coastguard Worker /* Load counter for CurLoc */
983*08b48e0bSAndroid Build Coastguard Worker if (!vector_cnt) {
984*08b48e0bSAndroid Build Coastguard Worker
985*08b48e0bSAndroid Build Coastguard Worker CurLoc = IRB.CreateLoad(IRB.getInt32Ty(), result);
986*08b48e0bSAndroid Build Coastguard Worker ModuleSanitizerCoverageAFL::SetNoSanitizeMetadata(CurLoc);
987*08b48e0bSAndroid Build Coastguard Worker MapPtrIdx = IRB.CreateGEP(Int8Ty, MapPtr, CurLoc);
988*08b48e0bSAndroid Build Coastguard Worker
989*08b48e0bSAndroid Build Coastguard Worker } else {
990*08b48e0bSAndroid Build Coastguard Worker
991*08b48e0bSAndroid Build Coastguard Worker auto element = IRB.CreateExtractElement(result, vector_cur++);
992*08b48e0bSAndroid Build Coastguard Worker auto elementptr = IRB.CreateIntToPtr(element, Int32PtrTy);
993*08b48e0bSAndroid Build Coastguard Worker auto elementld = IRB.CreateLoad(IRB.getInt32Ty(), elementptr);
994*08b48e0bSAndroid Build Coastguard Worker ModuleSanitizerCoverageAFL::SetNoSanitizeMetadata(elementld);
995*08b48e0bSAndroid Build Coastguard Worker MapPtrIdx = IRB.CreateGEP(Int8Ty, MapPtr, elementld);
996*08b48e0bSAndroid Build Coastguard Worker
997*08b48e0bSAndroid Build Coastguard Worker }
998*08b48e0bSAndroid Build Coastguard Worker
999*08b48e0bSAndroid Build Coastguard Worker if (use_threadsafe_counters) {
1000*08b48e0bSAndroid Build Coastguard Worker
1001*08b48e0bSAndroid Build Coastguard Worker IRB.CreateAtomicRMW(llvm::AtomicRMWInst::BinOp::Add, MapPtrIdx, One,
1002*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 13
1003*08b48e0bSAndroid Build Coastguard Worker llvm::MaybeAlign(1),
1004*08b48e0bSAndroid Build Coastguard Worker #endif
1005*08b48e0bSAndroid Build Coastguard Worker llvm::AtomicOrdering::Monotonic);
1006*08b48e0bSAndroid Build Coastguard Worker
1007*08b48e0bSAndroid Build Coastguard Worker } else {
1008*08b48e0bSAndroid Build Coastguard Worker
1009*08b48e0bSAndroid Build Coastguard Worker LoadInst *Counter = IRB.CreateLoad(IRB.getInt8Ty(), MapPtrIdx);
1010*08b48e0bSAndroid Build Coastguard Worker ModuleSanitizerCoverageAFL::SetNoSanitizeMetadata(Counter);
1011*08b48e0bSAndroid Build Coastguard Worker
1012*08b48e0bSAndroid Build Coastguard Worker /* Update bitmap */
1013*08b48e0bSAndroid Build Coastguard Worker
1014*08b48e0bSAndroid Build Coastguard Worker Value *Incr = IRB.CreateAdd(Counter, One);
1015*08b48e0bSAndroid Build Coastguard Worker
1016*08b48e0bSAndroid Build Coastguard Worker if (skip_nozero == NULL) {
1017*08b48e0bSAndroid Build Coastguard Worker
1018*08b48e0bSAndroid Build Coastguard Worker auto cf = IRB.CreateICmpEQ(Incr, Zero);
1019*08b48e0bSAndroid Build Coastguard Worker auto carry = IRB.CreateZExt(cf, Int8Ty);
1020*08b48e0bSAndroid Build Coastguard Worker Incr = IRB.CreateAdd(Incr, carry);
1021*08b48e0bSAndroid Build Coastguard Worker
1022*08b48e0bSAndroid Build Coastguard Worker }
1023*08b48e0bSAndroid Build Coastguard Worker
1024*08b48e0bSAndroid Build Coastguard Worker StoreInst *StoreCtx = IRB.CreateStore(Incr, MapPtrIdx);
1025*08b48e0bSAndroid Build Coastguard Worker ModuleSanitizerCoverageAFL::SetNoSanitizeMetadata(StoreCtx);
1026*08b48e0bSAndroid Build Coastguard Worker
1027*08b48e0bSAndroid Build Coastguard Worker }
1028*08b48e0bSAndroid Build Coastguard Worker
1029*08b48e0bSAndroid Build Coastguard Worker if (!vector_cnt) {
1030*08b48e0bSAndroid Build Coastguard Worker
1031*08b48e0bSAndroid Build Coastguard Worker vector_cnt = 2;
1032*08b48e0bSAndroid Build Coastguard Worker break;
1033*08b48e0bSAndroid Build Coastguard Worker
1034*08b48e0bSAndroid Build Coastguard Worker } else if (vector_cnt == vector_cur) {
1035*08b48e0bSAndroid Build Coastguard Worker
1036*08b48e0bSAndroid Build Coastguard Worker break;
1037*08b48e0bSAndroid Build Coastguard Worker
1038*08b48e0bSAndroid Build Coastguard Worker }
1039*08b48e0bSAndroid Build Coastguard Worker
1040*08b48e0bSAndroid Build Coastguard Worker }
1041*08b48e0bSAndroid Build Coastguard Worker
1042*08b48e0bSAndroid Build Coastguard Worker skip_next = 1;
1043*08b48e0bSAndroid Build Coastguard Worker instr += vector_cnt;
1044*08b48e0bSAndroid Build Coastguard Worker
1045*08b48e0bSAndroid Build Coastguard Worker } else {
1046*08b48e0bSAndroid Build Coastguard Worker
1047*08b48e0bSAndroid Build Coastguard Worker skip_next = 0;
1048*08b48e0bSAndroid Build Coastguard Worker
1049*08b48e0bSAndroid Build Coastguard Worker }
1050*08b48e0bSAndroid Build Coastguard Worker
1051*08b48e0bSAndroid Build Coastguard Worker }
1052*08b48e0bSAndroid Build Coastguard Worker
1053*08b48e0bSAndroid Build Coastguard Worker }
1054*08b48e0bSAndroid Build Coastguard Worker
1055*08b48e0bSAndroid Build Coastguard Worker if (AllBlocks.empty() && !special && !local_selects) return false;
1056*08b48e0bSAndroid Build Coastguard Worker
1057*08b48e0bSAndroid Build Coastguard Worker if (!AllBlocks.empty())
1058*08b48e0bSAndroid Build Coastguard Worker for (size_t i = 0, N = AllBlocks.size(); i < N; i++)
1059*08b48e0bSAndroid Build Coastguard Worker InjectCoverageAtBlock(F, *AllBlocks[i], i, IsLeafFunc);
1060*08b48e0bSAndroid Build Coastguard Worker
1061*08b48e0bSAndroid Build Coastguard Worker return true;
1062*08b48e0bSAndroid Build Coastguard Worker
1063*08b48e0bSAndroid Build Coastguard Worker }
1064*08b48e0bSAndroid Build Coastguard Worker
1065*08b48e0bSAndroid Build Coastguard Worker // For every switch statement we insert a call:
1066*08b48e0bSAndroid Build Coastguard Worker // __sanitizer_cov_trace_switch(CondValue,
1067*08b48e0bSAndroid Build Coastguard Worker // {NumCases, ValueSizeInBits, Case0Value, Case1Value, Case2Value, ... })
1068*08b48e0bSAndroid Build Coastguard Worker
InjectTraceForSwitch(Function &,ArrayRef<Instruction * > SwitchTraceTargets)1069*08b48e0bSAndroid Build Coastguard Worker void ModuleSanitizerCoverageAFL::InjectTraceForSwitch(
1070*08b48e0bSAndroid Build Coastguard Worker Function &, ArrayRef<Instruction *> SwitchTraceTargets) {
1071*08b48e0bSAndroid Build Coastguard Worker
1072*08b48e0bSAndroid Build Coastguard Worker for (auto I : SwitchTraceTargets) {
1073*08b48e0bSAndroid Build Coastguard Worker
1074*08b48e0bSAndroid Build Coastguard Worker if (SwitchInst *SI = dyn_cast<SwitchInst>(I)) {
1075*08b48e0bSAndroid Build Coastguard Worker
1076*08b48e0bSAndroid Build Coastguard Worker IRBuilder<> IRB(I);
1077*08b48e0bSAndroid Build Coastguard Worker SmallVector<Constant *, 16> Initializers;
1078*08b48e0bSAndroid Build Coastguard Worker Value *Cond = SI->getCondition();
1079*08b48e0bSAndroid Build Coastguard Worker if (Cond->getType()->getScalarSizeInBits() >
1080*08b48e0bSAndroid Build Coastguard Worker Int64Ty->getScalarSizeInBits())
1081*08b48e0bSAndroid Build Coastguard Worker continue;
1082*08b48e0bSAndroid Build Coastguard Worker Initializers.push_back(ConstantInt::get(Int64Ty, SI->getNumCases()));
1083*08b48e0bSAndroid Build Coastguard Worker Initializers.push_back(
1084*08b48e0bSAndroid Build Coastguard Worker ConstantInt::get(Int64Ty, Cond->getType()->getScalarSizeInBits()));
1085*08b48e0bSAndroid Build Coastguard Worker if (Cond->getType()->getScalarSizeInBits() <
1086*08b48e0bSAndroid Build Coastguard Worker Int64Ty->getScalarSizeInBits())
1087*08b48e0bSAndroid Build Coastguard Worker Cond = IRB.CreateIntCast(Cond, Int64Ty, false);
1088*08b48e0bSAndroid Build Coastguard Worker for (auto It : SI->cases()) {
1089*08b48e0bSAndroid Build Coastguard Worker
1090*08b48e0bSAndroid Build Coastguard Worker Constant *C = It.getCaseValue();
1091*08b48e0bSAndroid Build Coastguard Worker if (C->getType()->getScalarSizeInBits() <
1092*08b48e0bSAndroid Build Coastguard Worker Int64Ty->getScalarSizeInBits())
1093*08b48e0bSAndroid Build Coastguard Worker C = ConstantExpr::getCast(CastInst::ZExt, It.getCaseValue(), Int64Ty);
1094*08b48e0bSAndroid Build Coastguard Worker Initializers.push_back(C);
1095*08b48e0bSAndroid Build Coastguard Worker
1096*08b48e0bSAndroid Build Coastguard Worker }
1097*08b48e0bSAndroid Build Coastguard Worker
1098*08b48e0bSAndroid Build Coastguard Worker llvm::sort(drop_begin(Initializers, 2),
1099*08b48e0bSAndroid Build Coastguard Worker [](const Constant *A, const Constant *B) {
1100*08b48e0bSAndroid Build Coastguard Worker
1101*08b48e0bSAndroid Build Coastguard Worker return cast<ConstantInt>(A)->getLimitedValue() <
1102*08b48e0bSAndroid Build Coastguard Worker cast<ConstantInt>(B)->getLimitedValue();
1103*08b48e0bSAndroid Build Coastguard Worker
1104*08b48e0bSAndroid Build Coastguard Worker });
1105*08b48e0bSAndroid Build Coastguard Worker
1106*08b48e0bSAndroid Build Coastguard Worker ArrayType *ArrayOfInt64Ty = ArrayType::get(Int64Ty, Initializers.size());
1107*08b48e0bSAndroid Build Coastguard Worker GlobalVariable *GV = new GlobalVariable(
1108*08b48e0bSAndroid Build Coastguard Worker *CurModule, ArrayOfInt64Ty, false, GlobalVariable::InternalLinkage,
1109*08b48e0bSAndroid Build Coastguard Worker ConstantArray::get(ArrayOfInt64Ty, Initializers),
1110*08b48e0bSAndroid Build Coastguard Worker "__sancov_gen_cov_switch_values");
1111*08b48e0bSAndroid Build Coastguard Worker IRB.CreateCall(SanCovTraceSwitchFunction,
1112*08b48e0bSAndroid Build Coastguard Worker {Cond, IRB.CreatePointerCast(GV, Int64PtrTy)});
1113*08b48e0bSAndroid Build Coastguard Worker
1114*08b48e0bSAndroid Build Coastguard Worker }
1115*08b48e0bSAndroid Build Coastguard Worker
1116*08b48e0bSAndroid Build Coastguard Worker }
1117*08b48e0bSAndroid Build Coastguard Worker
1118*08b48e0bSAndroid Build Coastguard Worker }
1119*08b48e0bSAndroid Build Coastguard Worker
InjectTraceForCmp(Function &,ArrayRef<Instruction * > CmpTraceTargets)1120*08b48e0bSAndroid Build Coastguard Worker void ModuleSanitizerCoverageAFL::InjectTraceForCmp(
1121*08b48e0bSAndroid Build Coastguard Worker Function &, ArrayRef<Instruction *> CmpTraceTargets) {
1122*08b48e0bSAndroid Build Coastguard Worker
1123*08b48e0bSAndroid Build Coastguard Worker for (auto I : CmpTraceTargets) {
1124*08b48e0bSAndroid Build Coastguard Worker
1125*08b48e0bSAndroid Build Coastguard Worker if (ICmpInst *ICMP = dyn_cast<ICmpInst>(I)) {
1126*08b48e0bSAndroid Build Coastguard Worker
1127*08b48e0bSAndroid Build Coastguard Worker IRBuilder<> IRB(ICMP);
1128*08b48e0bSAndroid Build Coastguard Worker Value *A0 = ICMP->getOperand(0);
1129*08b48e0bSAndroid Build Coastguard Worker Value *A1 = ICMP->getOperand(1);
1130*08b48e0bSAndroid Build Coastguard Worker if (!A0->getType()->isIntegerTy()) continue;
1131*08b48e0bSAndroid Build Coastguard Worker uint64_t TypeSize = DL->getTypeStoreSizeInBits(A0->getType());
1132*08b48e0bSAndroid Build Coastguard Worker int CallbackIdx = TypeSize == 8 ? 0
1133*08b48e0bSAndroid Build Coastguard Worker : TypeSize == 16 ? 1
1134*08b48e0bSAndroid Build Coastguard Worker : TypeSize == 32 ? 2
1135*08b48e0bSAndroid Build Coastguard Worker : TypeSize == 64 ? 3
1136*08b48e0bSAndroid Build Coastguard Worker : -1;
1137*08b48e0bSAndroid Build Coastguard Worker if (CallbackIdx < 0) continue;
1138*08b48e0bSAndroid Build Coastguard Worker // __sanitizer_cov_trace_cmp((type_size << 32) | predicate, A0, A1);
1139*08b48e0bSAndroid Build Coastguard Worker auto CallbackFunc = SanCovTraceCmpFunction[CallbackIdx];
1140*08b48e0bSAndroid Build Coastguard Worker bool FirstIsConst = isa<ConstantInt>(A0);
1141*08b48e0bSAndroid Build Coastguard Worker bool SecondIsConst = isa<ConstantInt>(A1);
1142*08b48e0bSAndroid Build Coastguard Worker // If both are const, then we don't need such a comparison.
1143*08b48e0bSAndroid Build Coastguard Worker if (FirstIsConst && SecondIsConst) continue;
1144*08b48e0bSAndroid Build Coastguard Worker // If only one is const, then make it the first callback argument.
1145*08b48e0bSAndroid Build Coastguard Worker if (FirstIsConst || SecondIsConst) {
1146*08b48e0bSAndroid Build Coastguard Worker
1147*08b48e0bSAndroid Build Coastguard Worker CallbackFunc = SanCovTraceConstCmpFunction[CallbackIdx];
1148*08b48e0bSAndroid Build Coastguard Worker if (SecondIsConst) std::swap(A0, A1);
1149*08b48e0bSAndroid Build Coastguard Worker
1150*08b48e0bSAndroid Build Coastguard Worker }
1151*08b48e0bSAndroid Build Coastguard Worker
1152*08b48e0bSAndroid Build Coastguard Worker auto Ty = Type::getIntNTy(*C, TypeSize);
1153*08b48e0bSAndroid Build Coastguard Worker IRB.CreateCall(CallbackFunc, {IRB.CreateIntCast(A0, Ty, true),
1154*08b48e0bSAndroid Build Coastguard Worker IRB.CreateIntCast(A1, Ty, true)});
1155*08b48e0bSAndroid Build Coastguard Worker
1156*08b48e0bSAndroid Build Coastguard Worker }
1157*08b48e0bSAndroid Build Coastguard Worker
1158*08b48e0bSAndroid Build Coastguard Worker }
1159*08b48e0bSAndroid Build Coastguard Worker
1160*08b48e0bSAndroid Build Coastguard Worker }
1161*08b48e0bSAndroid Build Coastguard Worker
InjectCoverageAtBlock(Function & F,BasicBlock & BB,size_t Idx,bool IsLeafFunc)1162*08b48e0bSAndroid Build Coastguard Worker void ModuleSanitizerCoverageAFL::InjectCoverageAtBlock(Function &F,
1163*08b48e0bSAndroid Build Coastguard Worker BasicBlock &BB,
1164*08b48e0bSAndroid Build Coastguard Worker size_t Idx,
1165*08b48e0bSAndroid Build Coastguard Worker bool IsLeafFunc) {
1166*08b48e0bSAndroid Build Coastguard Worker
1167*08b48e0bSAndroid Build Coastguard Worker BasicBlock::iterator IP = BB.getFirstInsertionPt();
1168*08b48e0bSAndroid Build Coastguard Worker bool IsEntryBB = &BB == &F.getEntryBlock();
1169*08b48e0bSAndroid Build Coastguard Worker DebugLoc EntryLoc;
1170*08b48e0bSAndroid Build Coastguard Worker
1171*08b48e0bSAndroid Build Coastguard Worker if (IsEntryBB) {
1172*08b48e0bSAndroid Build Coastguard Worker
1173*08b48e0bSAndroid Build Coastguard Worker if (auto SP = F.getSubprogram())
1174*08b48e0bSAndroid Build Coastguard Worker EntryLoc = DILocation::get(SP->getContext(), SP->getScopeLine(), 0, SP);
1175*08b48e0bSAndroid Build Coastguard Worker // Keep static allocas and llvm.localescape calls in the entry block. Even
1176*08b48e0bSAndroid Build Coastguard Worker // if we aren't splitting the block, it's nice for allocas to be before
1177*08b48e0bSAndroid Build Coastguard Worker // calls.
1178*08b48e0bSAndroid Build Coastguard Worker IP = PrepareToSplitEntryBlock(BB, IP);
1179*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR < 15
1180*08b48e0bSAndroid Build Coastguard Worker
1181*08b48e0bSAndroid Build Coastguard Worker } else {
1182*08b48e0bSAndroid Build Coastguard Worker
1183*08b48e0bSAndroid Build Coastguard Worker EntryLoc = IP->getDebugLoc();
1184*08b48e0bSAndroid Build Coastguard Worker if (!EntryLoc)
1185*08b48e0bSAndroid Build Coastguard Worker if (auto *SP = F.getSubprogram())
1186*08b48e0bSAndroid Build Coastguard Worker EntryLoc = DILocation::get(SP->getContext(), 0, 0, SP);
1187*08b48e0bSAndroid Build Coastguard Worker #endif
1188*08b48e0bSAndroid Build Coastguard Worker
1189*08b48e0bSAndroid Build Coastguard Worker }
1190*08b48e0bSAndroid Build Coastguard Worker
1191*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 16
1192*08b48e0bSAndroid Build Coastguard Worker InstrumentationIRBuilder IRB(&*IP);
1193*08b48e0bSAndroid Build Coastguard Worker #else
1194*08b48e0bSAndroid Build Coastguard Worker IRBuilder<> IRB(&*IP);
1195*08b48e0bSAndroid Build Coastguard Worker #endif
1196*08b48e0bSAndroid Build Coastguard Worker if (EntryLoc) IRB.SetCurrentDebugLocation(EntryLoc);
1197*08b48e0bSAndroid Build Coastguard Worker if (Options.TracePCGuard) {
1198*08b48e0bSAndroid Build Coastguard Worker
1199*08b48e0bSAndroid Build Coastguard Worker /*
1200*08b48e0bSAndroid Build Coastguard Worker auto GuardPtr = IRB.CreateIntToPtr(
1201*08b48e0bSAndroid Build Coastguard Worker IRB.CreateAdd(IRB.CreatePointerCast(FunctionGuardArray, IntptrTy),
1202*08b48e0bSAndroid Build Coastguard Worker ConstantInt::get(IntptrTy, Idx * 4)),
1203*08b48e0bSAndroid Build Coastguard Worker Int32PtrTy);
1204*08b48e0bSAndroid Build Coastguard Worker IRB.CreateCall(SanCovTracePCGuard, GuardPtr)->setCannotMerge();
1205*08b48e0bSAndroid Build Coastguard Worker */
1206*08b48e0bSAndroid Build Coastguard Worker
1207*08b48e0bSAndroid Build Coastguard Worker /* Get CurLoc */
1208*08b48e0bSAndroid Build Coastguard Worker
1209*08b48e0bSAndroid Build Coastguard Worker Value *GuardPtr = IRB.CreateIntToPtr(
1210*08b48e0bSAndroid Build Coastguard Worker IRB.CreateAdd(IRB.CreatePointerCast(FunctionGuardArray, IntptrTy),
1211*08b48e0bSAndroid Build Coastguard Worker ConstantInt::get(IntptrTy, Idx * 4)),
1212*08b48e0bSAndroid Build Coastguard Worker Int32PtrTy);
1213*08b48e0bSAndroid Build Coastguard Worker
1214*08b48e0bSAndroid Build Coastguard Worker LoadInst *CurLoc = IRB.CreateLoad(IRB.getInt32Ty(), GuardPtr);
1215*08b48e0bSAndroid Build Coastguard Worker ModuleSanitizerCoverageAFL::SetNoSanitizeMetadata(CurLoc);
1216*08b48e0bSAndroid Build Coastguard Worker
1217*08b48e0bSAndroid Build Coastguard Worker /* Load SHM pointer */
1218*08b48e0bSAndroid Build Coastguard Worker
1219*08b48e0bSAndroid Build Coastguard Worker LoadInst *MapPtr = IRB.CreateLoad(PointerType::get(Int8Ty, 0), AFLMapPtr);
1220*08b48e0bSAndroid Build Coastguard Worker ModuleSanitizerCoverageAFL::SetNoSanitizeMetadata(MapPtr);
1221*08b48e0bSAndroid Build Coastguard Worker
1222*08b48e0bSAndroid Build Coastguard Worker /* Load counter for CurLoc */
1223*08b48e0bSAndroid Build Coastguard Worker
1224*08b48e0bSAndroid Build Coastguard Worker Value *MapPtrIdx = IRB.CreateGEP(Int8Ty, MapPtr, CurLoc);
1225*08b48e0bSAndroid Build Coastguard Worker
1226*08b48e0bSAndroid Build Coastguard Worker if (use_threadsafe_counters) {
1227*08b48e0bSAndroid Build Coastguard Worker
1228*08b48e0bSAndroid Build Coastguard Worker IRB.CreateAtomicRMW(llvm::AtomicRMWInst::BinOp::Add, MapPtrIdx, One,
1229*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 13
1230*08b48e0bSAndroid Build Coastguard Worker llvm::MaybeAlign(1),
1231*08b48e0bSAndroid Build Coastguard Worker #endif
1232*08b48e0bSAndroid Build Coastguard Worker llvm::AtomicOrdering::Monotonic);
1233*08b48e0bSAndroid Build Coastguard Worker
1234*08b48e0bSAndroid Build Coastguard Worker } else {
1235*08b48e0bSAndroid Build Coastguard Worker
1236*08b48e0bSAndroid Build Coastguard Worker LoadInst *Counter = IRB.CreateLoad(IRB.getInt8Ty(), MapPtrIdx);
1237*08b48e0bSAndroid Build Coastguard Worker ModuleSanitizerCoverageAFL::SetNoSanitizeMetadata(Counter);
1238*08b48e0bSAndroid Build Coastguard Worker
1239*08b48e0bSAndroid Build Coastguard Worker /* Update bitmap */
1240*08b48e0bSAndroid Build Coastguard Worker
1241*08b48e0bSAndroid Build Coastguard Worker Value *Incr = IRB.CreateAdd(Counter, One);
1242*08b48e0bSAndroid Build Coastguard Worker
1243*08b48e0bSAndroid Build Coastguard Worker if (skip_nozero == NULL) {
1244*08b48e0bSAndroid Build Coastguard Worker
1245*08b48e0bSAndroid Build Coastguard Worker auto cf = IRB.CreateICmpEQ(Incr, Zero);
1246*08b48e0bSAndroid Build Coastguard Worker auto carry = IRB.CreateZExt(cf, Int8Ty);
1247*08b48e0bSAndroid Build Coastguard Worker Incr = IRB.CreateAdd(Incr, carry);
1248*08b48e0bSAndroid Build Coastguard Worker
1249*08b48e0bSAndroid Build Coastguard Worker }
1250*08b48e0bSAndroid Build Coastguard Worker
1251*08b48e0bSAndroid Build Coastguard Worker StoreInst *StoreCtx = IRB.CreateStore(Incr, MapPtrIdx);
1252*08b48e0bSAndroid Build Coastguard Worker ModuleSanitizerCoverageAFL::SetNoSanitizeMetadata(StoreCtx);
1253*08b48e0bSAndroid Build Coastguard Worker
1254*08b48e0bSAndroid Build Coastguard Worker }
1255*08b48e0bSAndroid Build Coastguard Worker
1256*08b48e0bSAndroid Build Coastguard Worker // done :)
1257*08b48e0bSAndroid Build Coastguard Worker
1258*08b48e0bSAndroid Build Coastguard Worker // IRB.CreateCall(SanCovTracePCGuard, Offset)->setCannotMerge();
1259*08b48e0bSAndroid Build Coastguard Worker // IRB.CreateCall(SanCovTracePCGuard, GuardPtr)->setCannotMerge();
1260*08b48e0bSAndroid Build Coastguard Worker ++instr;
1261*08b48e0bSAndroid Build Coastguard Worker
1262*08b48e0bSAndroid Build Coastguard Worker }
1263*08b48e0bSAndroid Build Coastguard Worker
1264*08b48e0bSAndroid Build Coastguard Worker }
1265*08b48e0bSAndroid Build Coastguard Worker
getSectionName(const std::string & Section) const1266*08b48e0bSAndroid Build Coastguard Worker std::string ModuleSanitizerCoverageAFL::getSectionName(
1267*08b48e0bSAndroid Build Coastguard Worker const std::string &Section) const {
1268*08b48e0bSAndroid Build Coastguard Worker
1269*08b48e0bSAndroid Build Coastguard Worker if (TargetTriple.isOSBinFormatCOFF()) {
1270*08b48e0bSAndroid Build Coastguard Worker
1271*08b48e0bSAndroid Build Coastguard Worker if (Section == SanCovCountersSectionName) return ".SCOV$CM";
1272*08b48e0bSAndroid Build Coastguard Worker if (Section == SanCovBoolFlagSectionName) return ".SCOV$BM";
1273*08b48e0bSAndroid Build Coastguard Worker if (Section == SanCovPCsSectionName) return ".SCOVP$M";
1274*08b48e0bSAndroid Build Coastguard Worker return ".SCOV$GM"; // For SanCovGuardsSectionName.
1275*08b48e0bSAndroid Build Coastguard Worker
1276*08b48e0bSAndroid Build Coastguard Worker }
1277*08b48e0bSAndroid Build Coastguard Worker
1278*08b48e0bSAndroid Build Coastguard Worker if (TargetTriple.isOSBinFormatMachO()) return "__DATA,__" + Section;
1279*08b48e0bSAndroid Build Coastguard Worker return "__" + Section;
1280*08b48e0bSAndroid Build Coastguard Worker
1281*08b48e0bSAndroid Build Coastguard Worker }
1282*08b48e0bSAndroid Build Coastguard Worker
getSectionStart(const std::string & Section) const1283*08b48e0bSAndroid Build Coastguard Worker std::string ModuleSanitizerCoverageAFL::getSectionStart(
1284*08b48e0bSAndroid Build Coastguard Worker const std::string &Section) const {
1285*08b48e0bSAndroid Build Coastguard Worker
1286*08b48e0bSAndroid Build Coastguard Worker if (TargetTriple.isOSBinFormatMachO())
1287*08b48e0bSAndroid Build Coastguard Worker return "\1section$start$__DATA$__" + Section;
1288*08b48e0bSAndroid Build Coastguard Worker return "__start___" + Section;
1289*08b48e0bSAndroid Build Coastguard Worker
1290*08b48e0bSAndroid Build Coastguard Worker }
1291*08b48e0bSAndroid Build Coastguard Worker
getSectionEnd(const std::string & Section) const1292*08b48e0bSAndroid Build Coastguard Worker std::string ModuleSanitizerCoverageAFL::getSectionEnd(
1293*08b48e0bSAndroid Build Coastguard Worker const std::string &Section) const {
1294*08b48e0bSAndroid Build Coastguard Worker
1295*08b48e0bSAndroid Build Coastguard Worker if (TargetTriple.isOSBinFormatMachO())
1296*08b48e0bSAndroid Build Coastguard Worker return "\1section$end$__DATA$__" + Section;
1297*08b48e0bSAndroid Build Coastguard Worker return "__stop___" + Section;
1298*08b48e0bSAndroid Build Coastguard Worker
1299*08b48e0bSAndroid Build Coastguard Worker }
1300*08b48e0bSAndroid Build Coastguard Worker
1301