xref: /aosp_15_r20/external/AFLplusplus/instrumentation/SanitizerCoveragePCGUARD.so.cc (revision 08b48e0b10e97b33e7b60c5b6e2243bd915777f2)
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