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