xref: /aosp_15_r20/external/AFLplusplus/instrumentation/SanitizerCoverageLTO.so.cc (revision 08b48e0b10e97b33e7b60c5b6e2243bd915777f2)
1*08b48e0bSAndroid Build Coastguard Worker /* SanitizeCoverage.cpp ported to AFL++ LTO :-) */
2*08b48e0bSAndroid Build Coastguard Worker 
3*08b48e0bSAndroid Build Coastguard Worker #define AFL_LLVM_PASS
4*08b48e0bSAndroid Build Coastguard Worker 
5*08b48e0bSAndroid Build Coastguard Worker #include <stdio.h>
6*08b48e0bSAndroid Build Coastguard Worker #include <stdlib.h>
7*08b48e0bSAndroid Build Coastguard Worker #include <unistd.h>
8*08b48e0bSAndroid Build Coastguard Worker #include <string.h>
9*08b48e0bSAndroid Build Coastguard Worker #include <sys/time.h>
10*08b48e0bSAndroid Build Coastguard Worker 
11*08b48e0bSAndroid Build Coastguard Worker #include <list>
12*08b48e0bSAndroid Build Coastguard Worker #include <string>
13*08b48e0bSAndroid Build Coastguard Worker #include <fstream>
14*08b48e0bSAndroid Build Coastguard Worker #include <set>
15*08b48e0bSAndroid Build Coastguard Worker #include <iostream>
16*08b48e0bSAndroid Build Coastguard Worker 
17*08b48e0bSAndroid Build Coastguard Worker #include "llvm/Transforms/Instrumentation/SanitizerCoverage.h"
18*08b48e0bSAndroid Build Coastguard Worker #include "llvm/ADT/ArrayRef.h"
19*08b48e0bSAndroid Build Coastguard Worker #include "llvm/ADT/SmallVector.h"
20*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR < 17
21*08b48e0bSAndroid Build Coastguard Worker   #include "llvm/ADT/Triple.h"
22*08b48e0bSAndroid Build Coastguard Worker   #include "llvm/Analysis/EHPersonalities.h"
23*08b48e0bSAndroid Build Coastguard Worker #else
24*08b48e0bSAndroid Build Coastguard Worker   #include "llvm/IR/EHPersonalities.h"
25*08b48e0bSAndroid Build Coastguard Worker #endif
26*08b48e0bSAndroid Build Coastguard Worker #include "llvm/Analysis/PostDominators.h"
27*08b48e0bSAndroid Build Coastguard Worker #include "llvm/Analysis/ValueTracking.h"
28*08b48e0bSAndroid Build Coastguard Worker #include "llvm/IR/BasicBlock.h"
29*08b48e0bSAndroid Build Coastguard Worker #include "llvm/IR/CFG.h"
30*08b48e0bSAndroid Build Coastguard Worker #include "llvm/IR/Constant.h"
31*08b48e0bSAndroid Build Coastguard Worker #include "llvm/IR/DataLayout.h"
32*08b48e0bSAndroid Build Coastguard Worker #include "llvm/IR/DebugInfo.h"
33*08b48e0bSAndroid Build Coastguard Worker #include "llvm/IR/Dominators.h"
34*08b48e0bSAndroid Build Coastguard Worker #include "llvm/IR/Function.h"
35*08b48e0bSAndroid Build Coastguard Worker #include "llvm/IR/GlobalVariable.h"
36*08b48e0bSAndroid Build Coastguard Worker #include "llvm/IR/IRBuilder.h"
37*08b48e0bSAndroid Build Coastguard Worker #include "llvm/IR/InlineAsm.h"
38*08b48e0bSAndroid Build Coastguard Worker #include "llvm/IR/Instructions.h"
39*08b48e0bSAndroid Build Coastguard Worker #include "llvm/IR/IntrinsicInst.h"
40*08b48e0bSAndroid Build Coastguard Worker #include "llvm/IR/Intrinsics.h"
41*08b48e0bSAndroid Build Coastguard Worker #include "llvm/IR/LLVMContext.h"
42*08b48e0bSAndroid Build Coastguard Worker #include "llvm/IR/MDBuilder.h"
43*08b48e0bSAndroid Build Coastguard Worker #include "llvm/IR/Mangler.h"
44*08b48e0bSAndroid Build Coastguard Worker #include "llvm/IR/Module.h"
45*08b48e0bSAndroid Build Coastguard Worker #include "llvm/IR/Type.h"
46*08b48e0bSAndroid Build Coastguard Worker #include "llvm/InitializePasses.h"
47*08b48e0bSAndroid Build Coastguard Worker #include "llvm/Pass.h"
48*08b48e0bSAndroid Build Coastguard Worker #include "llvm/Support/CommandLine.h"
49*08b48e0bSAndroid Build Coastguard Worker #include "llvm/Support/Debug.h"
50*08b48e0bSAndroid Build Coastguard Worker #include "llvm/Support/SpecialCaseList.h"
51*08b48e0bSAndroid Build Coastguard Worker #include "llvm/Support/VirtualFileSystem.h"
52*08b48e0bSAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
53*08b48e0bSAndroid Build Coastguard Worker #include "llvm/Transforms/Instrumentation.h"
54*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR < 17
55*08b48e0bSAndroid Build Coastguard Worker   #include "llvm/Transforms/IPO/PassManagerBuilder.h"
56*08b48e0bSAndroid Build Coastguard Worker #endif
57*08b48e0bSAndroid Build Coastguard Worker #include "llvm/Transforms/Utils/BasicBlockUtils.h"
58*08b48e0bSAndroid Build Coastguard Worker #include "llvm/Transforms/Utils/BasicBlockUtils.h"
59*08b48e0bSAndroid Build Coastguard Worker #include "llvm/Transforms/Utils/ModuleUtils.h"
60*08b48e0bSAndroid Build Coastguard Worker #include "llvm/Passes/PassPlugin.h"
61*08b48e0bSAndroid Build Coastguard Worker #include "llvm/Passes/PassBuilder.h"
62*08b48e0bSAndroid Build Coastguard Worker #include "llvm/IR/PassManager.h"
63*08b48e0bSAndroid Build Coastguard Worker 
64*08b48e0bSAndroid Build Coastguard Worker #include "config.h"
65*08b48e0bSAndroid Build Coastguard Worker #include "debug.h"
66*08b48e0bSAndroid Build Coastguard Worker #include "afl-llvm-common.h"
67*08b48e0bSAndroid Build Coastguard Worker 
68*08b48e0bSAndroid Build Coastguard Worker using namespace llvm;
69*08b48e0bSAndroid Build Coastguard Worker 
70*08b48e0bSAndroid Build Coastguard Worker #define DEBUG_TYPE "sancov"
71*08b48e0bSAndroid Build Coastguard Worker 
72*08b48e0bSAndroid Build Coastguard Worker const char SanCovTracePCIndirName[] = "__sanitizer_cov_trace_pc_indir";
73*08b48e0bSAndroid Build Coastguard Worker const char SanCovTracePCName[] = "__sanitizer_cov_trace_pc";
74*08b48e0bSAndroid Build Coastguard Worker // const char SanCovTracePCGuardName =
75*08b48e0bSAndroid Build Coastguard Worker //    "__sanitizer_cov_trace_pc_guard";
76*08b48e0bSAndroid Build Coastguard Worker const char SanCovGuardsSectionName[] = "sancov_guards";
77*08b48e0bSAndroid Build Coastguard Worker const char SanCovCountersSectionName[] = "sancov_cntrs";
78*08b48e0bSAndroid Build Coastguard Worker const char SanCovBoolFlagSectionName[] = "sancov_bools";
79*08b48e0bSAndroid Build Coastguard Worker const char SanCovPCsSectionName[] = "sancov_pcs";
80*08b48e0bSAndroid Build Coastguard Worker 
81*08b48e0bSAndroid Build Coastguard Worker static cl::opt<int> ClCoverageLevel(
82*08b48e0bSAndroid Build Coastguard Worker     "lto-coverage-level",
83*08b48e0bSAndroid Build Coastguard Worker     cl::desc("Sanitizer Coverage. 0: none, 1: entry block, 2: all blocks, "
84*08b48e0bSAndroid Build Coastguard Worker              "3: all blocks and critical edges"),
85*08b48e0bSAndroid Build Coastguard Worker     cl::Hidden, cl::init(3));
86*08b48e0bSAndroid Build Coastguard Worker 
87*08b48e0bSAndroid Build Coastguard Worker static cl::opt<bool> ClTracePC("lto-coverage-trace-pc",
88*08b48e0bSAndroid Build Coastguard Worker                                cl::desc("Experimental pc tracing"), cl::Hidden,
89*08b48e0bSAndroid Build Coastguard Worker                                cl::init(false));
90*08b48e0bSAndroid Build Coastguard Worker 
91*08b48e0bSAndroid Build Coastguard Worker static cl::opt<bool> ClTracePCGuard("lto-coverage-trace-pc-guard",
92*08b48e0bSAndroid Build Coastguard Worker                                     cl::desc("pc tracing with a guard"),
93*08b48e0bSAndroid Build Coastguard Worker                                     cl::Hidden, cl::init(false));
94*08b48e0bSAndroid Build Coastguard Worker 
95*08b48e0bSAndroid Build Coastguard Worker // If true, we create a global variable that contains PCs of all instrumented
96*08b48e0bSAndroid Build Coastguard Worker // BBs, put this global into a named section, and pass this section's bounds
97*08b48e0bSAndroid Build Coastguard Worker // to __sanitizer_cov_pcs_init.
98*08b48e0bSAndroid Build Coastguard Worker // This way the coverage instrumentation does not need to acquire the PCs
99*08b48e0bSAndroid Build Coastguard Worker // at run-time. Works with trace-pc-guard, inline-8bit-counters, and
100*08b48e0bSAndroid Build Coastguard Worker // inline-bool-flag.
101*08b48e0bSAndroid Build Coastguard Worker static cl::opt<bool> ClCreatePCTable("lto-coverage-pc-table",
102*08b48e0bSAndroid Build Coastguard Worker                                      cl::desc("create a static PC table"),
103*08b48e0bSAndroid Build Coastguard Worker                                      cl::Hidden, cl::init(false));
104*08b48e0bSAndroid Build Coastguard Worker 
105*08b48e0bSAndroid Build Coastguard Worker static cl::opt<bool> ClInline8bitCounters(
106*08b48e0bSAndroid Build Coastguard Worker     "lto-coverage-inline-8bit-counters",
107*08b48e0bSAndroid Build Coastguard Worker     cl::desc("increments 8-bit counter for every edge"), cl::Hidden,
108*08b48e0bSAndroid Build Coastguard Worker     cl::init(false));
109*08b48e0bSAndroid Build Coastguard Worker 
110*08b48e0bSAndroid Build Coastguard Worker static cl::opt<bool> ClInlineBoolFlag(
111*08b48e0bSAndroid Build Coastguard Worker     "lto-coverage-inline-bool-flag",
112*08b48e0bSAndroid Build Coastguard Worker     cl::desc("sets a boolean flag for every edge"), cl::Hidden,
113*08b48e0bSAndroid Build Coastguard Worker     cl::init(false));
114*08b48e0bSAndroid Build Coastguard Worker 
115*08b48e0bSAndroid Build Coastguard Worker static cl::opt<bool> ClPruneBlocks(
116*08b48e0bSAndroid Build Coastguard Worker     "lto-coverage-prune-blocks",
117*08b48e0bSAndroid Build Coastguard Worker     cl::desc("Reduce the number of instrumented blocks"), cl::Hidden,
118*08b48e0bSAndroid Build Coastguard Worker     cl::init(true));
119*08b48e0bSAndroid Build Coastguard Worker 
120*08b48e0bSAndroid Build Coastguard Worker namespace llvm {
121*08b48e0bSAndroid Build Coastguard Worker 
122*08b48e0bSAndroid Build Coastguard Worker void initializeModuleSanitizerCoverageLTOLegacyPassPass(PassRegistry &PB);
123*08b48e0bSAndroid Build Coastguard Worker 
124*08b48e0bSAndroid Build Coastguard Worker }
125*08b48e0bSAndroid Build Coastguard Worker 
126*08b48e0bSAndroid Build Coastguard Worker namespace {
127*08b48e0bSAndroid Build Coastguard Worker 
getOptions(int LegacyCoverageLevel)128*08b48e0bSAndroid Build Coastguard Worker SanitizerCoverageOptions getOptions(int LegacyCoverageLevel) {
129*08b48e0bSAndroid Build Coastguard Worker 
130*08b48e0bSAndroid Build Coastguard Worker   SanitizerCoverageOptions Res;
131*08b48e0bSAndroid Build Coastguard Worker   switch (LegacyCoverageLevel) {
132*08b48e0bSAndroid Build Coastguard Worker 
133*08b48e0bSAndroid Build Coastguard Worker     case 0:
134*08b48e0bSAndroid Build Coastguard Worker       Res.CoverageType = SanitizerCoverageOptions::SCK_None;
135*08b48e0bSAndroid Build Coastguard Worker       break;
136*08b48e0bSAndroid Build Coastguard Worker     case 1:
137*08b48e0bSAndroid Build Coastguard Worker       Res.CoverageType = SanitizerCoverageOptions::SCK_Function;
138*08b48e0bSAndroid Build Coastguard Worker       break;
139*08b48e0bSAndroid Build Coastguard Worker     case 2:
140*08b48e0bSAndroid Build Coastguard Worker       Res.CoverageType = SanitizerCoverageOptions::SCK_BB;
141*08b48e0bSAndroid Build Coastguard Worker       break;
142*08b48e0bSAndroid Build Coastguard Worker     case 3:
143*08b48e0bSAndroid Build Coastguard Worker       Res.CoverageType = SanitizerCoverageOptions::SCK_Edge;
144*08b48e0bSAndroid Build Coastguard Worker       break;
145*08b48e0bSAndroid Build Coastguard Worker     case 4:
146*08b48e0bSAndroid Build Coastguard Worker       Res.CoverageType = SanitizerCoverageOptions::SCK_Edge;
147*08b48e0bSAndroid Build Coastguard Worker       Res.IndirectCalls = true;
148*08b48e0bSAndroid Build Coastguard Worker       break;
149*08b48e0bSAndroid Build Coastguard Worker 
150*08b48e0bSAndroid Build Coastguard Worker   }
151*08b48e0bSAndroid Build Coastguard Worker 
152*08b48e0bSAndroid Build Coastguard Worker   return Res;
153*08b48e0bSAndroid Build Coastguard Worker 
154*08b48e0bSAndroid Build Coastguard Worker }
155*08b48e0bSAndroid Build Coastguard Worker 
OverrideFromCL(SanitizerCoverageOptions Options)156*08b48e0bSAndroid Build Coastguard Worker SanitizerCoverageOptions OverrideFromCL(SanitizerCoverageOptions Options) {
157*08b48e0bSAndroid Build Coastguard Worker 
158*08b48e0bSAndroid Build Coastguard Worker   // Sets CoverageType and IndirectCalls.
159*08b48e0bSAndroid Build Coastguard Worker   SanitizerCoverageOptions CLOpts = getOptions(ClCoverageLevel);
160*08b48e0bSAndroid Build Coastguard Worker   Options.CoverageType = std::max(Options.CoverageType, CLOpts.CoverageType);
161*08b48e0bSAndroid Build Coastguard Worker   Options.IndirectCalls |= CLOpts.IndirectCalls;
162*08b48e0bSAndroid Build Coastguard Worker   Options.TracePC |= ClTracePC;
163*08b48e0bSAndroid Build Coastguard Worker   Options.TracePCGuard |= ClTracePCGuard;
164*08b48e0bSAndroid Build Coastguard Worker   Options.Inline8bitCounters |= ClInline8bitCounters;
165*08b48e0bSAndroid Build Coastguard Worker   Options.InlineBoolFlag |= ClInlineBoolFlag;
166*08b48e0bSAndroid Build Coastguard Worker   Options.PCTable |= ClCreatePCTable;
167*08b48e0bSAndroid Build Coastguard Worker   Options.NoPrune |= !ClPruneBlocks;
168*08b48e0bSAndroid Build Coastguard Worker   if (!Options.TracePCGuard && !Options.TracePC &&
169*08b48e0bSAndroid Build Coastguard Worker       !Options.Inline8bitCounters && !Options.InlineBoolFlag)
170*08b48e0bSAndroid Build Coastguard Worker     Options.TracePCGuard = true;  // TracePCGuard is default.
171*08b48e0bSAndroid Build Coastguard Worker   return Options;
172*08b48e0bSAndroid Build Coastguard Worker 
173*08b48e0bSAndroid Build Coastguard Worker }
174*08b48e0bSAndroid Build Coastguard Worker 
175*08b48e0bSAndroid Build Coastguard Worker using DomTreeCallback = function_ref<const DominatorTree *(Function &F)>;
176*08b48e0bSAndroid Build Coastguard Worker using PostDomTreeCallback =
177*08b48e0bSAndroid Build Coastguard Worker     function_ref<const PostDominatorTree *(Function &F)>;
178*08b48e0bSAndroid Build Coastguard Worker 
179*08b48e0bSAndroid Build Coastguard Worker class ModuleSanitizerCoverageLTO
180*08b48e0bSAndroid Build Coastguard Worker     : public PassInfoMixin<ModuleSanitizerCoverageLTO> {
181*08b48e0bSAndroid Build Coastguard Worker 
182*08b48e0bSAndroid Build Coastguard Worker  public:
ModuleSanitizerCoverageLTO(const SanitizerCoverageOptions & Options=SanitizerCoverageOptions ())183*08b48e0bSAndroid Build Coastguard Worker   ModuleSanitizerCoverageLTO(
184*08b48e0bSAndroid Build Coastguard Worker       const SanitizerCoverageOptions &Options = SanitizerCoverageOptions())
185*08b48e0bSAndroid Build Coastguard Worker       : Options(OverrideFromCL(Options)) {
186*08b48e0bSAndroid Build Coastguard Worker 
187*08b48e0bSAndroid Build Coastguard Worker   }
188*08b48e0bSAndroid Build Coastguard Worker 
189*08b48e0bSAndroid Build Coastguard Worker   bool instrumentModule(Module &M, DomTreeCallback DTCallback,
190*08b48e0bSAndroid Build Coastguard Worker                         PostDomTreeCallback PDTCallback);
191*08b48e0bSAndroid Build Coastguard Worker 
192*08b48e0bSAndroid Build Coastguard Worker   PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
193*08b48e0bSAndroid Build Coastguard Worker 
194*08b48e0bSAndroid Build Coastguard Worker  private:
195*08b48e0bSAndroid Build Coastguard Worker   void            instrumentFunction(Function &F, DomTreeCallback DTCallback,
196*08b48e0bSAndroid Build Coastguard Worker                                      PostDomTreeCallback PDTCallback);
197*08b48e0bSAndroid Build Coastguard Worker   void            InjectCoverageForIndirectCalls(Function               &F,
198*08b48e0bSAndroid Build Coastguard Worker                                                  ArrayRef<Instruction *> IndirCalls);
199*08b48e0bSAndroid Build Coastguard Worker   bool            InjectCoverage(Function &F, ArrayRef<BasicBlock *> AllBlocks,
200*08b48e0bSAndroid Build Coastguard Worker                                  bool IsLeafFunc = true);
201*08b48e0bSAndroid Build Coastguard Worker   GlobalVariable *CreateFunctionLocalArrayInSection(size_t    NumElements,
202*08b48e0bSAndroid Build Coastguard Worker                                                     Function &F, Type *Ty,
203*08b48e0bSAndroid Build Coastguard Worker                                                     const char *Section);
204*08b48e0bSAndroid Build Coastguard Worker   GlobalVariable *CreatePCArray(Function &F, ArrayRef<BasicBlock *> AllBlocks);
205*08b48e0bSAndroid Build Coastguard Worker   void CreateFunctionLocalArrays(Function &F, ArrayRef<BasicBlock *> AllBlocks);
206*08b48e0bSAndroid Build Coastguard Worker   void InjectCoverageAtBlock(Function &F, BasicBlock &BB, size_t Idx,
207*08b48e0bSAndroid Build Coastguard Worker                              bool IsLeafFunc = true);
208*08b48e0bSAndroid Build Coastguard Worker   //  std::pair<Value *, Value *> CreateSecStartEnd(Module &M, const char
209*08b48e0bSAndroid Build Coastguard Worker   //  *Section,
210*08b48e0bSAndroid Build Coastguard Worker   //                                                Type *Ty);
211*08b48e0bSAndroid Build Coastguard Worker 
SetNoSanitizeMetadata(Instruction * I)212*08b48e0bSAndroid Build Coastguard Worker   void SetNoSanitizeMetadata(Instruction *I) {
213*08b48e0bSAndroid Build Coastguard Worker 
214*08b48e0bSAndroid Build Coastguard Worker     I->setMetadata(I->getModule()->getMDKindID("nosanitize"),
215*08b48e0bSAndroid Build Coastguard Worker                    MDNode::get(*C, None));
216*08b48e0bSAndroid Build Coastguard Worker 
217*08b48e0bSAndroid Build Coastguard Worker   }
218*08b48e0bSAndroid Build Coastguard Worker 
219*08b48e0bSAndroid Build Coastguard Worker   std::string getSectionName(const std::string &Section) const;
220*08b48e0bSAndroid Build Coastguard Worker   //  std::string    getSectionStart(const std::string &Section) const;
221*08b48e0bSAndroid Build Coastguard Worker   //  std::string    getSectionEnd(const std::string &Section) const;
222*08b48e0bSAndroid Build Coastguard Worker   FunctionCallee SanCovTracePCIndir;
223*08b48e0bSAndroid Build Coastguard Worker   FunctionCallee SanCovTracePC /*, SanCovTracePCGuard*/;
224*08b48e0bSAndroid Build Coastguard Worker   Type *IntptrTy, *IntptrPtrTy, *Int64Ty, *Int64PtrTy, *Int32Ty, *Int32PtrTy,
225*08b48e0bSAndroid Build Coastguard Worker       *Int16Ty, *Int8Ty, *Int8PtrTy, *Int1Ty, *Int1PtrTy;
226*08b48e0bSAndroid Build Coastguard Worker   Module           *CurModule;
227*08b48e0bSAndroid Build Coastguard Worker   std::string       CurModuleUniqueId;
228*08b48e0bSAndroid Build Coastguard Worker   Triple            TargetTriple;
229*08b48e0bSAndroid Build Coastguard Worker   LLVMContext      *C;
230*08b48e0bSAndroid Build Coastguard Worker   const DataLayout *DL;
231*08b48e0bSAndroid Build Coastguard Worker 
232*08b48e0bSAndroid Build Coastguard Worker   GlobalVariable *FunctionGuardArray;        // for trace-pc-guard.
233*08b48e0bSAndroid Build Coastguard Worker   GlobalVariable *Function8bitCounterArray;  // for inline-8bit-counters.
234*08b48e0bSAndroid Build Coastguard Worker   GlobalVariable *FunctionBoolArray;         // for inline-bool-flag.
235*08b48e0bSAndroid Build Coastguard Worker   GlobalVariable *FunctionPCsArray;          // for pc-table.
236*08b48e0bSAndroid Build Coastguard Worker   SmallVector<GlobalValue *, 20> GlobalsToAppendToUsed;
237*08b48e0bSAndroid Build Coastguard Worker   SmallVector<GlobalValue *, 20> GlobalsToAppendToCompilerUsed;
238*08b48e0bSAndroid Build Coastguard Worker 
239*08b48e0bSAndroid Build Coastguard Worker   SanitizerCoverageOptions Options;
240*08b48e0bSAndroid Build Coastguard Worker 
241*08b48e0bSAndroid Build Coastguard Worker   // AFL++ START
242*08b48e0bSAndroid Build Coastguard Worker   // const SpecialCaseList *          Allowlist;
243*08b48e0bSAndroid Build Coastguard Worker   // const SpecialCaseList *          Blocklist;
244*08b48e0bSAndroid Build Coastguard Worker   uint32_t                         autodictionary = 1;
245*08b48e0bSAndroid Build Coastguard Worker   uint32_t                         autodictionary_no_main = 0;
246*08b48e0bSAndroid Build Coastguard Worker   uint32_t                         inst = 0;
247*08b48e0bSAndroid Build Coastguard Worker   uint32_t                         afl_global_id = 0;
248*08b48e0bSAndroid Build Coastguard Worker   uint32_t                         unhandled = 0;
249*08b48e0bSAndroid Build Coastguard Worker   uint32_t                         select_cnt = 0;
250*08b48e0bSAndroid Build Coastguard Worker   uint64_t                         map_addr = 0;
251*08b48e0bSAndroid Build Coastguard Worker   const char                      *skip_nozero = NULL;
252*08b48e0bSAndroid Build Coastguard Worker   const char                      *use_threadsafe_counters = nullptr;
253*08b48e0bSAndroid Build Coastguard Worker   std::vector<BasicBlock *>        BlockList;
254*08b48e0bSAndroid Build Coastguard Worker   DenseMap<Value *, std::string *> valueMap;
255*08b48e0bSAndroid Build Coastguard Worker   std::vector<std::string>         dictionary;
256*08b48e0bSAndroid Build Coastguard Worker   IntegerType                     *Int8Tyi = NULL;
257*08b48e0bSAndroid Build Coastguard Worker   IntegerType                     *Int32Tyi = NULL;
258*08b48e0bSAndroid Build Coastguard Worker   IntegerType                     *Int64Tyi = NULL;
259*08b48e0bSAndroid Build Coastguard Worker   ConstantInt                     *Zero = NULL;
260*08b48e0bSAndroid Build Coastguard Worker   ConstantInt                     *One = NULL;
261*08b48e0bSAndroid Build Coastguard Worker   LLVMContext                     *Ct = NULL;
262*08b48e0bSAndroid Build Coastguard Worker   Module                          *Mo = NULL;
263*08b48e0bSAndroid Build Coastguard Worker   GlobalVariable                  *AFLMapPtr = NULL;
264*08b48e0bSAndroid Build Coastguard Worker   Value                           *MapPtrFixed = NULL;
265*08b48e0bSAndroid Build Coastguard Worker   std::ofstream                    dFile;
266*08b48e0bSAndroid Build Coastguard Worker   size_t                           found = 0;
267*08b48e0bSAndroid Build Coastguard Worker   // AFL++ END
268*08b48e0bSAndroid Build Coastguard Worker 
269*08b48e0bSAndroid Build Coastguard Worker };
270*08b48e0bSAndroid Build Coastguard Worker 
271*08b48e0bSAndroid Build Coastguard Worker class ModuleSanitizerCoverageLTOLegacyPass : public ModulePass {
272*08b48e0bSAndroid Build Coastguard Worker 
273*08b48e0bSAndroid Build Coastguard Worker  public:
274*08b48e0bSAndroid Build Coastguard Worker   static char ID;
getPassName() const275*08b48e0bSAndroid Build Coastguard Worker   StringRef   getPassName() const override {
276*08b48e0bSAndroid Build Coastguard Worker 
277*08b48e0bSAndroid Build Coastguard Worker     return "sancov-lto";
278*08b48e0bSAndroid Build Coastguard Worker 
279*08b48e0bSAndroid Build Coastguard Worker   }
280*08b48e0bSAndroid Build Coastguard Worker 
getAnalysisUsage(AnalysisUsage & AU) const281*08b48e0bSAndroid Build Coastguard Worker   void getAnalysisUsage(AnalysisUsage &AU) const override {
282*08b48e0bSAndroid Build Coastguard Worker 
283*08b48e0bSAndroid Build Coastguard Worker     AU.addRequired<DominatorTreeWrapperPass>();
284*08b48e0bSAndroid Build Coastguard Worker     AU.addRequired<PostDominatorTreeWrapperPass>();
285*08b48e0bSAndroid Build Coastguard Worker 
286*08b48e0bSAndroid Build Coastguard Worker   }
287*08b48e0bSAndroid Build Coastguard Worker 
ModuleSanitizerCoverageLTOLegacyPass(const SanitizerCoverageOptions & Options=SanitizerCoverageOptions ())288*08b48e0bSAndroid Build Coastguard Worker   ModuleSanitizerCoverageLTOLegacyPass(
289*08b48e0bSAndroid Build Coastguard Worker       const SanitizerCoverageOptions &Options = SanitizerCoverageOptions())
290*08b48e0bSAndroid Build Coastguard Worker       : ModulePass(ID), Options(Options) {
291*08b48e0bSAndroid Build Coastguard Worker 
292*08b48e0bSAndroid Build Coastguard Worker     initializeModuleSanitizerCoverageLTOLegacyPassPass(
293*08b48e0bSAndroid Build Coastguard Worker         *PassRegistry::getPassRegistry());
294*08b48e0bSAndroid Build Coastguard Worker 
295*08b48e0bSAndroid Build Coastguard Worker   }
296*08b48e0bSAndroid Build Coastguard Worker 
runOnModule(Module & M)297*08b48e0bSAndroid Build Coastguard Worker   bool runOnModule(Module &M) override {
298*08b48e0bSAndroid Build Coastguard Worker 
299*08b48e0bSAndroid Build Coastguard Worker     ModuleSanitizerCoverageLTO ModuleSancov(Options);
300*08b48e0bSAndroid Build Coastguard Worker     auto DTCallback = [this](Function &F) -> const DominatorTree * {
301*08b48e0bSAndroid Build Coastguard Worker 
302*08b48e0bSAndroid Build Coastguard Worker       return &this->getAnalysis<DominatorTreeWrapperPass>(F).getDomTree();
303*08b48e0bSAndroid Build Coastguard Worker 
304*08b48e0bSAndroid Build Coastguard Worker     };
305*08b48e0bSAndroid Build Coastguard Worker 
306*08b48e0bSAndroid Build Coastguard Worker     auto PDTCallback = [this](Function &F) -> const PostDominatorTree * {
307*08b48e0bSAndroid Build Coastguard Worker 
308*08b48e0bSAndroid Build Coastguard Worker       return &this->getAnalysis<PostDominatorTreeWrapperPass>(F)
309*08b48e0bSAndroid Build Coastguard Worker                   .getPostDomTree();
310*08b48e0bSAndroid Build Coastguard Worker 
311*08b48e0bSAndroid Build Coastguard Worker     };
312*08b48e0bSAndroid Build Coastguard Worker 
313*08b48e0bSAndroid Build Coastguard Worker     return ModuleSancov.instrumentModule(M, DTCallback, PDTCallback);
314*08b48e0bSAndroid Build Coastguard Worker 
315*08b48e0bSAndroid Build Coastguard Worker   }
316*08b48e0bSAndroid Build Coastguard Worker 
317*08b48e0bSAndroid Build Coastguard Worker  private:
318*08b48e0bSAndroid Build Coastguard Worker   SanitizerCoverageOptions Options;
319*08b48e0bSAndroid Build Coastguard Worker 
320*08b48e0bSAndroid Build Coastguard Worker };
321*08b48e0bSAndroid Build Coastguard Worker 
322*08b48e0bSAndroid Build Coastguard Worker }  // namespace
323*08b48e0bSAndroid Build Coastguard Worker 
324*08b48e0bSAndroid Build Coastguard Worker extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK
llvmGetPassPluginInfo()325*08b48e0bSAndroid Build Coastguard Worker llvmGetPassPluginInfo() {
326*08b48e0bSAndroid Build Coastguard Worker 
327*08b48e0bSAndroid Build Coastguard Worker   return {LLVM_PLUGIN_API_VERSION, "SanitizerCoverageLTO", "v0.1",
328*08b48e0bSAndroid Build Coastguard Worker           /* lambda to insert our pass into the pass pipeline. */
329*08b48e0bSAndroid Build Coastguard Worker           [](PassBuilder &PB) {
330*08b48e0bSAndroid Build Coastguard Worker 
331*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR <= 13
332*08b48e0bSAndroid Build Coastguard Worker             using OptimizationLevel = typename PassBuilder::OptimizationLevel;
333*08b48e0bSAndroid Build Coastguard Worker #endif
334*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 15
335*08b48e0bSAndroid Build Coastguard Worker             PB.registerFullLinkTimeOptimizationLastEPCallback(
336*08b48e0bSAndroid Build Coastguard Worker #else
337*08b48e0bSAndroid Build Coastguard Worker             PB.registerOptimizerLastEPCallback(
338*08b48e0bSAndroid Build Coastguard Worker #endif
339*08b48e0bSAndroid Build Coastguard Worker                 [](ModulePassManager &MPM, OptimizationLevel OL) {
340*08b48e0bSAndroid Build Coastguard Worker 
341*08b48e0bSAndroid Build Coastguard Worker                   MPM.addPass(ModuleSanitizerCoverageLTO());
342*08b48e0bSAndroid Build Coastguard Worker 
343*08b48e0bSAndroid Build Coastguard Worker                 });
344*08b48e0bSAndroid Build Coastguard Worker 
345*08b48e0bSAndroid Build Coastguard Worker           }};
346*08b48e0bSAndroid Build Coastguard Worker 
347*08b48e0bSAndroid Build Coastguard Worker }
348*08b48e0bSAndroid Build Coastguard Worker 
run(Module & M,ModuleAnalysisManager & MAM)349*08b48e0bSAndroid Build Coastguard Worker PreservedAnalyses ModuleSanitizerCoverageLTO::run(Module                &M,
350*08b48e0bSAndroid Build Coastguard Worker                                                   ModuleAnalysisManager &MAM) {
351*08b48e0bSAndroid Build Coastguard Worker 
352*08b48e0bSAndroid Build Coastguard Worker   ModuleSanitizerCoverageLTO ModuleSancov(Options);
353*08b48e0bSAndroid Build Coastguard Worker   auto &FAM = MAM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
354*08b48e0bSAndroid Build Coastguard Worker   auto  DTCallback = [&FAM](Function &F) -> const DominatorTree  *{
355*08b48e0bSAndroid Build Coastguard Worker 
356*08b48e0bSAndroid Build Coastguard Worker     return &FAM.getResult<DominatorTreeAnalysis>(F);
357*08b48e0bSAndroid Build Coastguard Worker 
358*08b48e0bSAndroid Build Coastguard Worker   };
359*08b48e0bSAndroid Build Coastguard Worker 
360*08b48e0bSAndroid Build Coastguard Worker   auto PDTCallback = [&FAM](Function &F) -> const PostDominatorTree * {
361*08b48e0bSAndroid Build Coastguard Worker 
362*08b48e0bSAndroid Build Coastguard Worker     return &FAM.getResult<PostDominatorTreeAnalysis>(F);
363*08b48e0bSAndroid Build Coastguard Worker 
364*08b48e0bSAndroid Build Coastguard Worker   };
365*08b48e0bSAndroid Build Coastguard Worker 
366*08b48e0bSAndroid Build Coastguard Worker   if (ModuleSancov.instrumentModule(M, DTCallback, PDTCallback))
367*08b48e0bSAndroid Build Coastguard Worker     return PreservedAnalyses::none();
368*08b48e0bSAndroid Build Coastguard Worker 
369*08b48e0bSAndroid Build Coastguard Worker   return PreservedAnalyses::all();
370*08b48e0bSAndroid Build Coastguard Worker 
371*08b48e0bSAndroid Build Coastguard Worker }
372*08b48e0bSAndroid Build Coastguard Worker 
instrumentModule(Module & M,DomTreeCallback DTCallback,PostDomTreeCallback PDTCallback)373*08b48e0bSAndroid Build Coastguard Worker bool ModuleSanitizerCoverageLTO::instrumentModule(
374*08b48e0bSAndroid Build Coastguard Worker     Module &M, DomTreeCallback DTCallback, PostDomTreeCallback PDTCallback) {
375*08b48e0bSAndroid Build Coastguard Worker 
376*08b48e0bSAndroid Build Coastguard Worker   if (Options.CoverageType == SanitizerCoverageOptions::SCK_None) return false;
377*08b48e0bSAndroid Build Coastguard Worker   /*
378*08b48e0bSAndroid Build Coastguard Worker     if (Allowlist &&
379*08b48e0bSAndroid Build Coastguard Worker         !Allowlist->inSection("coverage", "src", MNAME))
380*08b48e0bSAndroid Build Coastguard Worker       return false;
381*08b48e0bSAndroid Build Coastguard Worker     if (Blocklist &&
382*08b48e0bSAndroid Build Coastguard Worker         Blocklist->inSection("coverage", "src", MNAME))
383*08b48e0bSAndroid Build Coastguard Worker       return false;
384*08b48e0bSAndroid Build Coastguard Worker   */
385*08b48e0bSAndroid Build Coastguard Worker   BlockList.clear();
386*08b48e0bSAndroid Build Coastguard Worker   valueMap.clear();
387*08b48e0bSAndroid Build Coastguard Worker   dictionary.clear();
388*08b48e0bSAndroid Build Coastguard Worker   C = &(M.getContext());
389*08b48e0bSAndroid Build Coastguard Worker   DL = &M.getDataLayout();
390*08b48e0bSAndroid Build Coastguard Worker   CurModule = &M;
391*08b48e0bSAndroid Build Coastguard Worker   CurModuleUniqueId = getUniqueModuleId(CurModule);
392*08b48e0bSAndroid Build Coastguard Worker   TargetTriple = Triple(M.getTargetTriple());
393*08b48e0bSAndroid Build Coastguard Worker   FunctionGuardArray = nullptr;
394*08b48e0bSAndroid Build Coastguard Worker   Function8bitCounterArray = nullptr;
395*08b48e0bSAndroid Build Coastguard Worker   FunctionBoolArray = nullptr;
396*08b48e0bSAndroid Build Coastguard Worker   FunctionPCsArray = nullptr;
397*08b48e0bSAndroid Build Coastguard Worker   IntptrTy = Type::getIntNTy(*C, DL->getPointerSizeInBits());
398*08b48e0bSAndroid Build Coastguard Worker   IntptrPtrTy = PointerType::getUnqual(IntptrTy);
399*08b48e0bSAndroid Build Coastguard Worker   Type       *VoidTy = Type::getVoidTy(*C);
400*08b48e0bSAndroid Build Coastguard Worker   IRBuilder<> IRB(*C);
401*08b48e0bSAndroid Build Coastguard Worker   Int64PtrTy = PointerType::getUnqual(IRB.getInt64Ty());
402*08b48e0bSAndroid Build Coastguard Worker   Int32PtrTy = PointerType::getUnqual(IRB.getInt32Ty());
403*08b48e0bSAndroid Build Coastguard Worker   Int8PtrTy = PointerType::getUnqual(IRB.getInt8Ty());
404*08b48e0bSAndroid Build Coastguard Worker   Int1PtrTy = PointerType::getUnqual(IRB.getInt1Ty());
405*08b48e0bSAndroid Build Coastguard Worker   Int64Ty = IRB.getInt64Ty();
406*08b48e0bSAndroid Build Coastguard Worker   Int32Ty = IRB.getInt32Ty();
407*08b48e0bSAndroid Build Coastguard Worker   Int16Ty = IRB.getInt16Ty();
408*08b48e0bSAndroid Build Coastguard Worker   Int8Ty = IRB.getInt8Ty();
409*08b48e0bSAndroid Build Coastguard Worker   Int1Ty = IRB.getInt1Ty();
410*08b48e0bSAndroid Build Coastguard Worker 
411*08b48e0bSAndroid Build Coastguard Worker   /* AFL++ START */
412*08b48e0bSAndroid Build Coastguard Worker   char        *ptr;
413*08b48e0bSAndroid Build Coastguard Worker   LLVMContext &Ctx = M.getContext();
414*08b48e0bSAndroid Build Coastguard Worker   Ct = &Ctx;
415*08b48e0bSAndroid Build Coastguard Worker   Int8Tyi = IntegerType::getInt8Ty(Ctx);
416*08b48e0bSAndroid Build Coastguard Worker   Int32Tyi = IntegerType::getInt32Ty(Ctx);
417*08b48e0bSAndroid Build Coastguard Worker   Int64Tyi = IntegerType::getInt64Ty(Ctx);
418*08b48e0bSAndroid Build Coastguard Worker 
419*08b48e0bSAndroid Build Coastguard Worker   /* Show a banner */
420*08b48e0bSAndroid Build Coastguard Worker   setvbuf(stdout, NULL, _IONBF, 0);
421*08b48e0bSAndroid Build Coastguard Worker   if (getenv("AFL_DEBUG")) { debug = 1; }
422*08b48e0bSAndroid Build Coastguard Worker   if (getenv("AFL_LLVM_DICT2FILE_NO_MAIN")) { autodictionary_no_main = 1; }
423*08b48e0bSAndroid Build Coastguard Worker 
424*08b48e0bSAndroid Build Coastguard Worker   if ((isatty(2) && !getenv("AFL_QUIET")) || debug) {
425*08b48e0bSAndroid Build Coastguard Worker 
426*08b48e0bSAndroid Build Coastguard Worker     SAYF(cCYA "afl-llvm-lto" VERSION cRST
427*08b48e0bSAndroid Build Coastguard Worker               " by Marc \"vanHauser\" Heuse <[email protected]>\n");
428*08b48e0bSAndroid Build Coastguard Worker 
429*08b48e0bSAndroid Build Coastguard Worker   } else
430*08b48e0bSAndroid Build Coastguard Worker 
431*08b48e0bSAndroid Build Coastguard Worker     be_quiet = 1;
432*08b48e0bSAndroid Build Coastguard Worker 
433*08b48e0bSAndroid Build Coastguard Worker   skip_nozero = getenv("AFL_LLVM_SKIP_NEVERZERO");
434*08b48e0bSAndroid Build Coastguard Worker   use_threadsafe_counters = getenv("AFL_LLVM_THREADSAFE_INST");
435*08b48e0bSAndroid Build Coastguard Worker 
436*08b48e0bSAndroid Build Coastguard Worker   if ((ptr = getenv("AFL_LLVM_LTO_STARTID")) != NULL)
437*08b48e0bSAndroid Build Coastguard Worker     if ((afl_global_id = atoi(ptr)) < 0)
438*08b48e0bSAndroid Build Coastguard Worker       FATAL("AFL_LLVM_LTO_STARTID value of \"%s\" is negative\n", ptr);
439*08b48e0bSAndroid Build Coastguard Worker 
440*08b48e0bSAndroid Build Coastguard Worker   if (afl_global_id < 4) { afl_global_id = 4; }
441*08b48e0bSAndroid Build Coastguard Worker 
442*08b48e0bSAndroid Build Coastguard Worker   if ((ptr = getenv("AFL_LLVM_DOCUMENT_IDS")) != NULL) {
443*08b48e0bSAndroid Build Coastguard Worker 
444*08b48e0bSAndroid Build Coastguard Worker     dFile.open(ptr, std::ofstream::out | std::ofstream::app);
445*08b48e0bSAndroid Build Coastguard Worker     if (dFile.is_open()) WARNF("Cannot access document file %s", ptr);
446*08b48e0bSAndroid Build Coastguard Worker 
447*08b48e0bSAndroid Build Coastguard Worker   }
448*08b48e0bSAndroid Build Coastguard Worker 
449*08b48e0bSAndroid Build Coastguard Worker   // we make this the default as the fixed map has problems with
450*08b48e0bSAndroid Build Coastguard Worker   // defered forkserver, early constructors, ifuncs and maybe more
451*08b48e0bSAndroid Build Coastguard Worker   /*if (getenv("AFL_LLVM_MAP_DYNAMIC"))*/
452*08b48e0bSAndroid Build Coastguard Worker   map_addr = 0;
453*08b48e0bSAndroid Build Coastguard Worker 
454*08b48e0bSAndroid Build Coastguard Worker   if ((ptr = getenv("AFL_LLVM_MAP_ADDR"))) {
455*08b48e0bSAndroid Build Coastguard Worker 
456*08b48e0bSAndroid Build Coastguard Worker     uint64_t val;
457*08b48e0bSAndroid Build Coastguard Worker     if (!*ptr || !strcmp(ptr, "0") || !strcmp(ptr, "0x0")) {
458*08b48e0bSAndroid Build Coastguard Worker 
459*08b48e0bSAndroid Build Coastguard Worker       map_addr = 0;
460*08b48e0bSAndroid Build Coastguard Worker 
461*08b48e0bSAndroid Build Coastguard Worker     } else if (getenv("AFL_LLVM_MAP_DYNAMIC")) {
462*08b48e0bSAndroid Build Coastguard Worker 
463*08b48e0bSAndroid Build Coastguard Worker       FATAL(
464*08b48e0bSAndroid Build Coastguard Worker           "AFL_LLVM_MAP_ADDR and AFL_LLVM_MAP_DYNAMIC cannot be used together");
465*08b48e0bSAndroid Build Coastguard Worker 
466*08b48e0bSAndroid Build Coastguard Worker     } else if (strncmp(ptr, "0x", 2) != 0) {
467*08b48e0bSAndroid Build Coastguard Worker 
468*08b48e0bSAndroid Build Coastguard Worker       map_addr = 0x10000;  // the default
469*08b48e0bSAndroid Build Coastguard Worker 
470*08b48e0bSAndroid Build Coastguard Worker     } else {
471*08b48e0bSAndroid Build Coastguard Worker 
472*08b48e0bSAndroid Build Coastguard Worker       val = strtoull(ptr, NULL, 16);
473*08b48e0bSAndroid Build Coastguard Worker       if (val < 0x100 || val > 0xffffffff00000000) {
474*08b48e0bSAndroid Build Coastguard Worker 
475*08b48e0bSAndroid Build Coastguard Worker         FATAL(
476*08b48e0bSAndroid Build Coastguard Worker             "AFL_LLVM_MAP_ADDR must be a value between 0x100 and "
477*08b48e0bSAndroid Build Coastguard Worker             "0xffffffff00000000");
478*08b48e0bSAndroid Build Coastguard Worker 
479*08b48e0bSAndroid Build Coastguard Worker       }
480*08b48e0bSAndroid Build Coastguard Worker 
481*08b48e0bSAndroid Build Coastguard Worker       map_addr = val;
482*08b48e0bSAndroid Build Coastguard Worker 
483*08b48e0bSAndroid Build Coastguard Worker     }
484*08b48e0bSAndroid Build Coastguard Worker 
485*08b48e0bSAndroid Build Coastguard Worker   }
486*08b48e0bSAndroid Build Coastguard Worker 
487*08b48e0bSAndroid Build Coastguard Worker   /* Get/set the globals for the SHM region. */
488*08b48e0bSAndroid Build Coastguard Worker 
489*08b48e0bSAndroid Build Coastguard Worker   if (!map_addr) {
490*08b48e0bSAndroid Build Coastguard Worker 
491*08b48e0bSAndroid Build Coastguard Worker     AFLMapPtr =
492*08b48e0bSAndroid Build Coastguard Worker         new GlobalVariable(M, PointerType::get(Int8Tyi, 0), false,
493*08b48e0bSAndroid Build Coastguard Worker                            GlobalValue::ExternalLinkage, 0, "__afl_area_ptr");
494*08b48e0bSAndroid Build Coastguard Worker 
495*08b48e0bSAndroid Build Coastguard Worker   } else {
496*08b48e0bSAndroid Build Coastguard Worker 
497*08b48e0bSAndroid Build Coastguard Worker     ConstantInt *MapAddr = ConstantInt::get(Int64Tyi, map_addr);
498*08b48e0bSAndroid Build Coastguard Worker     MapPtrFixed =
499*08b48e0bSAndroid Build Coastguard Worker         ConstantExpr::getIntToPtr(MapAddr, PointerType::getUnqual(Int8Tyi));
500*08b48e0bSAndroid Build Coastguard Worker 
501*08b48e0bSAndroid Build Coastguard Worker   }
502*08b48e0bSAndroid Build Coastguard Worker 
503*08b48e0bSAndroid Build Coastguard Worker   Zero = ConstantInt::get(Int8Tyi, 0);
504*08b48e0bSAndroid Build Coastguard Worker   One = ConstantInt::get(Int8Tyi, 1);
505*08b48e0bSAndroid Build Coastguard Worker 
506*08b48e0bSAndroid Build Coastguard Worker   initInstrumentList();
507*08b48e0bSAndroid Build Coastguard Worker   scanForDangerousFunctions(&M);
508*08b48e0bSAndroid Build Coastguard Worker   Mo = &M;
509*08b48e0bSAndroid Build Coastguard Worker 
510*08b48e0bSAndroid Build Coastguard Worker   if (autodictionary) {
511*08b48e0bSAndroid Build Coastguard Worker 
512*08b48e0bSAndroid Build Coastguard Worker     for (auto &F : M) {
513*08b48e0bSAndroid Build Coastguard Worker 
514*08b48e0bSAndroid Build Coastguard Worker       if (!isInInstrumentList(&F, MNAME) || !F.size()) { continue; }
515*08b48e0bSAndroid Build Coastguard Worker 
516*08b48e0bSAndroid Build Coastguard Worker       if (autodictionary_no_main &&
517*08b48e0bSAndroid Build Coastguard Worker           (!F.getName().compare("main") || !F.getName().compare("_main"))) {
518*08b48e0bSAndroid Build Coastguard Worker 
519*08b48e0bSAndroid Build Coastguard Worker         continue;
520*08b48e0bSAndroid Build Coastguard Worker 
521*08b48e0bSAndroid Build Coastguard Worker       }
522*08b48e0bSAndroid Build Coastguard Worker 
523*08b48e0bSAndroid Build Coastguard Worker       for (auto &BB : F) {
524*08b48e0bSAndroid Build Coastguard Worker 
525*08b48e0bSAndroid Build Coastguard Worker         for (auto &IN : BB) {
526*08b48e0bSAndroid Build Coastguard Worker 
527*08b48e0bSAndroid Build Coastguard Worker           CallInst *callInst = nullptr;
528*08b48e0bSAndroid Build Coastguard Worker           CmpInst  *cmpInst = nullptr;
529*08b48e0bSAndroid Build Coastguard Worker 
530*08b48e0bSAndroid Build Coastguard Worker           if ((cmpInst = dyn_cast<CmpInst>(&IN))) {
531*08b48e0bSAndroid Build Coastguard Worker 
532*08b48e0bSAndroid Build Coastguard Worker             Value       *op = cmpInst->getOperand(1);
533*08b48e0bSAndroid Build Coastguard Worker             ConstantInt *ilen = dyn_cast<ConstantInt>(op);
534*08b48e0bSAndroid Build Coastguard Worker 
535*08b48e0bSAndroid Build Coastguard Worker             if (ilen && ilen->uge(0xffffffffffffffff) == false) {
536*08b48e0bSAndroid Build Coastguard Worker 
537*08b48e0bSAndroid Build Coastguard Worker               u64 val2 = 0, val = ilen->getZExtValue();
538*08b48e0bSAndroid Build Coastguard Worker               u32 len = 0;
539*08b48e0bSAndroid Build Coastguard Worker               if (val > 0x10000 && val < 0xffffffff) len = 4;
540*08b48e0bSAndroid Build Coastguard Worker               if (val > 0x100000001 && val < 0xffffffffffffffff) len = 8;
541*08b48e0bSAndroid Build Coastguard Worker 
542*08b48e0bSAndroid Build Coastguard Worker               if (len) {
543*08b48e0bSAndroid Build Coastguard Worker 
544*08b48e0bSAndroid Build Coastguard Worker                 auto c = cmpInst->getPredicate();
545*08b48e0bSAndroid Build Coastguard Worker 
546*08b48e0bSAndroid Build Coastguard Worker                 switch (c) {
547*08b48e0bSAndroid Build Coastguard Worker 
548*08b48e0bSAndroid Build Coastguard Worker                   case CmpInst::FCMP_OGT:  // fall through
549*08b48e0bSAndroid Build Coastguard Worker                   case CmpInst::FCMP_OLE:  // fall through
550*08b48e0bSAndroid Build Coastguard Worker                   case CmpInst::ICMP_SLE:  // fall through
551*08b48e0bSAndroid Build Coastguard Worker                   case CmpInst::ICMP_SGT:
552*08b48e0bSAndroid Build Coastguard Worker 
553*08b48e0bSAndroid Build Coastguard Worker                     // signed comparison and it is a negative constant
554*08b48e0bSAndroid Build Coastguard Worker                     if ((len == 4 && (val & 80000000)) ||
555*08b48e0bSAndroid Build Coastguard Worker                         (len == 8 && (val & 8000000000000000))) {
556*08b48e0bSAndroid Build Coastguard Worker 
557*08b48e0bSAndroid Build Coastguard Worker                       if ((val & 0xffff) != 1) val2 = val - 1;
558*08b48e0bSAndroid Build Coastguard Worker                       break;
559*08b48e0bSAndroid Build Coastguard Worker 
560*08b48e0bSAndroid Build Coastguard Worker                     }
561*08b48e0bSAndroid Build Coastguard Worker 
562*08b48e0bSAndroid Build Coastguard Worker                     // fall through
563*08b48e0bSAndroid Build Coastguard Worker 
564*08b48e0bSAndroid Build Coastguard Worker                   case CmpInst::FCMP_UGT:  // fall through
565*08b48e0bSAndroid Build Coastguard Worker                   case CmpInst::FCMP_ULE:  // fall through
566*08b48e0bSAndroid Build Coastguard Worker                   case CmpInst::ICMP_UGT:  // fall through
567*08b48e0bSAndroid Build Coastguard Worker                   case CmpInst::ICMP_ULE:
568*08b48e0bSAndroid Build Coastguard Worker                     if ((val & 0xffff) != 0xfffe) val2 = val + 1;
569*08b48e0bSAndroid Build Coastguard Worker                     break;
570*08b48e0bSAndroid Build Coastguard Worker 
571*08b48e0bSAndroid Build Coastguard Worker                   case CmpInst::FCMP_OLT:  // fall through
572*08b48e0bSAndroid Build Coastguard Worker                   case CmpInst::FCMP_OGE:  // fall through
573*08b48e0bSAndroid Build Coastguard Worker                   case CmpInst::ICMP_SLT:  // fall through
574*08b48e0bSAndroid Build Coastguard Worker                   case CmpInst::ICMP_SGE:
575*08b48e0bSAndroid Build Coastguard Worker 
576*08b48e0bSAndroid Build Coastguard Worker                     // signed comparison and it is a negative constant
577*08b48e0bSAndroid Build Coastguard Worker                     if ((len == 4 && (val & 80000000)) ||
578*08b48e0bSAndroid Build Coastguard Worker                         (len == 8 && (val & 8000000000000000))) {
579*08b48e0bSAndroid Build Coastguard Worker 
580*08b48e0bSAndroid Build Coastguard Worker                       if ((val & 0xffff) != 1) val2 = val - 1;
581*08b48e0bSAndroid Build Coastguard Worker                       break;
582*08b48e0bSAndroid Build Coastguard Worker 
583*08b48e0bSAndroid Build Coastguard Worker                     }
584*08b48e0bSAndroid Build Coastguard Worker 
585*08b48e0bSAndroid Build Coastguard Worker                     // fall through
586*08b48e0bSAndroid Build Coastguard Worker 
587*08b48e0bSAndroid Build Coastguard Worker                   case CmpInst::FCMP_ULT:  // fall through
588*08b48e0bSAndroid Build Coastguard Worker                   case CmpInst::FCMP_UGE:  // fall through
589*08b48e0bSAndroid Build Coastguard Worker                   case CmpInst::ICMP_ULT:  // fall through
590*08b48e0bSAndroid Build Coastguard Worker                   case CmpInst::ICMP_UGE:
591*08b48e0bSAndroid Build Coastguard Worker                     if ((val & 0xffff) != 1) val2 = val - 1;
592*08b48e0bSAndroid Build Coastguard Worker                     break;
593*08b48e0bSAndroid Build Coastguard Worker 
594*08b48e0bSAndroid Build Coastguard Worker                   default:
595*08b48e0bSAndroid Build Coastguard Worker                     val2 = 0;
596*08b48e0bSAndroid Build Coastguard Worker 
597*08b48e0bSAndroid Build Coastguard Worker                 }
598*08b48e0bSAndroid Build Coastguard Worker 
599*08b48e0bSAndroid Build Coastguard Worker                 dictionary.push_back(std::string((char *)&val, len));
600*08b48e0bSAndroid Build Coastguard Worker                 found++;
601*08b48e0bSAndroid Build Coastguard Worker 
602*08b48e0bSAndroid Build Coastguard Worker                 if (val2) {
603*08b48e0bSAndroid Build Coastguard Worker 
604*08b48e0bSAndroid Build Coastguard Worker                   dictionary.push_back(std::string((char *)&val2, len));
605*08b48e0bSAndroid Build Coastguard Worker                   found++;
606*08b48e0bSAndroid Build Coastguard Worker 
607*08b48e0bSAndroid Build Coastguard Worker                 }
608*08b48e0bSAndroid Build Coastguard Worker 
609*08b48e0bSAndroid Build Coastguard Worker               }
610*08b48e0bSAndroid Build Coastguard Worker 
611*08b48e0bSAndroid Build Coastguard Worker             }
612*08b48e0bSAndroid Build Coastguard Worker 
613*08b48e0bSAndroid Build Coastguard Worker           }
614*08b48e0bSAndroid Build Coastguard Worker 
615*08b48e0bSAndroid Build Coastguard Worker           if ((callInst = dyn_cast<CallInst>(&IN))) {
616*08b48e0bSAndroid Build Coastguard Worker 
617*08b48e0bSAndroid Build Coastguard Worker             bool   isStrcmp = true;
618*08b48e0bSAndroid Build Coastguard Worker             bool   isMemcmp = true;
619*08b48e0bSAndroid Build Coastguard Worker             bool   isStrncmp = true;
620*08b48e0bSAndroid Build Coastguard Worker             bool   isStrcasecmp = true;
621*08b48e0bSAndroid Build Coastguard Worker             bool   isStrncasecmp = true;
622*08b48e0bSAndroid Build Coastguard Worker             bool   isIntMemcpy = true;
623*08b48e0bSAndroid Build Coastguard Worker             bool   isStdString = true;
624*08b48e0bSAndroid Build Coastguard Worker             size_t optLen = 0;
625*08b48e0bSAndroid Build Coastguard Worker 
626*08b48e0bSAndroid Build Coastguard Worker             Function *Callee = callInst->getCalledFunction();
627*08b48e0bSAndroid Build Coastguard Worker             if (!Callee) continue;
628*08b48e0bSAndroid Build Coastguard Worker             if (callInst->getCallingConv() != llvm::CallingConv::C) continue;
629*08b48e0bSAndroid Build Coastguard Worker             std::string FuncName = Callee->getName().str();
630*08b48e0bSAndroid Build Coastguard Worker 
631*08b48e0bSAndroid Build Coastguard Worker             isStrcmp &= (!FuncName.compare("strcmp") ||
632*08b48e0bSAndroid Build Coastguard Worker                          !FuncName.compare("xmlStrcmp") ||
633*08b48e0bSAndroid Build Coastguard Worker                          !FuncName.compare("xmlStrEqual") ||
634*08b48e0bSAndroid Build Coastguard Worker                          !FuncName.compare("g_strcmp0") ||
635*08b48e0bSAndroid Build Coastguard Worker                          !FuncName.compare("curl_strequal") ||
636*08b48e0bSAndroid Build Coastguard Worker                          !FuncName.compare("strcsequal"));
637*08b48e0bSAndroid Build Coastguard Worker             isMemcmp &=
638*08b48e0bSAndroid Build Coastguard Worker                 (!FuncName.compare("memcmp") || !FuncName.compare("bcmp") ||
639*08b48e0bSAndroid Build Coastguard Worker                  !FuncName.compare("CRYPTO_memcmp") ||
640*08b48e0bSAndroid Build Coastguard Worker                  !FuncName.compare("OPENSSL_memcmp") ||
641*08b48e0bSAndroid Build Coastguard Worker                  !FuncName.compare("memcmp_const_time") ||
642*08b48e0bSAndroid Build Coastguard Worker                  !FuncName.compare("memcmpct"));
643*08b48e0bSAndroid Build Coastguard Worker             isStrncmp &= (!FuncName.compare("strncmp") ||
644*08b48e0bSAndroid Build Coastguard Worker                           !FuncName.compare("xmlStrncmp") ||
645*08b48e0bSAndroid Build Coastguard Worker                           !FuncName.compare("curl_strnequal"));
646*08b48e0bSAndroid Build Coastguard Worker             isStrcasecmp &= (!FuncName.compare("strcasecmp") ||
647*08b48e0bSAndroid Build Coastguard Worker                              !FuncName.compare("stricmp") ||
648*08b48e0bSAndroid Build Coastguard Worker                              !FuncName.compare("ap_cstr_casecmp") ||
649*08b48e0bSAndroid Build Coastguard Worker                              !FuncName.compare("OPENSSL_strcasecmp") ||
650*08b48e0bSAndroid Build Coastguard Worker                              !FuncName.compare("xmlStrcasecmp") ||
651*08b48e0bSAndroid Build Coastguard Worker                              !FuncName.compare("g_strcasecmp") ||
652*08b48e0bSAndroid Build Coastguard Worker                              !FuncName.compare("g_ascii_strcasecmp") ||
653*08b48e0bSAndroid Build Coastguard Worker                              !FuncName.compare("Curl_strcasecompare") ||
654*08b48e0bSAndroid Build Coastguard Worker                              !FuncName.compare("Curl_safe_strcasecompare") ||
655*08b48e0bSAndroid Build Coastguard Worker                              !FuncName.compare("cmsstrcasecmp"));
656*08b48e0bSAndroid Build Coastguard Worker             isStrncasecmp &= (!FuncName.compare("strncasecmp") ||
657*08b48e0bSAndroid Build Coastguard Worker                               !FuncName.compare("strnicmp") ||
658*08b48e0bSAndroid Build Coastguard Worker                               !FuncName.compare("ap_cstr_casecmpn") ||
659*08b48e0bSAndroid Build Coastguard Worker                               !FuncName.compare("OPENSSL_strncasecmp") ||
660*08b48e0bSAndroid Build Coastguard Worker                               !FuncName.compare("xmlStrncasecmp") ||
661*08b48e0bSAndroid Build Coastguard Worker                               !FuncName.compare("g_ascii_strncasecmp") ||
662*08b48e0bSAndroid Build Coastguard Worker                               !FuncName.compare("Curl_strncasecompare") ||
663*08b48e0bSAndroid Build Coastguard Worker                               !FuncName.compare("g_strncasecmp"));
664*08b48e0bSAndroid Build Coastguard Worker 
665*08b48e0bSAndroid Build Coastguard Worker             isIntMemcpy &= !FuncName.compare("llvm.memcpy.p0i8.p0i8.i64");
666*08b48e0bSAndroid Build Coastguard Worker             isStdString &=
667*08b48e0bSAndroid Build Coastguard Worker                 ((FuncName.find("basic_string") != std::string::npos &&
668*08b48e0bSAndroid Build Coastguard Worker                   FuncName.find("compare") != std::string::npos) ||
669*08b48e0bSAndroid Build Coastguard Worker                  (FuncName.find("basic_string") != std::string::npos &&
670*08b48e0bSAndroid Build Coastguard Worker                   FuncName.find("find") != std::string::npos));
671*08b48e0bSAndroid Build Coastguard Worker 
672*08b48e0bSAndroid Build Coastguard Worker             /* we do something different here, putting this BB and the
673*08b48e0bSAndroid Build Coastguard Worker                successors in a block map */
674*08b48e0bSAndroid Build Coastguard Worker             if (!FuncName.compare("__afl_persistent_loop")) {
675*08b48e0bSAndroid Build Coastguard Worker 
676*08b48e0bSAndroid Build Coastguard Worker               BlockList.push_back(&BB);
677*08b48e0bSAndroid Build Coastguard Worker               for (succ_iterator SI = succ_begin(&BB), SE = succ_end(&BB);
678*08b48e0bSAndroid Build Coastguard Worker                    SI != SE; ++SI) {
679*08b48e0bSAndroid Build Coastguard Worker 
680*08b48e0bSAndroid Build Coastguard Worker                 BasicBlock *succ = *SI;
681*08b48e0bSAndroid Build Coastguard Worker                 BlockList.push_back(succ);
682*08b48e0bSAndroid Build Coastguard Worker 
683*08b48e0bSAndroid Build Coastguard Worker               }
684*08b48e0bSAndroid Build Coastguard Worker 
685*08b48e0bSAndroid Build Coastguard Worker             }
686*08b48e0bSAndroid Build Coastguard Worker 
687*08b48e0bSAndroid Build Coastguard Worker             if (!isStrcmp && !isMemcmp && !isStrncmp && !isStrcasecmp &&
688*08b48e0bSAndroid Build Coastguard Worker                 !isStrncasecmp && !isIntMemcpy && !isStdString)
689*08b48e0bSAndroid Build Coastguard Worker               continue;
690*08b48e0bSAndroid Build Coastguard Worker 
691*08b48e0bSAndroid Build Coastguard Worker             /* Verify the strcmp/memcmp/strncmp/strcasecmp/strncasecmp function
692*08b48e0bSAndroid Build Coastguard Worker              * prototype */
693*08b48e0bSAndroid Build Coastguard Worker             FunctionType *FT = Callee->getFunctionType();
694*08b48e0bSAndroid Build Coastguard Worker 
695*08b48e0bSAndroid Build Coastguard Worker             isStrcmp &=
696*08b48e0bSAndroid Build Coastguard Worker                 FT->getNumParams() == 2 &&
697*08b48e0bSAndroid Build Coastguard Worker                 FT->getReturnType()->isIntegerTy(32) &&
698*08b48e0bSAndroid Build Coastguard Worker                 FT->getParamType(0) == FT->getParamType(1) &&
699*08b48e0bSAndroid Build Coastguard Worker                 FT->getParamType(0) ==
700*08b48e0bSAndroid Build Coastguard Worker                     IntegerType::getInt8Ty(M.getContext())->getPointerTo(0);
701*08b48e0bSAndroid Build Coastguard Worker             isStrcasecmp &=
702*08b48e0bSAndroid Build Coastguard Worker                 FT->getNumParams() == 2 &&
703*08b48e0bSAndroid Build Coastguard Worker                 FT->getReturnType()->isIntegerTy(32) &&
704*08b48e0bSAndroid Build Coastguard Worker                 FT->getParamType(0) == FT->getParamType(1) &&
705*08b48e0bSAndroid Build Coastguard Worker                 FT->getParamType(0) ==
706*08b48e0bSAndroid Build Coastguard Worker                     IntegerType::getInt8Ty(M.getContext())->getPointerTo(0);
707*08b48e0bSAndroid Build Coastguard Worker             isMemcmp &= FT->getNumParams() == 3 &&
708*08b48e0bSAndroid Build Coastguard Worker                         FT->getReturnType()->isIntegerTy(32) &&
709*08b48e0bSAndroid Build Coastguard Worker                         FT->getParamType(0)->isPointerTy() &&
710*08b48e0bSAndroid Build Coastguard Worker                         FT->getParamType(1)->isPointerTy() &&
711*08b48e0bSAndroid Build Coastguard Worker                         FT->getParamType(2)->isIntegerTy();
712*08b48e0bSAndroid Build Coastguard Worker             isStrncmp &=
713*08b48e0bSAndroid Build Coastguard Worker                 FT->getNumParams() == 3 &&
714*08b48e0bSAndroid Build Coastguard Worker                 FT->getReturnType()->isIntegerTy(32) &&
715*08b48e0bSAndroid Build Coastguard Worker                 FT->getParamType(0) == FT->getParamType(1) &&
716*08b48e0bSAndroid Build Coastguard Worker                 FT->getParamType(0) ==
717*08b48e0bSAndroid Build Coastguard Worker                     IntegerType::getInt8Ty(M.getContext())->getPointerTo(0) &&
718*08b48e0bSAndroid Build Coastguard Worker                 FT->getParamType(2)->isIntegerTy();
719*08b48e0bSAndroid Build Coastguard Worker             isStrncasecmp &=
720*08b48e0bSAndroid Build Coastguard Worker                 FT->getNumParams() == 3 &&
721*08b48e0bSAndroid Build Coastguard Worker                 FT->getReturnType()->isIntegerTy(32) &&
722*08b48e0bSAndroid Build Coastguard Worker                 FT->getParamType(0) == FT->getParamType(1) &&
723*08b48e0bSAndroid Build Coastguard Worker                 FT->getParamType(0) ==
724*08b48e0bSAndroid Build Coastguard Worker                     IntegerType::getInt8Ty(M.getContext())->getPointerTo(0) &&
725*08b48e0bSAndroid Build Coastguard Worker                 FT->getParamType(2)->isIntegerTy();
726*08b48e0bSAndroid Build Coastguard Worker             isStdString &= FT->getNumParams() >= 2 &&
727*08b48e0bSAndroid Build Coastguard Worker                            FT->getParamType(0)->isPointerTy() &&
728*08b48e0bSAndroid Build Coastguard Worker                            FT->getParamType(1)->isPointerTy();
729*08b48e0bSAndroid Build Coastguard Worker 
730*08b48e0bSAndroid Build Coastguard Worker             if (!isStrcmp && !isMemcmp && !isStrncmp && !isStrcasecmp &&
731*08b48e0bSAndroid Build Coastguard Worker                 !isStrncasecmp && !isIntMemcpy && !isStdString)
732*08b48e0bSAndroid Build Coastguard Worker               continue;
733*08b48e0bSAndroid Build Coastguard Worker 
734*08b48e0bSAndroid Build Coastguard Worker             /* is a str{n,}{case,}cmp/memcmp, check if we have
735*08b48e0bSAndroid Build Coastguard Worker              * str{case,}cmp(x, "const") or str{case,}cmp("const", x)
736*08b48e0bSAndroid Build Coastguard Worker              * strn{case,}cmp(x, "const", ..) or strn{case,}cmp("const", x, ..)
737*08b48e0bSAndroid Build Coastguard Worker              * memcmp(x, "const", ..) or memcmp("const", x, ..) */
738*08b48e0bSAndroid Build Coastguard Worker             Value *Str1P = callInst->getArgOperand(0),
739*08b48e0bSAndroid Build Coastguard Worker                   *Str2P = callInst->getArgOperand(1);
740*08b48e0bSAndroid Build Coastguard Worker             std::string Str1, Str2;
741*08b48e0bSAndroid Build Coastguard Worker             StringRef   TmpStr;
742*08b48e0bSAndroid Build Coastguard Worker             bool        HasStr1 = getConstantStringInfo(Str1P, TmpStr);
743*08b48e0bSAndroid Build Coastguard Worker             if (TmpStr.empty())
744*08b48e0bSAndroid Build Coastguard Worker               HasStr1 = false;
745*08b48e0bSAndroid Build Coastguard Worker             else
746*08b48e0bSAndroid Build Coastguard Worker               Str1 = TmpStr.str();
747*08b48e0bSAndroid Build Coastguard Worker             bool HasStr2 = getConstantStringInfo(Str2P, TmpStr);
748*08b48e0bSAndroid Build Coastguard Worker             if (TmpStr.empty())
749*08b48e0bSAndroid Build Coastguard Worker               HasStr2 = false;
750*08b48e0bSAndroid Build Coastguard Worker             else
751*08b48e0bSAndroid Build Coastguard Worker               Str2 = TmpStr.str();
752*08b48e0bSAndroid Build Coastguard Worker 
753*08b48e0bSAndroid Build Coastguard Worker             if (debug)
754*08b48e0bSAndroid Build Coastguard Worker               fprintf(stderr, "F:%s %p(%s)->\"%s\"(%s) %p(%s)->\"%s\"(%s)\n",
755*08b48e0bSAndroid Build Coastguard Worker                       FuncName.c_str(), Str1P, Str1P->getName().str().c_str(),
756*08b48e0bSAndroid Build Coastguard Worker                       Str1.c_str(), HasStr1 == true ? "true" : "false", Str2P,
757*08b48e0bSAndroid Build Coastguard Worker                       Str2P->getName().str().c_str(), Str2.c_str(),
758*08b48e0bSAndroid Build Coastguard Worker                       HasStr2 == true ? "true" : "false");
759*08b48e0bSAndroid Build Coastguard Worker 
760*08b48e0bSAndroid Build Coastguard Worker             // we handle the 2nd parameter first because of llvm memcpy
761*08b48e0bSAndroid Build Coastguard Worker             if (!HasStr2) {
762*08b48e0bSAndroid Build Coastguard Worker 
763*08b48e0bSAndroid Build Coastguard Worker               auto *Ptr = dyn_cast<ConstantExpr>(Str2P);
764*08b48e0bSAndroid Build Coastguard Worker               if (Ptr && Ptr->getOpcode() == Instruction::GetElementPtr) {
765*08b48e0bSAndroid Build Coastguard Worker 
766*08b48e0bSAndroid Build Coastguard Worker                 if (auto *Var = dyn_cast<GlobalVariable>(Ptr->getOperand(0))) {
767*08b48e0bSAndroid Build Coastguard Worker 
768*08b48e0bSAndroid Build Coastguard Worker                   if (Var->hasInitializer()) {
769*08b48e0bSAndroid Build Coastguard Worker 
770*08b48e0bSAndroid Build Coastguard Worker                     if (auto *Array = dyn_cast<ConstantDataArray>(
771*08b48e0bSAndroid Build Coastguard Worker                             Var->getInitializer())) {
772*08b48e0bSAndroid Build Coastguard Worker 
773*08b48e0bSAndroid Build Coastguard Worker                       HasStr2 = true;
774*08b48e0bSAndroid Build Coastguard Worker                       Str2 = Array->getRawDataValues().str();
775*08b48e0bSAndroid Build Coastguard Worker 
776*08b48e0bSAndroid Build Coastguard Worker                     }
777*08b48e0bSAndroid Build Coastguard Worker 
778*08b48e0bSAndroid Build Coastguard Worker                   }
779*08b48e0bSAndroid Build Coastguard Worker 
780*08b48e0bSAndroid Build Coastguard Worker                 }
781*08b48e0bSAndroid Build Coastguard Worker 
782*08b48e0bSAndroid Build Coastguard Worker               }
783*08b48e0bSAndroid Build Coastguard Worker 
784*08b48e0bSAndroid Build Coastguard Worker             }
785*08b48e0bSAndroid Build Coastguard Worker 
786*08b48e0bSAndroid Build Coastguard Worker             // for the internal memcpy routine we only care for the second
787*08b48e0bSAndroid Build Coastguard Worker             // parameter and are not reporting anything.
788*08b48e0bSAndroid Build Coastguard Worker             if (isIntMemcpy == true) {
789*08b48e0bSAndroid Build Coastguard Worker 
790*08b48e0bSAndroid Build Coastguard Worker               if (HasStr2 == true) {
791*08b48e0bSAndroid Build Coastguard Worker 
792*08b48e0bSAndroid Build Coastguard Worker                 Value       *op2 = callInst->getArgOperand(2);
793*08b48e0bSAndroid Build Coastguard Worker                 ConstantInt *ilen = dyn_cast<ConstantInt>(op2);
794*08b48e0bSAndroid Build Coastguard Worker                 if (ilen) {
795*08b48e0bSAndroid Build Coastguard Worker 
796*08b48e0bSAndroid Build Coastguard Worker                   uint64_t literalLength = Str2.size();
797*08b48e0bSAndroid Build Coastguard Worker                   uint64_t optLength = ilen->getZExtValue();
798*08b48e0bSAndroid Build Coastguard Worker                   if (optLength > literalLength + 1) {
799*08b48e0bSAndroid Build Coastguard Worker 
800*08b48e0bSAndroid Build Coastguard Worker                     optLength = Str2.length() + 1;
801*08b48e0bSAndroid Build Coastguard Worker 
802*08b48e0bSAndroid Build Coastguard Worker                   }
803*08b48e0bSAndroid Build Coastguard Worker 
804*08b48e0bSAndroid Build Coastguard Worker                   if (literalLength + 1 == optLength) {
805*08b48e0bSAndroid Build Coastguard Worker 
806*08b48e0bSAndroid Build Coastguard Worker                     Str2.append("\0", 1);  // add null byte
807*08b48e0bSAndroid Build Coastguard Worker 
808*08b48e0bSAndroid Build Coastguard Worker                   }
809*08b48e0bSAndroid Build Coastguard Worker 
810*08b48e0bSAndroid Build Coastguard Worker                 }
811*08b48e0bSAndroid Build Coastguard Worker 
812*08b48e0bSAndroid Build Coastguard Worker                 valueMap[Str1P] = new std::string(Str2);
813*08b48e0bSAndroid Build Coastguard Worker 
814*08b48e0bSAndroid Build Coastguard Worker                 if (debug)
815*08b48e0bSAndroid Build Coastguard Worker                   fprintf(stderr, "Saved: %s for %p\n", Str2.c_str(), Str1P);
816*08b48e0bSAndroid Build Coastguard Worker                 continue;
817*08b48e0bSAndroid Build Coastguard Worker 
818*08b48e0bSAndroid Build Coastguard Worker               }
819*08b48e0bSAndroid Build Coastguard Worker 
820*08b48e0bSAndroid Build Coastguard Worker               continue;
821*08b48e0bSAndroid Build Coastguard Worker 
822*08b48e0bSAndroid Build Coastguard Worker             }
823*08b48e0bSAndroid Build Coastguard Worker 
824*08b48e0bSAndroid Build Coastguard Worker             // Neither a literal nor a global variable?
825*08b48e0bSAndroid Build Coastguard Worker             // maybe it is a local variable that we saved
826*08b48e0bSAndroid Build Coastguard Worker             if (!HasStr2) {
827*08b48e0bSAndroid Build Coastguard Worker 
828*08b48e0bSAndroid Build Coastguard Worker               std::string *strng = valueMap[Str2P];
829*08b48e0bSAndroid Build Coastguard Worker               if (strng && !strng->empty()) {
830*08b48e0bSAndroid Build Coastguard Worker 
831*08b48e0bSAndroid Build Coastguard Worker                 Str2 = *strng;
832*08b48e0bSAndroid Build Coastguard Worker                 HasStr2 = true;
833*08b48e0bSAndroid Build Coastguard Worker                 if (debug)
834*08b48e0bSAndroid Build Coastguard Worker                   fprintf(stderr, "Filled2: %s for %p\n", strng->c_str(),
835*08b48e0bSAndroid Build Coastguard Worker                           Str2P);
836*08b48e0bSAndroid Build Coastguard Worker 
837*08b48e0bSAndroid Build Coastguard Worker               }
838*08b48e0bSAndroid Build Coastguard Worker 
839*08b48e0bSAndroid Build Coastguard Worker             }
840*08b48e0bSAndroid Build Coastguard Worker 
841*08b48e0bSAndroid Build Coastguard Worker             if (!HasStr1) {
842*08b48e0bSAndroid Build Coastguard Worker 
843*08b48e0bSAndroid Build Coastguard Worker               auto Ptr = dyn_cast<ConstantExpr>(Str1P);
844*08b48e0bSAndroid Build Coastguard Worker 
845*08b48e0bSAndroid Build Coastguard Worker               if (Ptr && Ptr->getOpcode() == Instruction::GetElementPtr) {
846*08b48e0bSAndroid Build Coastguard Worker 
847*08b48e0bSAndroid Build Coastguard Worker                 if (auto *Var = dyn_cast<GlobalVariable>(Ptr->getOperand(0))) {
848*08b48e0bSAndroid Build Coastguard Worker 
849*08b48e0bSAndroid Build Coastguard Worker                   if (Var->hasInitializer()) {
850*08b48e0bSAndroid Build Coastguard Worker 
851*08b48e0bSAndroid Build Coastguard Worker                     if (auto *Array = dyn_cast<ConstantDataArray>(
852*08b48e0bSAndroid Build Coastguard Worker                             Var->getInitializer())) {
853*08b48e0bSAndroid Build Coastguard Worker 
854*08b48e0bSAndroid Build Coastguard Worker                       HasStr1 = true;
855*08b48e0bSAndroid Build Coastguard Worker                       Str1 = Array->getRawDataValues().str();
856*08b48e0bSAndroid Build Coastguard Worker 
857*08b48e0bSAndroid Build Coastguard Worker                     }
858*08b48e0bSAndroid Build Coastguard Worker 
859*08b48e0bSAndroid Build Coastguard Worker                   }
860*08b48e0bSAndroid Build Coastguard Worker 
861*08b48e0bSAndroid Build Coastguard Worker                 }
862*08b48e0bSAndroid Build Coastguard Worker 
863*08b48e0bSAndroid Build Coastguard Worker               }
864*08b48e0bSAndroid Build Coastguard Worker 
865*08b48e0bSAndroid Build Coastguard Worker             }
866*08b48e0bSAndroid Build Coastguard Worker 
867*08b48e0bSAndroid Build Coastguard Worker             // Neither a literal nor a global variable?
868*08b48e0bSAndroid Build Coastguard Worker             // maybe it is a local variable that we saved
869*08b48e0bSAndroid Build Coastguard Worker             if (!HasStr1) {
870*08b48e0bSAndroid Build Coastguard Worker 
871*08b48e0bSAndroid Build Coastguard Worker               std::string *strng = valueMap[Str1P];
872*08b48e0bSAndroid Build Coastguard Worker               if (strng && !strng->empty()) {
873*08b48e0bSAndroid Build Coastguard Worker 
874*08b48e0bSAndroid Build Coastguard Worker                 Str1 = *strng;
875*08b48e0bSAndroid Build Coastguard Worker                 HasStr1 = true;
876*08b48e0bSAndroid Build Coastguard Worker                 if (debug)
877*08b48e0bSAndroid Build Coastguard Worker                   fprintf(stderr, "Filled1: %s for %p\n", strng->c_str(),
878*08b48e0bSAndroid Build Coastguard Worker                           Str1P);
879*08b48e0bSAndroid Build Coastguard Worker 
880*08b48e0bSAndroid Build Coastguard Worker               }
881*08b48e0bSAndroid Build Coastguard Worker 
882*08b48e0bSAndroid Build Coastguard Worker             }
883*08b48e0bSAndroid Build Coastguard Worker 
884*08b48e0bSAndroid Build Coastguard Worker             /* handle cases of one string is const, one string is variable */
885*08b48e0bSAndroid Build Coastguard Worker             if (!(HasStr1 ^ HasStr2)) continue;
886*08b48e0bSAndroid Build Coastguard Worker 
887*08b48e0bSAndroid Build Coastguard Worker             std::string thestring;
888*08b48e0bSAndroid Build Coastguard Worker 
889*08b48e0bSAndroid Build Coastguard Worker             if (HasStr1)
890*08b48e0bSAndroid Build Coastguard Worker               thestring = Str1;
891*08b48e0bSAndroid Build Coastguard Worker             else
892*08b48e0bSAndroid Build Coastguard Worker               thestring = Str2;
893*08b48e0bSAndroid Build Coastguard Worker 
894*08b48e0bSAndroid Build Coastguard Worker             optLen = thestring.length();
895*08b48e0bSAndroid Build Coastguard Worker             if (optLen < 2 || (optLen == 2 && !thestring[1])) { continue; }
896*08b48e0bSAndroid Build Coastguard Worker 
897*08b48e0bSAndroid Build Coastguard Worker             if (isMemcmp || isStrncmp || isStrncasecmp) {
898*08b48e0bSAndroid Build Coastguard Worker 
899*08b48e0bSAndroid Build Coastguard Worker               Value       *op2 = callInst->getArgOperand(2);
900*08b48e0bSAndroid Build Coastguard Worker               ConstantInt *ilen = dyn_cast<ConstantInt>(op2);
901*08b48e0bSAndroid Build Coastguard Worker 
902*08b48e0bSAndroid Build Coastguard Worker               if (ilen) {
903*08b48e0bSAndroid Build Coastguard Worker 
904*08b48e0bSAndroid Build Coastguard Worker                 uint64_t literalLength = optLen;
905*08b48e0bSAndroid Build Coastguard Worker                 optLen = ilen->getZExtValue();
906*08b48e0bSAndroid Build Coastguard Worker                 if (optLen > thestring.length() + 1) {
907*08b48e0bSAndroid Build Coastguard Worker 
908*08b48e0bSAndroid Build Coastguard Worker                   optLen = thestring.length() + 1;
909*08b48e0bSAndroid Build Coastguard Worker 
910*08b48e0bSAndroid Build Coastguard Worker                 }
911*08b48e0bSAndroid Build Coastguard Worker 
912*08b48e0bSAndroid Build Coastguard Worker                 if (optLen < 2) { continue; }
913*08b48e0bSAndroid Build Coastguard Worker                 if (literalLength + 1 == optLen) {  // add null byte
914*08b48e0bSAndroid Build Coastguard Worker 
915*08b48e0bSAndroid Build Coastguard Worker                   thestring.append("\0", 1);
916*08b48e0bSAndroid Build Coastguard Worker 
917*08b48e0bSAndroid Build Coastguard Worker                 }
918*08b48e0bSAndroid Build Coastguard Worker 
919*08b48e0bSAndroid Build Coastguard Worker               }
920*08b48e0bSAndroid Build Coastguard Worker 
921*08b48e0bSAndroid Build Coastguard Worker             }
922*08b48e0bSAndroid Build Coastguard Worker 
923*08b48e0bSAndroid Build Coastguard Worker             // add null byte if this is a string compare function and a null
924*08b48e0bSAndroid Build Coastguard Worker             // was not already added
925*08b48e0bSAndroid Build Coastguard Worker             if (!isMemcmp) {
926*08b48e0bSAndroid Build Coastguard Worker 
927*08b48e0bSAndroid Build Coastguard Worker               /*
928*08b48e0bSAndroid Build Coastguard Worker                             if (addedNull == false && thestring[optLen - 1] !=
929*08b48e0bSAndroid Build Coastguard Worker                  '\0') {
930*08b48e0bSAndroid Build Coastguard Worker 
931*08b48e0bSAndroid Build Coastguard Worker                               thestring.append("\0", 1);  // add null byte
932*08b48e0bSAndroid Build Coastguard Worker                               optLen++;
933*08b48e0bSAndroid Build Coastguard Worker 
934*08b48e0bSAndroid Build Coastguard Worker                             }
935*08b48e0bSAndroid Build Coastguard Worker 
936*08b48e0bSAndroid Build Coastguard Worker               */
937*08b48e0bSAndroid Build Coastguard Worker               if (!isStdString &&
938*08b48e0bSAndroid Build Coastguard Worker                   thestring.find('\0', 0) != std::string::npos) {
939*08b48e0bSAndroid Build Coastguard Worker 
940*08b48e0bSAndroid Build Coastguard Worker                 // ensure we do not have garbage
941*08b48e0bSAndroid Build Coastguard Worker                 size_t offset = thestring.find('\0', 0);
942*08b48e0bSAndroid Build Coastguard Worker                 if (offset + 1 < optLen) optLen = offset + 1;
943*08b48e0bSAndroid Build Coastguard Worker                 thestring = thestring.substr(0, optLen);
944*08b48e0bSAndroid Build Coastguard Worker 
945*08b48e0bSAndroid Build Coastguard Worker               }
946*08b48e0bSAndroid Build Coastguard Worker 
947*08b48e0bSAndroid Build Coastguard Worker             }
948*08b48e0bSAndroid Build Coastguard Worker 
949*08b48e0bSAndroid Build Coastguard Worker             if (!be_quiet) {
950*08b48e0bSAndroid Build Coastguard Worker 
951*08b48e0bSAndroid Build Coastguard Worker               std::string outstring;
952*08b48e0bSAndroid Build Coastguard Worker               fprintf(stderr, "%s: length %zu/%zu \"", FuncName.c_str(), optLen,
953*08b48e0bSAndroid Build Coastguard Worker                       thestring.length());
954*08b48e0bSAndroid Build Coastguard Worker               for (uint16_t i = 0; i < (uint16_t)thestring.length(); i++) {
955*08b48e0bSAndroid Build Coastguard Worker 
956*08b48e0bSAndroid Build Coastguard Worker                 uint8_t c = thestring[i];
957*08b48e0bSAndroid Build Coastguard Worker                 if (c <= 32 || c >= 127)
958*08b48e0bSAndroid Build Coastguard Worker                   fprintf(stderr, "\\x%02x", c);
959*08b48e0bSAndroid Build Coastguard Worker                 else
960*08b48e0bSAndroid Build Coastguard Worker                   fprintf(stderr, "%c", c);
961*08b48e0bSAndroid Build Coastguard Worker 
962*08b48e0bSAndroid Build Coastguard Worker               }
963*08b48e0bSAndroid Build Coastguard Worker 
964*08b48e0bSAndroid Build Coastguard Worker               fprintf(stderr, "\"\n");
965*08b48e0bSAndroid Build Coastguard Worker 
966*08b48e0bSAndroid Build Coastguard Worker             }
967*08b48e0bSAndroid Build Coastguard Worker 
968*08b48e0bSAndroid Build Coastguard Worker             // we take the longer string, even if the compare was to a
969*08b48e0bSAndroid Build Coastguard Worker             // shorter part. Note that depending on the optimizer of the
970*08b48e0bSAndroid Build Coastguard Worker             // compiler this can be wrong, but it is more likely that this
971*08b48e0bSAndroid Build Coastguard Worker             // is helping the fuzzer
972*08b48e0bSAndroid Build Coastguard Worker             if (optLen != thestring.length()) optLen = thestring.length();
973*08b48e0bSAndroid Build Coastguard Worker             if (optLen > MAX_AUTO_EXTRA) optLen = MAX_AUTO_EXTRA;
974*08b48e0bSAndroid Build Coastguard Worker             if (optLen < MIN_AUTO_EXTRA)  // too short? skip
975*08b48e0bSAndroid Build Coastguard Worker               continue;
976*08b48e0bSAndroid Build Coastguard Worker 
977*08b48e0bSAndroid Build Coastguard Worker             dictionary.push_back(thestring.substr(0, optLen));
978*08b48e0bSAndroid Build Coastguard Worker 
979*08b48e0bSAndroid Build Coastguard Worker           }
980*08b48e0bSAndroid Build Coastguard Worker 
981*08b48e0bSAndroid Build Coastguard Worker         }
982*08b48e0bSAndroid Build Coastguard Worker 
983*08b48e0bSAndroid Build Coastguard Worker       }
984*08b48e0bSAndroid Build Coastguard Worker 
985*08b48e0bSAndroid Build Coastguard Worker     }
986*08b48e0bSAndroid Build Coastguard Worker 
987*08b48e0bSAndroid Build Coastguard Worker   }
988*08b48e0bSAndroid Build Coastguard Worker 
989*08b48e0bSAndroid Build Coastguard Worker   // AFL++ END
990*08b48e0bSAndroid Build Coastguard Worker 
991*08b48e0bSAndroid Build Coastguard Worker   SanCovTracePCIndir =
992*08b48e0bSAndroid Build Coastguard Worker       M.getOrInsertFunction(SanCovTracePCIndirName, VoidTy, IntptrTy);
993*08b48e0bSAndroid Build Coastguard Worker   // Make sure smaller parameters are zero-extended to i64 as required by the
994*08b48e0bSAndroid Build Coastguard Worker   // x86_64 ABI.
995*08b48e0bSAndroid Build Coastguard Worker   AttributeList SanCovTraceCmpZeroExtAL;
996*08b48e0bSAndroid Build Coastguard Worker   if (TargetTriple.getArch() == Triple::x86_64) {
997*08b48e0bSAndroid Build Coastguard Worker 
998*08b48e0bSAndroid Build Coastguard Worker     SanCovTraceCmpZeroExtAL =
999*08b48e0bSAndroid Build Coastguard Worker         SanCovTraceCmpZeroExtAL.addParamAttribute(*C, 0, Attribute::ZExt);
1000*08b48e0bSAndroid Build Coastguard Worker     SanCovTraceCmpZeroExtAL =
1001*08b48e0bSAndroid Build Coastguard Worker         SanCovTraceCmpZeroExtAL.addParamAttribute(*C, 1, Attribute::ZExt);
1002*08b48e0bSAndroid Build Coastguard Worker 
1003*08b48e0bSAndroid Build Coastguard Worker   }
1004*08b48e0bSAndroid Build Coastguard Worker 
1005*08b48e0bSAndroid Build Coastguard Worker   SanCovTracePC = M.getOrInsertFunction(SanCovTracePCName, VoidTy);
1006*08b48e0bSAndroid Build Coastguard Worker 
1007*08b48e0bSAndroid Build Coastguard Worker   // SanCovTracePCGuard =
1008*08b48e0bSAndroid Build Coastguard Worker   //    M.getOrInsertFunction(SanCovTracePCGuardName, VoidTy, Int32PtrTy);
1009*08b48e0bSAndroid Build Coastguard Worker 
1010*08b48e0bSAndroid Build Coastguard Worker   for (auto &F : M)
1011*08b48e0bSAndroid Build Coastguard Worker     instrumentFunction(F, DTCallback, PDTCallback);
1012*08b48e0bSAndroid Build Coastguard Worker 
1013*08b48e0bSAndroid Build Coastguard Worker   // AFL++ START
1014*08b48e0bSAndroid Build Coastguard Worker   if (dFile.is_open()) dFile.close();
1015*08b48e0bSAndroid Build Coastguard Worker 
1016*08b48e0bSAndroid Build Coastguard Worker   if (!getenv("AFL_LLVM_LTO_SKIPINIT") &&
1017*08b48e0bSAndroid Build Coastguard Worker       (!getenv("AFL_LLVM_LTO_DONTWRITEID") || dictionary.size() || map_addr)) {
1018*08b48e0bSAndroid Build Coastguard Worker 
1019*08b48e0bSAndroid Build Coastguard Worker     // yes we could create our own function, insert it into ctors ...
1020*08b48e0bSAndroid Build Coastguard Worker     // but this would be a pain in the butt ... so we use afl-llvm-rt-lto.o
1021*08b48e0bSAndroid Build Coastguard Worker 
1022*08b48e0bSAndroid Build Coastguard Worker     Function *f = M.getFunction("__afl_auto_init_globals");
1023*08b48e0bSAndroid Build Coastguard Worker 
1024*08b48e0bSAndroid Build Coastguard Worker     if (!f) {
1025*08b48e0bSAndroid Build Coastguard Worker 
1026*08b48e0bSAndroid Build Coastguard Worker       fprintf(stderr,
1027*08b48e0bSAndroid Build Coastguard Worker               "Error: init function could not be found (this should not "
1028*08b48e0bSAndroid Build Coastguard Worker               "happen)\n");
1029*08b48e0bSAndroid Build Coastguard Worker       exit(-1);
1030*08b48e0bSAndroid Build Coastguard Worker 
1031*08b48e0bSAndroid Build Coastguard Worker     }
1032*08b48e0bSAndroid Build Coastguard Worker 
1033*08b48e0bSAndroid Build Coastguard Worker     BasicBlock *bb = &f->getEntryBlock();
1034*08b48e0bSAndroid Build Coastguard Worker     if (!bb) {
1035*08b48e0bSAndroid Build Coastguard Worker 
1036*08b48e0bSAndroid Build Coastguard Worker       fprintf(stderr,
1037*08b48e0bSAndroid Build Coastguard Worker               "Error: init function does not have an EntryBlock (this should "
1038*08b48e0bSAndroid Build Coastguard Worker               "not happen)\n");
1039*08b48e0bSAndroid Build Coastguard Worker       exit(-1);
1040*08b48e0bSAndroid Build Coastguard Worker 
1041*08b48e0bSAndroid Build Coastguard Worker     }
1042*08b48e0bSAndroid Build Coastguard Worker 
1043*08b48e0bSAndroid Build Coastguard Worker     BasicBlock::iterator IP = bb->getFirstInsertionPt();
1044*08b48e0bSAndroid Build Coastguard Worker     IRBuilder<>          IRB(&(*IP));
1045*08b48e0bSAndroid Build Coastguard Worker 
1046*08b48e0bSAndroid Build Coastguard Worker     if (map_addr) {
1047*08b48e0bSAndroid Build Coastguard Worker 
1048*08b48e0bSAndroid Build Coastguard Worker       GlobalVariable *AFLMapAddrFixed = new GlobalVariable(
1049*08b48e0bSAndroid Build Coastguard Worker           M, Int64Tyi, true, GlobalValue::ExternalLinkage, 0, "__afl_map_addr");
1050*08b48e0bSAndroid Build Coastguard Worker       ConstantInt *MapAddr = ConstantInt::get(Int64Tyi, map_addr);
1051*08b48e0bSAndroid Build Coastguard Worker       StoreInst   *StoreMapAddr = IRB.CreateStore(MapAddr, AFLMapAddrFixed);
1052*08b48e0bSAndroid Build Coastguard Worker       ModuleSanitizerCoverageLTO::SetNoSanitizeMetadata(StoreMapAddr);
1053*08b48e0bSAndroid Build Coastguard Worker 
1054*08b48e0bSAndroid Build Coastguard Worker     }
1055*08b48e0bSAndroid Build Coastguard Worker 
1056*08b48e0bSAndroid Build Coastguard Worker     if (getenv("AFL_LLVM_LTO_DONTWRITEID") == NULL) {
1057*08b48e0bSAndroid Build Coastguard Worker 
1058*08b48e0bSAndroid Build Coastguard Worker       uint32_t write_loc = afl_global_id;
1059*08b48e0bSAndroid Build Coastguard Worker 
1060*08b48e0bSAndroid Build Coastguard Worker       write_loc = (((afl_global_id + 8) >> 3) << 3);
1061*08b48e0bSAndroid Build Coastguard Worker 
1062*08b48e0bSAndroid Build Coastguard Worker       GlobalVariable *AFLFinalLoc =
1063*08b48e0bSAndroid Build Coastguard Worker           new GlobalVariable(M, Int32Tyi, true, GlobalValue::ExternalLinkage, 0,
1064*08b48e0bSAndroid Build Coastguard Worker                              "__afl_final_loc");
1065*08b48e0bSAndroid Build Coastguard Worker       ConstantInt *const_loc = ConstantInt::get(Int32Tyi, write_loc);
1066*08b48e0bSAndroid Build Coastguard Worker       StoreInst   *StoreFinalLoc = IRB.CreateStore(const_loc, AFLFinalLoc);
1067*08b48e0bSAndroid Build Coastguard Worker       ModuleSanitizerCoverageLTO::SetNoSanitizeMetadata(StoreFinalLoc);
1068*08b48e0bSAndroid Build Coastguard Worker 
1069*08b48e0bSAndroid Build Coastguard Worker     }
1070*08b48e0bSAndroid Build Coastguard Worker 
1071*08b48e0bSAndroid Build Coastguard Worker     if (dictionary.size()) {
1072*08b48e0bSAndroid Build Coastguard Worker 
1073*08b48e0bSAndroid Build Coastguard Worker       size_t memlen = 0, count = 0, offset = 0;
1074*08b48e0bSAndroid Build Coastguard Worker 
1075*08b48e0bSAndroid Build Coastguard Worker       // sort and unique the dictionary
1076*08b48e0bSAndroid Build Coastguard Worker       std::sort(dictionary.begin(), dictionary.end());
1077*08b48e0bSAndroid Build Coastguard Worker       auto last = std::unique(dictionary.begin(), dictionary.end());
1078*08b48e0bSAndroid Build Coastguard Worker       dictionary.erase(last, dictionary.end());
1079*08b48e0bSAndroid Build Coastguard Worker 
1080*08b48e0bSAndroid Build Coastguard Worker       for (auto token : dictionary) {
1081*08b48e0bSAndroid Build Coastguard Worker 
1082*08b48e0bSAndroid Build Coastguard Worker         memlen += token.length();
1083*08b48e0bSAndroid Build Coastguard Worker         count++;
1084*08b48e0bSAndroid Build Coastguard Worker 
1085*08b48e0bSAndroid Build Coastguard Worker       }
1086*08b48e0bSAndroid Build Coastguard Worker 
1087*08b48e0bSAndroid Build Coastguard Worker       if (!be_quiet)
1088*08b48e0bSAndroid Build Coastguard Worker         printf("AUTODICTIONARY: %zu string%s found\n", count,
1089*08b48e0bSAndroid Build Coastguard Worker                count == 1 ? "" : "s");
1090*08b48e0bSAndroid Build Coastguard Worker 
1091*08b48e0bSAndroid Build Coastguard Worker       if (count) {
1092*08b48e0bSAndroid Build Coastguard Worker 
1093*08b48e0bSAndroid Build Coastguard Worker         auto ptrhld = std::unique_ptr<char[]>(new char[memlen + count]);
1094*08b48e0bSAndroid Build Coastguard Worker 
1095*08b48e0bSAndroid Build Coastguard Worker         count = 0;
1096*08b48e0bSAndroid Build Coastguard Worker 
1097*08b48e0bSAndroid Build Coastguard Worker         for (auto token : dictionary) {
1098*08b48e0bSAndroid Build Coastguard Worker 
1099*08b48e0bSAndroid Build Coastguard Worker           if (offset + token.length() < 0xfffff0 && count < MAX_AUTO_EXTRAS) {
1100*08b48e0bSAndroid Build Coastguard Worker 
1101*08b48e0bSAndroid Build Coastguard Worker             ptrhld.get()[offset++] = (uint8_t)token.length();
1102*08b48e0bSAndroid Build Coastguard Worker             memcpy(ptrhld.get() + offset, token.c_str(), token.length());
1103*08b48e0bSAndroid Build Coastguard Worker             offset += token.length();
1104*08b48e0bSAndroid Build Coastguard Worker             count++;
1105*08b48e0bSAndroid Build Coastguard Worker 
1106*08b48e0bSAndroid Build Coastguard Worker           }
1107*08b48e0bSAndroid Build Coastguard Worker 
1108*08b48e0bSAndroid Build Coastguard Worker         }
1109*08b48e0bSAndroid Build Coastguard Worker 
1110*08b48e0bSAndroid Build Coastguard Worker         GlobalVariable *AFLDictionaryLen =
1111*08b48e0bSAndroid Build Coastguard Worker             new GlobalVariable(M, Int32Tyi, false, GlobalValue::ExternalLinkage,
1112*08b48e0bSAndroid Build Coastguard Worker                                0, "__afl_dictionary_len");
1113*08b48e0bSAndroid Build Coastguard Worker         ConstantInt *const_len = ConstantInt::get(Int32Tyi, offset);
1114*08b48e0bSAndroid Build Coastguard Worker         StoreInst *StoreDictLen = IRB.CreateStore(const_len, AFLDictionaryLen);
1115*08b48e0bSAndroid Build Coastguard Worker         ModuleSanitizerCoverageLTO::SetNoSanitizeMetadata(StoreDictLen);
1116*08b48e0bSAndroid Build Coastguard Worker 
1117*08b48e0bSAndroid Build Coastguard Worker         ArrayType *ArrayTy = ArrayType::get(IntegerType::get(Ctx, 8), offset);
1118*08b48e0bSAndroid Build Coastguard Worker         GlobalVariable *AFLInternalDictionary = new GlobalVariable(
1119*08b48e0bSAndroid Build Coastguard Worker             M, ArrayTy, true, GlobalValue::ExternalLinkage,
1120*08b48e0bSAndroid Build Coastguard Worker             ConstantDataArray::get(Ctx,
1121*08b48e0bSAndroid Build Coastguard Worker                                    *(new ArrayRef<char>(ptrhld.get(), offset))),
1122*08b48e0bSAndroid Build Coastguard Worker             "__afl_internal_dictionary");
1123*08b48e0bSAndroid Build Coastguard Worker         AFLInternalDictionary->setInitializer(ConstantDataArray::get(
1124*08b48e0bSAndroid Build Coastguard Worker             Ctx, *(new ArrayRef<char>(ptrhld.get(), offset))));
1125*08b48e0bSAndroid Build Coastguard Worker         AFLInternalDictionary->setConstant(true);
1126*08b48e0bSAndroid Build Coastguard Worker 
1127*08b48e0bSAndroid Build Coastguard Worker         GlobalVariable *AFLDictionary = new GlobalVariable(
1128*08b48e0bSAndroid Build Coastguard Worker             M, PointerType::get(Int8Tyi, 0), false,
1129*08b48e0bSAndroid Build Coastguard Worker             GlobalValue::ExternalLinkage, 0, "__afl_dictionary");
1130*08b48e0bSAndroid Build Coastguard Worker 
1131*08b48e0bSAndroid Build Coastguard Worker         Value *AFLDictOff = IRB.CreateGEP(Int8Ty, AFLInternalDictionary, Zero);
1132*08b48e0bSAndroid Build Coastguard Worker         Value *AFLDictPtr =
1133*08b48e0bSAndroid Build Coastguard Worker             IRB.CreatePointerCast(AFLDictOff, PointerType::get(Int8Tyi, 0));
1134*08b48e0bSAndroid Build Coastguard Worker         StoreInst *StoreDict = IRB.CreateStore(AFLDictPtr, AFLDictionary);
1135*08b48e0bSAndroid Build Coastguard Worker         ModuleSanitizerCoverageLTO::SetNoSanitizeMetadata(StoreDict);
1136*08b48e0bSAndroid Build Coastguard Worker 
1137*08b48e0bSAndroid Build Coastguard Worker       }
1138*08b48e0bSAndroid Build Coastguard Worker 
1139*08b48e0bSAndroid Build Coastguard Worker     }
1140*08b48e0bSAndroid Build Coastguard Worker 
1141*08b48e0bSAndroid Build Coastguard Worker   }
1142*08b48e0bSAndroid Build Coastguard Worker 
1143*08b48e0bSAndroid Build Coastguard Worker   /* Say something nice. */
1144*08b48e0bSAndroid Build Coastguard Worker 
1145*08b48e0bSAndroid Build Coastguard Worker   if (!be_quiet) {
1146*08b48e0bSAndroid Build Coastguard Worker 
1147*08b48e0bSAndroid Build Coastguard Worker     if (!inst)
1148*08b48e0bSAndroid Build Coastguard Worker       WARNF("No instrumentation targets found.");
1149*08b48e0bSAndroid Build Coastguard Worker     else {
1150*08b48e0bSAndroid Build Coastguard Worker 
1151*08b48e0bSAndroid Build Coastguard Worker       char modeline[100];
1152*08b48e0bSAndroid Build Coastguard Worker       snprintf(modeline, sizeof(modeline), "%s%s%s%s%s%s",
1153*08b48e0bSAndroid Build Coastguard Worker                getenv("AFL_HARDEN") ? "hardened" : "non-hardened",
1154*08b48e0bSAndroid Build Coastguard Worker                getenv("AFL_USE_ASAN") ? ", ASAN" : "",
1155*08b48e0bSAndroid Build Coastguard Worker                getenv("AFL_USE_MSAN") ? ", MSAN" : "",
1156*08b48e0bSAndroid Build Coastguard Worker                getenv("AFL_USE_TSAN") ? ", TSAN" : "",
1157*08b48e0bSAndroid Build Coastguard Worker                getenv("AFL_USE_CFISAN") ? ", CFISAN" : "",
1158*08b48e0bSAndroid Build Coastguard Worker                getenv("AFL_USE_UBSAN") ? ", UBSAN" : "");
1159*08b48e0bSAndroid Build Coastguard Worker       OKF("Instrumented %u locations (%u selects) without collisions (%llu "
1160*08b48e0bSAndroid Build Coastguard Worker           "collisions have been avoided) (%s mode).",
1161*08b48e0bSAndroid Build Coastguard Worker           inst, select_cnt, calculateCollisions(inst), modeline);
1162*08b48e0bSAndroid Build Coastguard Worker 
1163*08b48e0bSAndroid Build Coastguard Worker     }
1164*08b48e0bSAndroid Build Coastguard Worker 
1165*08b48e0bSAndroid Build Coastguard Worker   }
1166*08b48e0bSAndroid Build Coastguard Worker 
1167*08b48e0bSAndroid Build Coastguard Worker   // AFL++ END
1168*08b48e0bSAndroid Build Coastguard Worker 
1169*08b48e0bSAndroid Build Coastguard Worker   // We don't reference these arrays directly in any of our runtime functions,
1170*08b48e0bSAndroid Build Coastguard Worker   // so we need to prevent them from being dead stripped.
1171*08b48e0bSAndroid Build Coastguard Worker   if (TargetTriple.isOSBinFormatMachO()) appendToUsed(M, GlobalsToAppendToUsed);
1172*08b48e0bSAndroid Build Coastguard Worker   appendToCompilerUsed(M, GlobalsToAppendToCompilerUsed);
1173*08b48e0bSAndroid Build Coastguard Worker   return true;
1174*08b48e0bSAndroid Build Coastguard Worker 
1175*08b48e0bSAndroid Build Coastguard Worker }
1176*08b48e0bSAndroid Build Coastguard Worker 
1177*08b48e0bSAndroid Build Coastguard Worker // True if block has successors and it dominates all of them.
isFullDominator(const BasicBlock * BB,const DominatorTree * DT)1178*08b48e0bSAndroid Build Coastguard Worker static bool isFullDominator(const BasicBlock *BB, const DominatorTree *DT) {
1179*08b48e0bSAndroid Build Coastguard Worker 
1180*08b48e0bSAndroid Build Coastguard Worker   if (succ_begin(BB) == succ_end(BB)) return false;
1181*08b48e0bSAndroid Build Coastguard Worker 
1182*08b48e0bSAndroid Build Coastguard Worker   for (const BasicBlock *SUCC : make_range(succ_begin(BB), succ_end(BB))) {
1183*08b48e0bSAndroid Build Coastguard Worker 
1184*08b48e0bSAndroid Build Coastguard Worker     if (!DT->dominates(BB, SUCC)) return false;
1185*08b48e0bSAndroid Build Coastguard Worker 
1186*08b48e0bSAndroid Build Coastguard Worker   }
1187*08b48e0bSAndroid Build Coastguard Worker 
1188*08b48e0bSAndroid Build Coastguard Worker   return true;
1189*08b48e0bSAndroid Build Coastguard Worker 
1190*08b48e0bSAndroid Build Coastguard Worker }
1191*08b48e0bSAndroid Build Coastguard Worker 
1192*08b48e0bSAndroid Build Coastguard Worker // True if block has predecessors and it postdominates all of them.
isFullPostDominator(const BasicBlock * BB,const PostDominatorTree * PDT)1193*08b48e0bSAndroid Build Coastguard Worker static bool isFullPostDominator(const BasicBlock        *BB,
1194*08b48e0bSAndroid Build Coastguard Worker                                 const PostDominatorTree *PDT) {
1195*08b48e0bSAndroid Build Coastguard Worker 
1196*08b48e0bSAndroid Build Coastguard Worker   if (pred_begin(BB) == pred_end(BB)) return false;
1197*08b48e0bSAndroid Build Coastguard Worker 
1198*08b48e0bSAndroid Build Coastguard Worker   for (const BasicBlock *PRED : make_range(pred_begin(BB), pred_end(BB))) {
1199*08b48e0bSAndroid Build Coastguard Worker 
1200*08b48e0bSAndroid Build Coastguard Worker     if (!PDT->dominates(BB, PRED)) return false;
1201*08b48e0bSAndroid Build Coastguard Worker 
1202*08b48e0bSAndroid Build Coastguard Worker   }
1203*08b48e0bSAndroid Build Coastguard Worker 
1204*08b48e0bSAndroid Build Coastguard Worker   return true;
1205*08b48e0bSAndroid Build Coastguard Worker 
1206*08b48e0bSAndroid Build Coastguard Worker }
1207*08b48e0bSAndroid Build Coastguard Worker 
shouldInstrumentBlock(const Function & F,const BasicBlock * BB,const DominatorTree * DT,const PostDominatorTree * PDT,const SanitizerCoverageOptions & Options)1208*08b48e0bSAndroid Build Coastguard Worker static bool shouldInstrumentBlock(const Function &F, const BasicBlock *BB,
1209*08b48e0bSAndroid Build Coastguard Worker                                   const DominatorTree            *DT,
1210*08b48e0bSAndroid Build Coastguard Worker                                   const PostDominatorTree        *PDT,
1211*08b48e0bSAndroid Build Coastguard Worker                                   const SanitizerCoverageOptions &Options) {
1212*08b48e0bSAndroid Build Coastguard Worker 
1213*08b48e0bSAndroid Build Coastguard Worker   // Don't insert coverage for blocks containing nothing but unreachable: we
1214*08b48e0bSAndroid Build Coastguard Worker   // will never call __sanitizer_cov() for them, so counting them in
1215*08b48e0bSAndroid Build Coastguard Worker   // NumberOfInstrumentedBlocks() might complicate calculation of code coverage
1216*08b48e0bSAndroid Build Coastguard Worker   // percentage. Also, unreachable instructions frequently have no debug
1217*08b48e0bSAndroid Build Coastguard Worker   // locations.
1218*08b48e0bSAndroid Build Coastguard Worker   if (isa<UnreachableInst>(BB->getFirstNonPHIOrDbgOrLifetime())) return false;
1219*08b48e0bSAndroid Build Coastguard Worker 
1220*08b48e0bSAndroid Build Coastguard Worker   // Don't insert coverage into blocks without a valid insertion point
1221*08b48e0bSAndroid Build Coastguard Worker   // (catchswitch blocks).
1222*08b48e0bSAndroid Build Coastguard Worker   if (BB->getFirstInsertionPt() == BB->end()) return false;
1223*08b48e0bSAndroid Build Coastguard Worker 
1224*08b48e0bSAndroid Build Coastguard Worker   // AFL++ START
1225*08b48e0bSAndroid Build Coastguard Worker   if (!Options.NoPrune && &F.getEntryBlock() == BB && F.size() > 1)
1226*08b48e0bSAndroid Build Coastguard Worker     return false;
1227*08b48e0bSAndroid Build Coastguard Worker   // AFL++ END
1228*08b48e0bSAndroid Build Coastguard Worker 
1229*08b48e0bSAndroid Build Coastguard Worker   if (Options.NoPrune || &F.getEntryBlock() == BB) return true;
1230*08b48e0bSAndroid Build Coastguard Worker 
1231*08b48e0bSAndroid Build Coastguard Worker   if (Options.CoverageType == SanitizerCoverageOptions::SCK_Function &&
1232*08b48e0bSAndroid Build Coastguard Worker       &F.getEntryBlock() != BB)
1233*08b48e0bSAndroid Build Coastguard Worker     return false;
1234*08b48e0bSAndroid Build Coastguard Worker 
1235*08b48e0bSAndroid Build Coastguard Worker   // Do not instrument full dominators, or full post-dominators with multiple
1236*08b48e0bSAndroid Build Coastguard Worker   // predecessors.
1237*08b48e0bSAndroid Build Coastguard Worker   return !isFullDominator(BB, DT) &&
1238*08b48e0bSAndroid Build Coastguard Worker          !(isFullPostDominator(BB, PDT) && !BB->getSinglePredecessor());
1239*08b48e0bSAndroid Build Coastguard Worker 
1240*08b48e0bSAndroid Build Coastguard Worker }
1241*08b48e0bSAndroid Build Coastguard Worker 
instrumentFunction(Function & F,DomTreeCallback DTCallback,PostDomTreeCallback PDTCallback)1242*08b48e0bSAndroid Build Coastguard Worker void ModuleSanitizerCoverageLTO::instrumentFunction(
1243*08b48e0bSAndroid Build Coastguard Worker     Function &F, DomTreeCallback DTCallback, PostDomTreeCallback PDTCallback) {
1244*08b48e0bSAndroid Build Coastguard Worker 
1245*08b48e0bSAndroid Build Coastguard Worker   if (F.empty()) return;
1246*08b48e0bSAndroid Build Coastguard Worker   if (F.getName().find(".module_ctor") != std::string::npos)
1247*08b48e0bSAndroid Build Coastguard Worker     return;  // Should not instrument sanitizer init functions.
1248*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 18
1249*08b48e0bSAndroid Build Coastguard Worker   if (F.getName().starts_with("__sanitizer_"))
1250*08b48e0bSAndroid Build Coastguard Worker #else
1251*08b48e0bSAndroid Build Coastguard Worker   if (F.getName().startswith("__sanitizer_"))
1252*08b48e0bSAndroid Build Coastguard Worker #endif
1253*08b48e0bSAndroid Build Coastguard Worker     return;  // Don't instrument __sanitizer_* callbacks.
1254*08b48e0bSAndroid Build Coastguard Worker   // Don't touch available_externally functions, their actual body is elsewhere.
1255*08b48e0bSAndroid Build Coastguard Worker   if (F.getLinkage() == GlobalValue::AvailableExternallyLinkage) return;
1256*08b48e0bSAndroid Build Coastguard Worker   // Don't instrument MSVC CRT configuration helpers. They may run before normal
1257*08b48e0bSAndroid Build Coastguard Worker   // initialization.
1258*08b48e0bSAndroid Build Coastguard Worker   if (F.getName() == "__local_stdio_printf_options" ||
1259*08b48e0bSAndroid Build Coastguard Worker       F.getName() == "__local_stdio_scanf_options")
1260*08b48e0bSAndroid Build Coastguard Worker     return;
1261*08b48e0bSAndroid Build Coastguard Worker   if (isa<UnreachableInst>(F.getEntryBlock().getTerminator())) return;
1262*08b48e0bSAndroid Build Coastguard Worker   // Don't instrument functions using SEH for now. Splitting basic blocks like
1263*08b48e0bSAndroid Build Coastguard Worker   // we do for coverage breaks WinEHPrepare.
1264*08b48e0bSAndroid Build Coastguard Worker   // FIXME: Remove this when SEH no longer uses landingpad pattern matching.
1265*08b48e0bSAndroid Build Coastguard Worker   if (F.hasPersonalityFn() &&
1266*08b48e0bSAndroid Build Coastguard Worker       isAsynchronousEHPersonality(classifyEHPersonality(F.getPersonalityFn())))
1267*08b48e0bSAndroid Build Coastguard Worker     return;
1268*08b48e0bSAndroid Build Coastguard Worker   // if (Allowlist && !Allowlist->inSection("coverage", "fun", F.getName()))
1269*08b48e0bSAndroid Build Coastguard Worker   //  return;
1270*08b48e0bSAndroid Build Coastguard Worker   // if (Blocklist && Blocklist->inSection("coverage", "fun", F.getName()))
1271*08b48e0bSAndroid Build Coastguard Worker   // return;
1272*08b48e0bSAndroid Build Coastguard Worker 
1273*08b48e0bSAndroid Build Coastguard Worker   // AFL++ START
1274*08b48e0bSAndroid Build Coastguard Worker   if (!F.size()) return;
1275*08b48e0bSAndroid Build Coastguard Worker   if (!isInInstrumentList(&F, FMNAME)) return;
1276*08b48e0bSAndroid Build Coastguard Worker   // AFL++ END
1277*08b48e0bSAndroid Build Coastguard Worker 
1278*08b48e0bSAndroid Build Coastguard Worker   if (Options.CoverageType >= SanitizerCoverageOptions::SCK_Edge)
1279*08b48e0bSAndroid Build Coastguard Worker     SplitAllCriticalEdges(
1280*08b48e0bSAndroid Build Coastguard Worker         F, CriticalEdgeSplittingOptions().setIgnoreUnreachableDests());
1281*08b48e0bSAndroid Build Coastguard Worker   SmallVector<Instruction *, 8> IndirCalls;
1282*08b48e0bSAndroid Build Coastguard Worker   SmallVector<BasicBlock *, 16> BlocksToInstrument;
1283*08b48e0bSAndroid Build Coastguard Worker 
1284*08b48e0bSAndroid Build Coastguard Worker   const DominatorTree     *DT = DTCallback(F);
1285*08b48e0bSAndroid Build Coastguard Worker   const PostDominatorTree *PDT = PDTCallback(F);
1286*08b48e0bSAndroid Build Coastguard Worker   bool                     IsLeafFunc = true;
1287*08b48e0bSAndroid Build Coastguard Worker   uint32_t                 skip_next = 0;
1288*08b48e0bSAndroid Build Coastguard Worker 
1289*08b48e0bSAndroid Build Coastguard Worker   for (auto &BB : F) {
1290*08b48e0bSAndroid Build Coastguard Worker 
1291*08b48e0bSAndroid Build Coastguard Worker     for (auto &IN : BB) {
1292*08b48e0bSAndroid Build Coastguard Worker 
1293*08b48e0bSAndroid Build Coastguard Worker       CallInst *callInst = nullptr;
1294*08b48e0bSAndroid Build Coastguard Worker 
1295*08b48e0bSAndroid Build Coastguard Worker       if ((callInst = dyn_cast<CallInst>(&IN))) {
1296*08b48e0bSAndroid Build Coastguard Worker 
1297*08b48e0bSAndroid Build Coastguard Worker         Function *Callee = callInst->getCalledFunction();
1298*08b48e0bSAndroid Build Coastguard Worker         if (!Callee) continue;
1299*08b48e0bSAndroid Build Coastguard Worker         if (callInst->getCallingConv() != llvm::CallingConv::C) continue;
1300*08b48e0bSAndroid Build Coastguard Worker         StringRef FuncName = Callee->getName();
1301*08b48e0bSAndroid Build Coastguard Worker         if (!FuncName.compare(StringRef("dlopen")) ||
1302*08b48e0bSAndroid Build Coastguard Worker             !FuncName.compare(StringRef("_dlopen"))) {
1303*08b48e0bSAndroid Build Coastguard Worker 
1304*08b48e0bSAndroid Build Coastguard Worker           fprintf(stderr,
1305*08b48e0bSAndroid Build Coastguard Worker                   "WARNING: dlopen() detected. To have coverage for a library "
1306*08b48e0bSAndroid Build Coastguard Worker                   "that your target dlopen()'s this must either happen before "
1307*08b48e0bSAndroid Build Coastguard Worker                   "__AFL_INIT() or you must use AFL_PRELOAD to preload all "
1308*08b48e0bSAndroid Build Coastguard Worker                   "dlopen()'ed libraries!\n");
1309*08b48e0bSAndroid Build Coastguard Worker           continue;
1310*08b48e0bSAndroid Build Coastguard Worker 
1311*08b48e0bSAndroid Build Coastguard Worker         }
1312*08b48e0bSAndroid Build Coastguard Worker 
1313*08b48e0bSAndroid Build Coastguard Worker         if (FuncName.compare(StringRef("__afl_coverage_interesting"))) continue;
1314*08b48e0bSAndroid Build Coastguard Worker 
1315*08b48e0bSAndroid Build Coastguard Worker         Value *val = ConstantInt::get(Int32Ty, ++afl_global_id);
1316*08b48e0bSAndroid Build Coastguard Worker         callInst->setOperand(1, val);
1317*08b48e0bSAndroid Build Coastguard Worker         ++inst;
1318*08b48e0bSAndroid Build Coastguard Worker 
1319*08b48e0bSAndroid Build Coastguard Worker       }
1320*08b48e0bSAndroid Build Coastguard Worker 
1321*08b48e0bSAndroid Build Coastguard Worker       SelectInst *selectInst = nullptr;
1322*08b48e0bSAndroid Build Coastguard Worker 
1323*08b48e0bSAndroid Build Coastguard Worker       /*
1324*08b48e0bSAndroid Build Coastguard Worker             std::string errMsg;
1325*08b48e0bSAndroid Build Coastguard Worker             raw_string_ostream os(errMsg);
1326*08b48e0bSAndroid Build Coastguard Worker             IN.print(os);
1327*08b48e0bSAndroid Build Coastguard Worker             fprintf(stderr, "X(%u): %s\n", skip_next, os.str().c_str());
1328*08b48e0bSAndroid Build Coastguard Worker       */
1329*08b48e0bSAndroid Build Coastguard Worker       if (!skip_next && (selectInst = dyn_cast<SelectInst>(&IN))) {
1330*08b48e0bSAndroid Build Coastguard Worker 
1331*08b48e0bSAndroid Build Coastguard Worker         uint32_t    vector_cnt = 0;
1332*08b48e0bSAndroid Build Coastguard Worker         Value      *condition = selectInst->getCondition();
1333*08b48e0bSAndroid Build Coastguard Worker         Value      *result;
1334*08b48e0bSAndroid Build Coastguard Worker         auto        t = condition->getType();
1335*08b48e0bSAndroid Build Coastguard Worker         IRBuilder<> IRB(selectInst->getNextNode());
1336*08b48e0bSAndroid Build Coastguard Worker 
1337*08b48e0bSAndroid Build Coastguard Worker         ++select_cnt;
1338*08b48e0bSAndroid Build Coastguard Worker 
1339*08b48e0bSAndroid Build Coastguard Worker         if (t->getTypeID() == llvm::Type::IntegerTyID) {
1340*08b48e0bSAndroid Build Coastguard Worker 
1341*08b48e0bSAndroid Build Coastguard Worker           Value *val1 = ConstantInt::get(Int32Ty, ++afl_global_id);
1342*08b48e0bSAndroid Build Coastguard Worker           Value *val2 = ConstantInt::get(Int32Ty, ++afl_global_id);
1343*08b48e0bSAndroid Build Coastguard Worker           result = IRB.CreateSelect(condition, val1, val2);
1344*08b48e0bSAndroid Build Coastguard Worker           skip_next = 1;
1345*08b48e0bSAndroid Build Coastguard Worker           inst += 2;
1346*08b48e0bSAndroid Build Coastguard Worker 
1347*08b48e0bSAndroid Build Coastguard Worker         } else
1348*08b48e0bSAndroid Build Coastguard Worker 
1349*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 14
1350*08b48e0bSAndroid Build Coastguard Worker             if (t->getTypeID() == llvm::Type::FixedVectorTyID) {
1351*08b48e0bSAndroid Build Coastguard Worker 
1352*08b48e0bSAndroid Build Coastguard Worker           FixedVectorType *tt = dyn_cast<FixedVectorType>(t);
1353*08b48e0bSAndroid Build Coastguard Worker           if (tt) {
1354*08b48e0bSAndroid Build Coastguard Worker 
1355*08b48e0bSAndroid Build Coastguard Worker             uint32_t elements = tt->getElementCount().getFixedValue();
1356*08b48e0bSAndroid Build Coastguard Worker             vector_cnt = elements;
1357*08b48e0bSAndroid Build Coastguard Worker             inst += vector_cnt * 2;
1358*08b48e0bSAndroid Build Coastguard Worker             if (elements) {
1359*08b48e0bSAndroid Build Coastguard Worker 
1360*08b48e0bSAndroid Build Coastguard Worker               FixedVectorType *GuardPtr1 =
1361*08b48e0bSAndroid Build Coastguard Worker                   FixedVectorType::get(Int32Ty, elements);
1362*08b48e0bSAndroid Build Coastguard Worker               FixedVectorType *GuardPtr2 =
1363*08b48e0bSAndroid Build Coastguard Worker                   FixedVectorType::get(Int32Ty, elements);
1364*08b48e0bSAndroid Build Coastguard Worker               Value *x, *y;
1365*08b48e0bSAndroid Build Coastguard Worker 
1366*08b48e0bSAndroid Build Coastguard Worker               Value *val1 = ConstantInt::get(Int32Ty, ++afl_global_id);
1367*08b48e0bSAndroid Build Coastguard Worker               Value *val2 = ConstantInt::get(Int32Ty, ++afl_global_id);
1368*08b48e0bSAndroid Build Coastguard Worker               x = IRB.CreateInsertElement(GuardPtr1, val1, (uint64_t)0);
1369*08b48e0bSAndroid Build Coastguard Worker               y = IRB.CreateInsertElement(GuardPtr2, val2, (uint64_t)0);
1370*08b48e0bSAndroid Build Coastguard Worker 
1371*08b48e0bSAndroid Build Coastguard Worker               for (uint64_t i = 1; i < elements; i++) {
1372*08b48e0bSAndroid Build Coastguard Worker 
1373*08b48e0bSAndroid Build Coastguard Worker                 val1 = ConstantInt::get(Int32Ty, ++afl_global_id);
1374*08b48e0bSAndroid Build Coastguard Worker                 val2 = ConstantInt::get(Int32Ty, ++afl_global_id);
1375*08b48e0bSAndroid Build Coastguard Worker                 x = IRB.CreateInsertElement(GuardPtr1, val1, i);
1376*08b48e0bSAndroid Build Coastguard Worker                 y = IRB.CreateInsertElement(GuardPtr2, val2, i);
1377*08b48e0bSAndroid Build Coastguard Worker 
1378*08b48e0bSAndroid Build Coastguard Worker               }
1379*08b48e0bSAndroid Build Coastguard Worker 
1380*08b48e0bSAndroid Build Coastguard Worker               result = IRB.CreateSelect(condition, x, y);
1381*08b48e0bSAndroid Build Coastguard Worker               skip_next = 1;
1382*08b48e0bSAndroid Build Coastguard Worker 
1383*08b48e0bSAndroid Build Coastguard Worker             }
1384*08b48e0bSAndroid Build Coastguard Worker 
1385*08b48e0bSAndroid Build Coastguard Worker           }
1386*08b48e0bSAndroid Build Coastguard Worker 
1387*08b48e0bSAndroid Build Coastguard Worker         } else
1388*08b48e0bSAndroid Build Coastguard Worker 
1389*08b48e0bSAndroid Build Coastguard Worker #endif
1390*08b48e0bSAndroid Build Coastguard Worker         {
1391*08b48e0bSAndroid Build Coastguard Worker 
1392*08b48e0bSAndroid Build Coastguard Worker           unhandled++;
1393*08b48e0bSAndroid Build Coastguard Worker           continue;
1394*08b48e0bSAndroid Build Coastguard Worker 
1395*08b48e0bSAndroid Build Coastguard Worker         }
1396*08b48e0bSAndroid Build Coastguard Worker 
1397*08b48e0bSAndroid Build Coastguard Worker         uint32_t vector_cur = 0;
1398*08b48e0bSAndroid Build Coastguard Worker         /* Load SHM pointer */
1399*08b48e0bSAndroid Build Coastguard Worker         LoadInst *MapPtr =
1400*08b48e0bSAndroid Build Coastguard Worker             IRB.CreateLoad(PointerType::get(Int8Ty, 0), AFLMapPtr);
1401*08b48e0bSAndroid Build Coastguard Worker         ModuleSanitizerCoverageLTO::SetNoSanitizeMetadata(MapPtr);
1402*08b48e0bSAndroid Build Coastguard Worker 
1403*08b48e0bSAndroid Build Coastguard Worker         while (1) {
1404*08b48e0bSAndroid Build Coastguard Worker 
1405*08b48e0bSAndroid Build Coastguard Worker           /* Get CurLoc */
1406*08b48e0bSAndroid Build Coastguard Worker           Value *MapPtrIdx = nullptr;
1407*08b48e0bSAndroid Build Coastguard Worker 
1408*08b48e0bSAndroid Build Coastguard Worker           /* Load counter for CurLoc */
1409*08b48e0bSAndroid Build Coastguard Worker           if (!vector_cnt) {
1410*08b48e0bSAndroid Build Coastguard Worker 
1411*08b48e0bSAndroid Build Coastguard Worker             MapPtrIdx = IRB.CreateGEP(Int8Ty, MapPtr, result);
1412*08b48e0bSAndroid Build Coastguard Worker 
1413*08b48e0bSAndroid Build Coastguard Worker           } else {
1414*08b48e0bSAndroid Build Coastguard Worker 
1415*08b48e0bSAndroid Build Coastguard Worker             auto element = IRB.CreateExtractElement(result, vector_cur++);
1416*08b48e0bSAndroid Build Coastguard Worker             MapPtrIdx = IRB.CreateGEP(Int8Ty, MapPtr, element);
1417*08b48e0bSAndroid Build Coastguard Worker 
1418*08b48e0bSAndroid Build Coastguard Worker           }
1419*08b48e0bSAndroid Build Coastguard Worker 
1420*08b48e0bSAndroid Build Coastguard Worker           if (use_threadsafe_counters) {
1421*08b48e0bSAndroid Build Coastguard Worker 
1422*08b48e0bSAndroid Build Coastguard Worker             IRB.CreateAtomicRMW(llvm::AtomicRMWInst::BinOp::Add, MapPtrIdx, One,
1423*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 13
1424*08b48e0bSAndroid Build Coastguard Worker                                 llvm::MaybeAlign(1),
1425*08b48e0bSAndroid Build Coastguard Worker #endif
1426*08b48e0bSAndroid Build Coastguard Worker                                 llvm::AtomicOrdering::Monotonic);
1427*08b48e0bSAndroid Build Coastguard Worker 
1428*08b48e0bSAndroid Build Coastguard Worker           } else {
1429*08b48e0bSAndroid Build Coastguard Worker 
1430*08b48e0bSAndroid Build Coastguard Worker             LoadInst *Counter = IRB.CreateLoad(IRB.getInt8Ty(), MapPtrIdx);
1431*08b48e0bSAndroid Build Coastguard Worker             ModuleSanitizerCoverageLTO::SetNoSanitizeMetadata(Counter);
1432*08b48e0bSAndroid Build Coastguard Worker 
1433*08b48e0bSAndroid Build Coastguard Worker             /* Update bitmap */
1434*08b48e0bSAndroid Build Coastguard Worker 
1435*08b48e0bSAndroid Build Coastguard Worker             Value *Incr = IRB.CreateAdd(Counter, One);
1436*08b48e0bSAndroid Build Coastguard Worker 
1437*08b48e0bSAndroid Build Coastguard Worker             if (skip_nozero == NULL) {
1438*08b48e0bSAndroid Build Coastguard Worker 
1439*08b48e0bSAndroid Build Coastguard Worker               auto cf = IRB.CreateICmpEQ(Incr, Zero);
1440*08b48e0bSAndroid Build Coastguard Worker               auto carry = IRB.CreateZExt(cf, Int8Ty);
1441*08b48e0bSAndroid Build Coastguard Worker               Incr = IRB.CreateAdd(Incr, carry);
1442*08b48e0bSAndroid Build Coastguard Worker 
1443*08b48e0bSAndroid Build Coastguard Worker             }
1444*08b48e0bSAndroid Build Coastguard Worker 
1445*08b48e0bSAndroid Build Coastguard Worker             auto nosan = IRB.CreateStore(Incr, MapPtrIdx);
1446*08b48e0bSAndroid Build Coastguard Worker             ModuleSanitizerCoverageLTO::SetNoSanitizeMetadata(nosan);
1447*08b48e0bSAndroid Build Coastguard Worker 
1448*08b48e0bSAndroid Build Coastguard Worker           }
1449*08b48e0bSAndroid Build Coastguard Worker 
1450*08b48e0bSAndroid Build Coastguard Worker           if (!vector_cnt || vector_cnt == vector_cur) { break; }
1451*08b48e0bSAndroid Build Coastguard Worker 
1452*08b48e0bSAndroid Build Coastguard Worker         }
1453*08b48e0bSAndroid Build Coastguard Worker 
1454*08b48e0bSAndroid Build Coastguard Worker         skip_next = 1;
1455*08b48e0bSAndroid Build Coastguard Worker 
1456*08b48e0bSAndroid Build Coastguard Worker       } else {
1457*08b48e0bSAndroid Build Coastguard Worker 
1458*08b48e0bSAndroid Build Coastguard Worker         skip_next = 0;
1459*08b48e0bSAndroid Build Coastguard Worker 
1460*08b48e0bSAndroid Build Coastguard Worker       }
1461*08b48e0bSAndroid Build Coastguard Worker 
1462*08b48e0bSAndroid Build Coastguard Worker     }
1463*08b48e0bSAndroid Build Coastguard Worker 
1464*08b48e0bSAndroid Build Coastguard Worker     if (shouldInstrumentBlock(F, &BB, DT, PDT, Options))
1465*08b48e0bSAndroid Build Coastguard Worker       BlocksToInstrument.push_back(&BB);
1466*08b48e0bSAndroid Build Coastguard Worker     for (auto &Inst : BB) {
1467*08b48e0bSAndroid Build Coastguard Worker 
1468*08b48e0bSAndroid Build Coastguard Worker       if (Options.IndirectCalls) {
1469*08b48e0bSAndroid Build Coastguard Worker 
1470*08b48e0bSAndroid Build Coastguard Worker         CallBase *CB = dyn_cast<CallBase>(&Inst);
1471*08b48e0bSAndroid Build Coastguard Worker         if (CB && !CB->getCalledFunction()) IndirCalls.push_back(&Inst);
1472*08b48e0bSAndroid Build Coastguard Worker 
1473*08b48e0bSAndroid Build Coastguard Worker       }
1474*08b48e0bSAndroid Build Coastguard Worker 
1475*08b48e0bSAndroid Build Coastguard Worker     }
1476*08b48e0bSAndroid Build Coastguard Worker 
1477*08b48e0bSAndroid Build Coastguard Worker   }
1478*08b48e0bSAndroid Build Coastguard Worker 
1479*08b48e0bSAndroid Build Coastguard Worker   InjectCoverage(F, BlocksToInstrument, IsLeafFunc);
1480*08b48e0bSAndroid Build Coastguard Worker   InjectCoverageForIndirectCalls(F, IndirCalls);
1481*08b48e0bSAndroid Build Coastguard Worker 
1482*08b48e0bSAndroid Build Coastguard Worker }
1483*08b48e0bSAndroid Build Coastguard Worker 
CreateFunctionLocalArrayInSection(size_t NumElements,Function & F,Type * Ty,const char * Section)1484*08b48e0bSAndroid Build Coastguard Worker GlobalVariable *ModuleSanitizerCoverageLTO::CreateFunctionLocalArrayInSection(
1485*08b48e0bSAndroid Build Coastguard Worker     size_t NumElements, Function &F, Type *Ty, const char *Section) {
1486*08b48e0bSAndroid Build Coastguard Worker 
1487*08b48e0bSAndroid Build Coastguard Worker   ArrayType *ArrayTy = ArrayType::get(Ty, NumElements);
1488*08b48e0bSAndroid Build Coastguard Worker   auto       Array = new GlobalVariable(
1489*08b48e0bSAndroid Build Coastguard Worker       *CurModule, ArrayTy, false, GlobalVariable::PrivateLinkage,
1490*08b48e0bSAndroid Build Coastguard Worker       Constant::getNullValue(ArrayTy), "__sancov_gen_");
1491*08b48e0bSAndroid Build Coastguard Worker 
1492*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 13
1493*08b48e0bSAndroid Build Coastguard Worker   if (TargetTriple.supportsCOMDAT() &&
1494*08b48e0bSAndroid Build Coastguard Worker       (TargetTriple.isOSBinFormatELF() || !F.isInterposable()))
1495*08b48e0bSAndroid Build Coastguard Worker     if (auto Comdat = getOrCreateFunctionComdat(F, TargetTriple))
1496*08b48e0bSAndroid Build Coastguard Worker       Array->setComdat(Comdat);
1497*08b48e0bSAndroid Build Coastguard Worker #else
1498*08b48e0bSAndroid Build Coastguard Worker   if (TargetTriple.supportsCOMDAT() && !F.isInterposable())
1499*08b48e0bSAndroid Build Coastguard Worker     if (auto Comdat =
1500*08b48e0bSAndroid Build Coastguard Worker             GetOrCreateFunctionComdat(F, TargetTriple, CurModuleUniqueId))
1501*08b48e0bSAndroid Build Coastguard Worker       Array->setComdat(Comdat);
1502*08b48e0bSAndroid Build Coastguard Worker #endif
1503*08b48e0bSAndroid Build Coastguard Worker   Array->setSection(getSectionName(Section));
1504*08b48e0bSAndroid Build Coastguard Worker   Array->setAlignment(Align(DL->getTypeStoreSize(Ty).getFixedValue()));
1505*08b48e0bSAndroid Build Coastguard Worker   GlobalsToAppendToUsed.push_back(Array);
1506*08b48e0bSAndroid Build Coastguard Worker   GlobalsToAppendToCompilerUsed.push_back(Array);
1507*08b48e0bSAndroid Build Coastguard Worker   MDNode *MD = MDNode::get(F.getContext(), ValueAsMetadata::get(&F));
1508*08b48e0bSAndroid Build Coastguard Worker   Array->addMetadata(LLVMContext::MD_associated, *MD);
1509*08b48e0bSAndroid Build Coastguard Worker 
1510*08b48e0bSAndroid Build Coastguard Worker   return Array;
1511*08b48e0bSAndroid Build Coastguard Worker 
1512*08b48e0bSAndroid Build Coastguard Worker }
1513*08b48e0bSAndroid Build Coastguard Worker 
CreatePCArray(Function & F,ArrayRef<BasicBlock * > AllBlocks)1514*08b48e0bSAndroid Build Coastguard Worker GlobalVariable *ModuleSanitizerCoverageLTO::CreatePCArray(
1515*08b48e0bSAndroid Build Coastguard Worker     Function &F, ArrayRef<BasicBlock *> AllBlocks) {
1516*08b48e0bSAndroid Build Coastguard Worker 
1517*08b48e0bSAndroid Build Coastguard Worker   size_t N = AllBlocks.size();
1518*08b48e0bSAndroid Build Coastguard Worker   assert(N);
1519*08b48e0bSAndroid Build Coastguard Worker   SmallVector<Constant *, 32> PCs;
1520*08b48e0bSAndroid Build Coastguard Worker   IRBuilder<>                 IRB(&*F.getEntryBlock().getFirstInsertionPt());
1521*08b48e0bSAndroid Build Coastguard Worker   for (size_t i = 0; i < N; i++) {
1522*08b48e0bSAndroid Build Coastguard Worker 
1523*08b48e0bSAndroid Build Coastguard Worker     if (&F.getEntryBlock() == AllBlocks[i]) {
1524*08b48e0bSAndroid Build Coastguard Worker 
1525*08b48e0bSAndroid Build Coastguard Worker       PCs.push_back((Constant *)IRB.CreatePointerCast(&F, IntptrPtrTy));
1526*08b48e0bSAndroid Build Coastguard Worker       PCs.push_back((Constant *)IRB.CreateIntToPtr(
1527*08b48e0bSAndroid Build Coastguard Worker           ConstantInt::get(IntptrTy, 1), IntptrPtrTy));
1528*08b48e0bSAndroid Build Coastguard Worker 
1529*08b48e0bSAndroid Build Coastguard Worker     } else {
1530*08b48e0bSAndroid Build Coastguard Worker 
1531*08b48e0bSAndroid Build Coastguard Worker       PCs.push_back((Constant *)IRB.CreatePointerCast(
1532*08b48e0bSAndroid Build Coastguard Worker           BlockAddress::get(AllBlocks[i]), IntptrPtrTy));
1533*08b48e0bSAndroid Build Coastguard Worker       PCs.push_back((Constant *)IRB.CreateIntToPtr(
1534*08b48e0bSAndroid Build Coastguard Worker           ConstantInt::get(IntptrTy, 0), IntptrPtrTy));
1535*08b48e0bSAndroid Build Coastguard Worker 
1536*08b48e0bSAndroid Build Coastguard Worker     }
1537*08b48e0bSAndroid Build Coastguard Worker 
1538*08b48e0bSAndroid Build Coastguard Worker   }
1539*08b48e0bSAndroid Build Coastguard Worker 
1540*08b48e0bSAndroid Build Coastguard Worker   auto *PCArray = CreateFunctionLocalArrayInSection(N * 2, F, IntptrPtrTy,
1541*08b48e0bSAndroid Build Coastguard Worker                                                     SanCovPCsSectionName);
1542*08b48e0bSAndroid Build Coastguard Worker   PCArray->setInitializer(
1543*08b48e0bSAndroid Build Coastguard Worker       ConstantArray::get(ArrayType::get(IntptrPtrTy, N * 2), PCs));
1544*08b48e0bSAndroid Build Coastguard Worker   PCArray->setConstant(true);
1545*08b48e0bSAndroid Build Coastguard Worker 
1546*08b48e0bSAndroid Build Coastguard Worker   return PCArray;
1547*08b48e0bSAndroid Build Coastguard Worker 
1548*08b48e0bSAndroid Build Coastguard Worker }
1549*08b48e0bSAndroid Build Coastguard Worker 
CreateFunctionLocalArrays(Function & F,ArrayRef<BasicBlock * > AllBlocks)1550*08b48e0bSAndroid Build Coastguard Worker void ModuleSanitizerCoverageLTO::CreateFunctionLocalArrays(
1551*08b48e0bSAndroid Build Coastguard Worker     Function &F, ArrayRef<BasicBlock *> AllBlocks) {
1552*08b48e0bSAndroid Build Coastguard Worker 
1553*08b48e0bSAndroid Build Coastguard Worker   if (Options.TracePCGuard)
1554*08b48e0bSAndroid Build Coastguard Worker     FunctionGuardArray = CreateFunctionLocalArrayInSection(
1555*08b48e0bSAndroid Build Coastguard Worker         AllBlocks.size(), F, Int32Ty, SanCovGuardsSectionName);
1556*08b48e0bSAndroid Build Coastguard Worker   if (Options.Inline8bitCounters)
1557*08b48e0bSAndroid Build Coastguard Worker     Function8bitCounterArray = CreateFunctionLocalArrayInSection(
1558*08b48e0bSAndroid Build Coastguard Worker         AllBlocks.size(), F, Int8Ty, SanCovCountersSectionName);
1559*08b48e0bSAndroid Build Coastguard Worker   if (Options.InlineBoolFlag)
1560*08b48e0bSAndroid Build Coastguard Worker     FunctionBoolArray = CreateFunctionLocalArrayInSection(
1561*08b48e0bSAndroid Build Coastguard Worker         AllBlocks.size(), F, Int1Ty, SanCovBoolFlagSectionName);
1562*08b48e0bSAndroid Build Coastguard Worker   if (Options.PCTable) FunctionPCsArray = CreatePCArray(F, AllBlocks);
1563*08b48e0bSAndroid Build Coastguard Worker 
1564*08b48e0bSAndroid Build Coastguard Worker }
1565*08b48e0bSAndroid Build Coastguard Worker 
InjectCoverage(Function & F,ArrayRef<BasicBlock * > AllBlocks,bool IsLeafFunc)1566*08b48e0bSAndroid Build Coastguard Worker bool ModuleSanitizerCoverageLTO::InjectCoverage(
1567*08b48e0bSAndroid Build Coastguard Worker     Function &F, ArrayRef<BasicBlock *> AllBlocks, bool IsLeafFunc) {
1568*08b48e0bSAndroid Build Coastguard Worker 
1569*08b48e0bSAndroid Build Coastguard Worker   if (AllBlocks.empty()) return false;
1570*08b48e0bSAndroid Build Coastguard Worker   CreateFunctionLocalArrays(F, AllBlocks);
1571*08b48e0bSAndroid Build Coastguard Worker 
1572*08b48e0bSAndroid Build Coastguard Worker   for (size_t i = 0, N = AllBlocks.size(); i < N; i++) {
1573*08b48e0bSAndroid Build Coastguard Worker 
1574*08b48e0bSAndroid Build Coastguard Worker     // AFL++ START
1575*08b48e0bSAndroid Build Coastguard Worker     if (BlockList.size()) {
1576*08b48e0bSAndroid Build Coastguard Worker 
1577*08b48e0bSAndroid Build Coastguard Worker       int skip = 0;
1578*08b48e0bSAndroid Build Coastguard Worker       for (uint32_t k = 0; k < BlockList.size(); k++) {
1579*08b48e0bSAndroid Build Coastguard Worker 
1580*08b48e0bSAndroid Build Coastguard Worker         if (AllBlocks[i] == BlockList[k]) {
1581*08b48e0bSAndroid Build Coastguard Worker 
1582*08b48e0bSAndroid Build Coastguard Worker           if (debug)
1583*08b48e0bSAndroid Build Coastguard Worker             fprintf(stderr,
1584*08b48e0bSAndroid Build Coastguard Worker                     "DEBUG: Function %s skipping BB with/after __afl_loop\n",
1585*08b48e0bSAndroid Build Coastguard Worker                     F.getName().str().c_str());
1586*08b48e0bSAndroid Build Coastguard Worker           skip = 1;
1587*08b48e0bSAndroid Build Coastguard Worker 
1588*08b48e0bSAndroid Build Coastguard Worker         }
1589*08b48e0bSAndroid Build Coastguard Worker 
1590*08b48e0bSAndroid Build Coastguard Worker       }
1591*08b48e0bSAndroid Build Coastguard Worker 
1592*08b48e0bSAndroid Build Coastguard Worker       if (skip) continue;
1593*08b48e0bSAndroid Build Coastguard Worker 
1594*08b48e0bSAndroid Build Coastguard Worker     }
1595*08b48e0bSAndroid Build Coastguard Worker 
1596*08b48e0bSAndroid Build Coastguard Worker     // AFL++ END
1597*08b48e0bSAndroid Build Coastguard Worker 
1598*08b48e0bSAndroid Build Coastguard Worker     InjectCoverageAtBlock(F, *AllBlocks[i], i, IsLeafFunc);
1599*08b48e0bSAndroid Build Coastguard Worker 
1600*08b48e0bSAndroid Build Coastguard Worker   }
1601*08b48e0bSAndroid Build Coastguard Worker 
1602*08b48e0bSAndroid Build Coastguard Worker   return true;
1603*08b48e0bSAndroid Build Coastguard Worker 
1604*08b48e0bSAndroid Build Coastguard Worker }
1605*08b48e0bSAndroid Build Coastguard Worker 
1606*08b48e0bSAndroid Build Coastguard Worker // On every indirect call we call a run-time function
1607*08b48e0bSAndroid Build Coastguard Worker // __sanitizer_cov_indir_call* with two parameters:
1608*08b48e0bSAndroid Build Coastguard Worker //   - callee address,
1609*08b48e0bSAndroid Build Coastguard Worker //   - global cache array that contains CacheSize pointers (zero-initialized).
1610*08b48e0bSAndroid Build Coastguard Worker //     The cache is used to speed up recording the caller-callee pairs.
1611*08b48e0bSAndroid Build Coastguard Worker // The address of the caller is passed implicitly via caller PC.
1612*08b48e0bSAndroid Build Coastguard Worker // CacheSize is encoded in the name of the run-time function.
InjectCoverageForIndirectCalls(Function & F,ArrayRef<Instruction * > IndirCalls)1613*08b48e0bSAndroid Build Coastguard Worker void ModuleSanitizerCoverageLTO::InjectCoverageForIndirectCalls(
1614*08b48e0bSAndroid Build Coastguard Worker     Function &F, ArrayRef<Instruction *> IndirCalls) {
1615*08b48e0bSAndroid Build Coastguard Worker 
1616*08b48e0bSAndroid Build Coastguard Worker   if (IndirCalls.empty()) return;
1617*08b48e0bSAndroid Build Coastguard Worker   assert(Options.TracePC || Options.TracePCGuard ||
1618*08b48e0bSAndroid Build Coastguard Worker          Options.Inline8bitCounters || Options.InlineBoolFlag);
1619*08b48e0bSAndroid Build Coastguard Worker   for (auto I : IndirCalls) {
1620*08b48e0bSAndroid Build Coastguard Worker 
1621*08b48e0bSAndroid Build Coastguard Worker     IRBuilder<> IRB(I);
1622*08b48e0bSAndroid Build Coastguard Worker     CallBase   &CB = cast<CallBase>(*I);
1623*08b48e0bSAndroid Build Coastguard Worker     Value      *Callee = CB.getCalledOperand();
1624*08b48e0bSAndroid Build Coastguard Worker     if (isa<InlineAsm>(Callee)) continue;
1625*08b48e0bSAndroid Build Coastguard Worker     IRB.CreateCall(SanCovTracePCIndir, IRB.CreatePointerCast(Callee, IntptrTy));
1626*08b48e0bSAndroid Build Coastguard Worker 
1627*08b48e0bSAndroid Build Coastguard Worker   }
1628*08b48e0bSAndroid Build Coastguard Worker 
1629*08b48e0bSAndroid Build Coastguard Worker }
1630*08b48e0bSAndroid Build Coastguard Worker 
InjectCoverageAtBlock(Function & F,BasicBlock & BB,size_t Idx,bool IsLeafFunc)1631*08b48e0bSAndroid Build Coastguard Worker void ModuleSanitizerCoverageLTO::InjectCoverageAtBlock(Function   &F,
1632*08b48e0bSAndroid Build Coastguard Worker                                                        BasicBlock &BB,
1633*08b48e0bSAndroid Build Coastguard Worker                                                        size_t      Idx,
1634*08b48e0bSAndroid Build Coastguard Worker                                                        bool        IsLeafFunc) {
1635*08b48e0bSAndroid Build Coastguard Worker 
1636*08b48e0bSAndroid Build Coastguard Worker   BasicBlock::iterator IP = BB.getFirstInsertionPt();
1637*08b48e0bSAndroid Build Coastguard Worker   bool                 IsEntryBB = &BB == &F.getEntryBlock();
1638*08b48e0bSAndroid Build Coastguard Worker 
1639*08b48e0bSAndroid Build Coastguard Worker   if (IsEntryBB) {
1640*08b48e0bSAndroid Build Coastguard Worker 
1641*08b48e0bSAndroid Build Coastguard Worker     // Keep static allocas and llvm.localescape calls in the entry block.  Even
1642*08b48e0bSAndroid Build Coastguard Worker     // if we aren't splitting the block, it's nice for allocas to be before
1643*08b48e0bSAndroid Build Coastguard Worker     // calls.
1644*08b48e0bSAndroid Build Coastguard Worker     IP = PrepareToSplitEntryBlock(BB, IP);
1645*08b48e0bSAndroid Build Coastguard Worker 
1646*08b48e0bSAndroid Build Coastguard Worker   }
1647*08b48e0bSAndroid Build Coastguard Worker 
1648*08b48e0bSAndroid Build Coastguard Worker   IRBuilder<> IRB(&*IP);
1649*08b48e0bSAndroid Build Coastguard Worker   if (Options.TracePC) {
1650*08b48e0bSAndroid Build Coastguard Worker 
1651*08b48e0bSAndroid Build Coastguard Worker     IRB.CreateCall(SanCovTracePC)
1652*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 12
1653*08b48e0bSAndroid Build Coastguard Worker         ->setCannotMerge();  // gets the PC using GET_CALLER_PC.
1654*08b48e0bSAndroid Build Coastguard Worker #else
1655*08b48e0bSAndroid Build Coastguard Worker         ->cannotMerge();  // gets the PC using GET_CALLER_PC.
1656*08b48e0bSAndroid Build Coastguard Worker #endif
1657*08b48e0bSAndroid Build Coastguard Worker 
1658*08b48e0bSAndroid Build Coastguard Worker   }
1659*08b48e0bSAndroid Build Coastguard Worker 
1660*08b48e0bSAndroid Build Coastguard Worker   if (Options.TracePCGuard) {
1661*08b48e0bSAndroid Build Coastguard Worker 
1662*08b48e0bSAndroid Build Coastguard Worker     // AFL++ START
1663*08b48e0bSAndroid Build Coastguard Worker     ++afl_global_id;
1664*08b48e0bSAndroid Build Coastguard Worker 
1665*08b48e0bSAndroid Build Coastguard Worker     if (dFile.is_open()) {
1666*08b48e0bSAndroid Build Coastguard Worker 
1667*08b48e0bSAndroid Build Coastguard Worker       unsigned long long int moduleID =
1668*08b48e0bSAndroid Build Coastguard Worker           (((unsigned long long int)(rand() & 0xffffffff)) << 32) | getpid();
1669*08b48e0bSAndroid Build Coastguard Worker       dFile << "ModuleID=" << moduleID << " Function=" << F.getName().str()
1670*08b48e0bSAndroid Build Coastguard Worker             << " edgeID=" << afl_global_id << "\n";
1671*08b48e0bSAndroid Build Coastguard Worker 
1672*08b48e0bSAndroid Build Coastguard Worker     }
1673*08b48e0bSAndroid Build Coastguard Worker 
1674*08b48e0bSAndroid Build Coastguard Worker     /* Set the ID of the inserted basic block */
1675*08b48e0bSAndroid Build Coastguard Worker 
1676*08b48e0bSAndroid Build Coastguard Worker     ConstantInt *CurLoc = ConstantInt::get(Int32Tyi, afl_global_id);
1677*08b48e0bSAndroid Build Coastguard Worker 
1678*08b48e0bSAndroid Build Coastguard Worker     /* Load SHM pointer */
1679*08b48e0bSAndroid Build Coastguard Worker 
1680*08b48e0bSAndroid Build Coastguard Worker     Value *MapPtrIdx;
1681*08b48e0bSAndroid Build Coastguard Worker 
1682*08b48e0bSAndroid Build Coastguard Worker     if (map_addr) {
1683*08b48e0bSAndroid Build Coastguard Worker 
1684*08b48e0bSAndroid Build Coastguard Worker       MapPtrIdx = IRB.CreateGEP(Int8Ty, MapPtrFixed, CurLoc);
1685*08b48e0bSAndroid Build Coastguard Worker 
1686*08b48e0bSAndroid Build Coastguard Worker     } else {
1687*08b48e0bSAndroid Build Coastguard Worker 
1688*08b48e0bSAndroid Build Coastguard Worker       LoadInst *MapPtr = IRB.CreateLoad(PointerType::get(Int8Ty, 0), AFLMapPtr);
1689*08b48e0bSAndroid Build Coastguard Worker       ModuleSanitizerCoverageLTO::SetNoSanitizeMetadata(MapPtr);
1690*08b48e0bSAndroid Build Coastguard Worker       MapPtrIdx = IRB.CreateGEP(Int8Ty, MapPtr, CurLoc);
1691*08b48e0bSAndroid Build Coastguard Worker 
1692*08b48e0bSAndroid Build Coastguard Worker     }
1693*08b48e0bSAndroid Build Coastguard Worker 
1694*08b48e0bSAndroid Build Coastguard Worker     /* Update bitmap */
1695*08b48e0bSAndroid Build Coastguard Worker     if (use_threadsafe_counters) {                                /* Atomic */
1696*08b48e0bSAndroid Build Coastguard Worker 
1697*08b48e0bSAndroid Build Coastguard Worker       IRB.CreateAtomicRMW(llvm::AtomicRMWInst::BinOp::Add, MapPtrIdx, One,
1698*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 13
1699*08b48e0bSAndroid Build Coastguard Worker                           llvm::MaybeAlign(1),
1700*08b48e0bSAndroid Build Coastguard Worker #endif
1701*08b48e0bSAndroid Build Coastguard Worker                           llvm::AtomicOrdering::Monotonic);
1702*08b48e0bSAndroid Build Coastguard Worker 
1703*08b48e0bSAndroid Build Coastguard Worker     } else {
1704*08b48e0bSAndroid Build Coastguard Worker 
1705*08b48e0bSAndroid Build Coastguard Worker       LoadInst *Counter = IRB.CreateLoad(IRB.getInt8Ty(), MapPtrIdx);
1706*08b48e0bSAndroid Build Coastguard Worker       ModuleSanitizerCoverageLTO::SetNoSanitizeMetadata(Counter);
1707*08b48e0bSAndroid Build Coastguard Worker 
1708*08b48e0bSAndroid Build Coastguard Worker       Value *Incr = IRB.CreateAdd(Counter, One);
1709*08b48e0bSAndroid Build Coastguard Worker 
1710*08b48e0bSAndroid Build Coastguard Worker       if (skip_nozero == NULL) {
1711*08b48e0bSAndroid Build Coastguard Worker 
1712*08b48e0bSAndroid Build Coastguard Worker         auto cf = IRB.CreateICmpEQ(Incr, Zero);
1713*08b48e0bSAndroid Build Coastguard Worker         auto carry = IRB.CreateZExt(cf, Int8Tyi);
1714*08b48e0bSAndroid Build Coastguard Worker         Incr = IRB.CreateAdd(Incr, carry);
1715*08b48e0bSAndroid Build Coastguard Worker 
1716*08b48e0bSAndroid Build Coastguard Worker       }
1717*08b48e0bSAndroid Build Coastguard Worker 
1718*08b48e0bSAndroid Build Coastguard Worker       auto nosan = IRB.CreateStore(Incr, MapPtrIdx);
1719*08b48e0bSAndroid Build Coastguard Worker       ModuleSanitizerCoverageLTO::SetNoSanitizeMetadata(nosan);
1720*08b48e0bSAndroid Build Coastguard Worker 
1721*08b48e0bSAndroid Build Coastguard Worker     }
1722*08b48e0bSAndroid Build Coastguard Worker 
1723*08b48e0bSAndroid Build Coastguard Worker     // done :)
1724*08b48e0bSAndroid Build Coastguard Worker 
1725*08b48e0bSAndroid Build Coastguard Worker     inst++;
1726*08b48e0bSAndroid Build Coastguard Worker     // AFL++ END
1727*08b48e0bSAndroid Build Coastguard Worker 
1728*08b48e0bSAndroid Build Coastguard Worker     /*
1729*08b48e0bSAndroid Build Coastguard Worker     XXXXXXXXXXXXXXXXXXX
1730*08b48e0bSAndroid Build Coastguard Worker 
1731*08b48e0bSAndroid Build Coastguard Worker         auto GuardPtr = IRB.CreateIntToPtr(
1732*08b48e0bSAndroid Build Coastguard Worker             IRB.CreateAdd(IRB.CreatePointerCast(FunctionGuardArray, IntptrTy),
1733*08b48e0bSAndroid Build Coastguard Worker                           ConstantInt::get(IntptrTy, Idx * 4)),
1734*08b48e0bSAndroid Build Coastguard Worker             Int32PtrTy);
1735*08b48e0bSAndroid Build Coastguard Worker 
1736*08b48e0bSAndroid Build Coastguard Worker         IRB.CreateCall(SanCovTracePCGuard, GuardPtr)->setCannotMerge();
1737*08b48e0bSAndroid Build Coastguard Worker     */
1738*08b48e0bSAndroid Build Coastguard Worker 
1739*08b48e0bSAndroid Build Coastguard Worker   }
1740*08b48e0bSAndroid Build Coastguard Worker 
1741*08b48e0bSAndroid Build Coastguard Worker   if (Options.Inline8bitCounters) {
1742*08b48e0bSAndroid Build Coastguard Worker 
1743*08b48e0bSAndroid Build Coastguard Worker     auto CounterPtr = IRB.CreateGEP(
1744*08b48e0bSAndroid Build Coastguard Worker         Function8bitCounterArray->getValueType(), Function8bitCounterArray,
1745*08b48e0bSAndroid Build Coastguard Worker         {ConstantInt::get(IntptrTy, 0), ConstantInt::get(IntptrTy, Idx)});
1746*08b48e0bSAndroid Build Coastguard Worker     auto Load = IRB.CreateLoad(Int8Ty, CounterPtr);
1747*08b48e0bSAndroid Build Coastguard Worker     auto Inc = IRB.CreateAdd(Load, ConstantInt::get(Int8Ty, 1));
1748*08b48e0bSAndroid Build Coastguard Worker     auto Store = IRB.CreateStore(Inc, CounterPtr);
1749*08b48e0bSAndroid Build Coastguard Worker     SetNoSanitizeMetadata(Load);
1750*08b48e0bSAndroid Build Coastguard Worker     SetNoSanitizeMetadata(Store);
1751*08b48e0bSAndroid Build Coastguard Worker 
1752*08b48e0bSAndroid Build Coastguard Worker   }
1753*08b48e0bSAndroid Build Coastguard Worker 
1754*08b48e0bSAndroid Build Coastguard Worker   if (Options.InlineBoolFlag) {
1755*08b48e0bSAndroid Build Coastguard Worker 
1756*08b48e0bSAndroid Build Coastguard Worker     auto FlagPtr = IRB.CreateGEP(
1757*08b48e0bSAndroid Build Coastguard Worker         FunctionBoolArray->getValueType(), FunctionBoolArray,
1758*08b48e0bSAndroid Build Coastguard Worker         {ConstantInt::get(IntptrTy, 0), ConstantInt::get(IntptrTy, Idx)});
1759*08b48e0bSAndroid Build Coastguard Worker     auto Load = IRB.CreateLoad(Int1Ty, FlagPtr);
1760*08b48e0bSAndroid Build Coastguard Worker     auto ThenTerm =
1761*08b48e0bSAndroid Build Coastguard Worker         SplitBlockAndInsertIfThen(IRB.CreateIsNull(Load), &*IP, false);
1762*08b48e0bSAndroid Build Coastguard Worker     IRBuilder<> ThenIRB(ThenTerm);
1763*08b48e0bSAndroid Build Coastguard Worker     auto Store = ThenIRB.CreateStore(ConstantInt::getTrue(Int1Ty), FlagPtr);
1764*08b48e0bSAndroid Build Coastguard Worker     SetNoSanitizeMetadata(Load);
1765*08b48e0bSAndroid Build Coastguard Worker     SetNoSanitizeMetadata(Store);
1766*08b48e0bSAndroid Build Coastguard Worker 
1767*08b48e0bSAndroid Build Coastguard Worker   }
1768*08b48e0bSAndroid Build Coastguard Worker 
1769*08b48e0bSAndroid Build Coastguard Worker }
1770*08b48e0bSAndroid Build Coastguard Worker 
getSectionName(const std::string & Section) const1771*08b48e0bSAndroid Build Coastguard Worker std::string ModuleSanitizerCoverageLTO::getSectionName(
1772*08b48e0bSAndroid Build Coastguard Worker     const std::string &Section) const {
1773*08b48e0bSAndroid Build Coastguard Worker 
1774*08b48e0bSAndroid Build Coastguard Worker   if (TargetTriple.isOSBinFormatCOFF()) {
1775*08b48e0bSAndroid Build Coastguard Worker 
1776*08b48e0bSAndroid Build Coastguard Worker     if (Section == SanCovCountersSectionName) return ".SCOV$CM";
1777*08b48e0bSAndroid Build Coastguard Worker     if (Section == SanCovBoolFlagSectionName) return ".SCOV$BM";
1778*08b48e0bSAndroid Build Coastguard Worker     if (Section == SanCovPCsSectionName) return ".SCOVP$M";
1779*08b48e0bSAndroid Build Coastguard Worker     return ".SCOV$GM";  // For SanCovGuardsSectionName.
1780*08b48e0bSAndroid Build Coastguard Worker 
1781*08b48e0bSAndroid Build Coastguard Worker   }
1782*08b48e0bSAndroid Build Coastguard Worker 
1783*08b48e0bSAndroid Build Coastguard Worker   if (TargetTriple.isOSBinFormatMachO()) return "__DATA,__" + Section;
1784*08b48e0bSAndroid Build Coastguard Worker   return "__" + Section;
1785*08b48e0bSAndroid Build Coastguard Worker 
1786*08b48e0bSAndroid Build Coastguard Worker }
1787*08b48e0bSAndroid Build Coastguard Worker 
1788*08b48e0bSAndroid Build Coastguard Worker char ModuleSanitizerCoverageLTOLegacyPass::ID = 0;
1789*08b48e0bSAndroid Build Coastguard Worker 
1790*08b48e0bSAndroid Build Coastguard Worker INITIALIZE_PASS_BEGIN(ModuleSanitizerCoverageLTOLegacyPass, "sancov-lto",
1791*08b48e0bSAndroid Build Coastguard Worker                       "Pass for instrumenting coverage on functions", false,
1792*08b48e0bSAndroid Build Coastguard Worker                       false)
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)1793*08b48e0bSAndroid Build Coastguard Worker INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
1794*08b48e0bSAndroid Build Coastguard Worker INITIALIZE_PASS_DEPENDENCY(PostDominatorTreeWrapperPass)
1795*08b48e0bSAndroid Build Coastguard Worker INITIALIZE_PASS_END(ModuleSanitizerCoverageLTOLegacyPass, "sancov-lto",
1796*08b48e0bSAndroid Build Coastguard Worker                     "Pass for instrumenting coverage on functions", false,
1797*08b48e0bSAndroid Build Coastguard Worker                     false)
1798*08b48e0bSAndroid Build Coastguard Worker 
1799*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR < 16
1800*08b48e0bSAndroid Build Coastguard Worker static void registerLTOPass(const PassManagerBuilder &,
1801*08b48e0bSAndroid Build Coastguard Worker                             legacy::PassManagerBase &PM) {
1802*08b48e0bSAndroid Build Coastguard Worker 
1803*08b48e0bSAndroid Build Coastguard Worker   auto p = new ModuleSanitizerCoverageLTOLegacyPass();
1804*08b48e0bSAndroid Build Coastguard Worker   PM.add(p);
1805*08b48e0bSAndroid Build Coastguard Worker 
1806*08b48e0bSAndroid Build Coastguard Worker }
1807*08b48e0bSAndroid Build Coastguard Worker 
1808*08b48e0bSAndroid Build Coastguard Worker static RegisterStandardPasses RegisterCompTransPass(
1809*08b48e0bSAndroid Build Coastguard Worker     PassManagerBuilder::EP_OptimizerLast, registerLTOPass);
1810*08b48e0bSAndroid Build Coastguard Worker 
1811*08b48e0bSAndroid Build Coastguard Worker static RegisterStandardPasses RegisterCompTransPass0(
1812*08b48e0bSAndroid Build Coastguard Worker     PassManagerBuilder::EP_EnabledOnOptLevel0, registerLTOPass);
1813*08b48e0bSAndroid Build Coastguard Worker 
1814*08b48e0bSAndroid Build Coastguard Worker   #if LLVM_VERSION_MAJOR >= 11
1815*08b48e0bSAndroid Build Coastguard Worker static RegisterStandardPasses RegisterCompTransPassLTO(
1816*08b48e0bSAndroid Build Coastguard Worker     PassManagerBuilder::EP_FullLinkTimeOptimizationLast, registerLTOPass);
1817*08b48e0bSAndroid Build Coastguard Worker   #endif
1818*08b48e0bSAndroid Build Coastguard Worker #endif
1819*08b48e0bSAndroid Build Coastguard Worker 
1820