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