xref: /aosp_15_r20/external/AFLplusplus/instrumentation/afl-llvm-pass.so.cc (revision 08b48e0b10e97b33e7b60c5b6e2243bd915777f2)
1 /*
2    american fuzzy lop++ - LLVM-mode instrumentation pass
3    ---------------------------------------------------
4 
5    Written by Laszlo Szekeres <[email protected]>,
6               Adrian Herrera <[email protected]>,
7               Michal Zalewski
8 
9    LLVM integration design comes from Laszlo Szekeres. C bits copied-and-pasted
10    from afl-as.c are Michal's fault.
11 
12    NGRAM previous location coverage comes from Adrian Herrera.
13 
14    Copyright 2015, 2016 Google Inc. All rights reserved.
15    Copyright 2019-2024 AFLplusplus Project. All rights reserved.
16 
17    Licensed under the Apache License, Version 2.0 (the "License");
18    you may not use this file except in compliance with the License.
19    You may obtain a copy of the License at:
20 
21      https://www.apache.org/licenses/LICENSE-2.0
22 
23    This library is plugged into LLVM when invoking clang through afl-clang-fast.
24    It tells the compiler to add code roughly equivalent to the bits discussed
25    in ../afl-as.h.
26 
27  */
28 
29 #define AFL_LLVM_PASS
30 
31 #include "config.h"
32 #include "debug.h"
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <unistd.h>
36 
37 #include <list>
38 #include <string>
39 #include <fstream>
40 #include <sys/time.h>
41 
42 #include "llvm/Config/llvm-config.h"
43 #if LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR < 5
44 typedef long double max_align_t;
45 #endif
46 
47 #include "llvm/Pass.h"
48 #if LLVM_VERSION_MAJOR >= 11                        /* use new pass manager */
49   #include "llvm/Passes/PassPlugin.h"
50   #include "llvm/Passes/PassBuilder.h"
51   #include "llvm/IR/PassManager.h"
52 #else
53   #include "llvm/IR/LegacyPassManager.h"
54   #include "llvm/Transforms/IPO/PassManagerBuilder.h"
55 #endif
56 #include "llvm/IR/BasicBlock.h"
57 #include "llvm/IR/Module.h"
58 #include "llvm/Support/Debug.h"
59 #include "llvm/Support/MathExtras.h"
60 #if LLVM_VERSION_MAJOR >= 14                /* how about stable interfaces? */
61   #include "llvm/Passes/OptimizationLevel.h"
62 #endif
63 
64 #if LLVM_VERSION_MAJOR >= 4 || \
65     (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR > 4)
66   #include "llvm/IR/DebugInfo.h"
67   #include "llvm/IR/CFG.h"
68 #else
69   #include "llvm/DebugInfo.h"
70   #include "llvm/Support/CFG.h"
71 #endif
72 
73 #include "llvm/IR/IRBuilder.h"
74 
75 #include "afl-llvm-common.h"
76 #include "llvm-alternative-coverage.h"
77 
78 using namespace llvm;
79 
80 namespace {
81 
82 #if LLVM_VERSION_MAJOR >= 11                        /* use new pass manager */
83 class AFLCoverage : public PassInfoMixin<AFLCoverage> {
84 
85  public:
AFLCoverage()86   AFLCoverage() {
87 
88 #else
89 class AFLCoverage : public ModulePass {
90 
91  public:
92   static char ID;
93   AFLCoverage() : ModulePass(ID) {
94 
95 #endif
96 
97     initInstrumentList();
98 
99   }
100 
101 #if LLVM_VERSION_MAJOR >= 11                        /* use new pass manager */
102   PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
103 #else
104   bool runOnModule(Module &M) override;
105 #endif
106 
107  protected:
108   uint32_t    ngram_size = 0;
109   uint32_t    ctx_k = 0;
110   uint32_t    map_size = MAP_SIZE;
111   uint32_t    function_minimum_size = 1;
112   const char *ctx_str = NULL, *caller_str = NULL, *skip_nozero = NULL;
113   const char *use_threadsafe_counters = nullptr;
114 
115 };
116 
117 }  // namespace
118 
119 #if LLVM_VERSION_MAJOR >= 11                        /* use new pass manager */
120 extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK
llvmGetPassPluginInfo()121 llvmGetPassPluginInfo() {
122 
123   return {LLVM_PLUGIN_API_VERSION, "AFLCoverage", "v0.1",
124           /* lambda to insert our pass into the pass pipeline. */
125           [](PassBuilder &PB) {
126 
127   #if 1
128     #if LLVM_VERSION_MAJOR <= 13
129             using OptimizationLevel = typename PassBuilder::OptimizationLevel;
130     #endif
131             PB.registerOptimizerLastEPCallback(
132                 [](ModulePassManager &MPM, OptimizationLevel OL) {
133 
134                   MPM.addPass(AFLCoverage());
135 
136                 });
137 
138   /* TODO LTO registration */
139   #else
140             using PipelineElement = typename PassBuilder::PipelineElement;
141             PB.registerPipelineParsingCallback([](StringRef          Name,
142                                                   ModulePassManager &MPM,
143                                                   ArrayRef<PipelineElement>) {
144 
145               if (Name == "AFLCoverage") {
146 
147                 MPM.addPass(AFLCoverage());
148                 return true;
149 
150               } else {
151 
152                 return false;
153 
154               }
155 
156             });
157 
158   #endif
159 
160           }};
161 
162 }
163 
164 #else
165 
166 char AFLCoverage::ID = 0;
167 #endif
168 
169 /* needed up to 3.9.0 */
170 #if LLVM_VERSION_MAJOR == 3 && \
171     (LLVM_VERSION_MINOR < 9 || \
172      (LLVM_VERSION_MINOR == 9 && LLVM_VERSION_PATCH < 1))
PowerOf2Ceil(unsigned in)173 uint64_t PowerOf2Ceil(unsigned in) {
174 
175   uint64_t in64 = in - 1;
176   in64 |= (in64 >> 1);
177   in64 |= (in64 >> 2);
178   in64 |= (in64 >> 4);
179   in64 |= (in64 >> 8);
180   in64 |= (in64 >> 16);
181   in64 |= (in64 >> 32);
182   return in64 + 1;
183 
184 }
185 
186 #endif
187 
188 /* #if LLVM_VERSION_STRING >= "4.0.1" */
189 #if LLVM_VERSION_MAJOR >= 5 || \
190     (LLVM_VERSION_MAJOR == 4 && LLVM_VERSION_PATCH >= 1)
191   #define AFL_HAVE_VECTOR_INTRINSICS 1
192 #endif
193 
194 #if LLVM_VERSION_MAJOR >= 11                        /* use new pass manager */
run(Module & M,ModuleAnalysisManager & MAM)195 PreservedAnalyses AFLCoverage::run(Module &M, ModuleAnalysisManager &MAM) {
196 
197 #else
198 bool AFLCoverage::runOnModule(Module &M) {
199 
200 #endif
201 
202   LLVMContext &C = M.getContext();
203 
204   IntegerType *Int8Ty = IntegerType::getInt8Ty(C);
205   IntegerType *Int32Ty = IntegerType::getInt32Ty(C);
206 #ifdef AFL_HAVE_VECTOR_INTRINSICS
207   IntegerType *IntLocTy =
208       IntegerType::getIntNTy(C, sizeof(PREV_LOC_T) * CHAR_BIT);
209 #endif
210   struct timeval  tv;
211   struct timezone tz;
212   u32             rand_seed;
213   unsigned int    cur_loc = 0;
214 
215 #if LLVM_VERSION_MAJOR >= 11                        /* use new pass manager */
216   auto PA = PreservedAnalyses::all();
217 #endif
218 
219   /* Setup random() so we get Actually Random(TM) outputs from AFL_R() */
220   gettimeofday(&tv, &tz);
221   rand_seed = tv.tv_sec ^ tv.tv_usec ^ getpid();
222   AFL_SR(rand_seed);
223 
224   /* Show a banner */
225 
226   setvbuf(stdout, NULL, _IONBF, 0);
227 
228   if (getenv("AFL_DEBUG")) debug = 1;
229 
230   if ((isatty(2) && !getenv("AFL_QUIET")) || getenv("AFL_DEBUG") != NULL) {
231 
232     SAYF(cCYA "afl-llvm-pass" VERSION cRST
233               " by <[email protected]> and <[email protected]>\n");
234 
235   } else
236 
237     be_quiet = 1;
238 
239   /*
240     char *ptr;
241     if ((ptr = getenv("AFL_MAP_SIZE")) || (ptr = getenv("AFL_MAPSIZE"))) {
242 
243       map_size = atoi(ptr);
244       if (map_size < 8 || map_size > (1 << 29))
245         FATAL("illegal AFL_MAP_SIZE %u, must be between 2^3 and 2^30",
246     map_size); if (map_size % 8) map_size = (((map_size >> 3) + 1) << 3);
247 
248     }
249 
250   */
251 
252   /* Decide instrumentation ratio */
253 
254   char        *inst_ratio_str = getenv("AFL_INST_RATIO");
255   unsigned int inst_ratio = 100;
256 
257   if (inst_ratio_str) {
258 
259     if (sscanf(inst_ratio_str, "%u", &inst_ratio) != 1 || !inst_ratio ||
260         inst_ratio > 100)
261       FATAL("Bad value of AFL_INST_RATIO (must be between 1 and 100)");
262 
263   }
264 
265 #if LLVM_VERSION_MAJOR < 9
266   char *neverZero_counters_str = getenv("AFL_LLVM_NOT_ZERO");
267 #endif
268   skip_nozero = getenv("AFL_LLVM_SKIP_NEVERZERO");
269   use_threadsafe_counters = getenv("AFL_LLVM_THREADSAFE_INST");
270 
271   if ((isatty(2) && !getenv("AFL_QUIET")) || !!getenv("AFL_DEBUG")) {
272 
273     if (use_threadsafe_counters) {
274 
275       // disabled unless there is support for other modules as well
276       // (increases documentation complexity)
277       /*      if (!getenv("AFL_LLVM_NOT_ZERO")) { */
278 
279       skip_nozero = "1";
280       SAYF(cCYA "afl-llvm-pass" VERSION cRST " using thread safe counters\n");
281 
282       /*
283 
284             } else {
285 
286               SAYF(cCYA "afl-llvm-pass" VERSION cRST
287                         " using thread safe not-zero-counters\n");
288 
289             }
290 
291       */
292 
293     } else {
294 
295       SAYF(cCYA "afl-llvm-pass" VERSION cRST
296                 " using non-thread safe instrumentation\n");
297 
298     }
299 
300   }
301 
302   unsigned PrevLocSize = 0;
303   unsigned PrevCallerSize = 0;
304 
305   char *ngram_size_str = getenv("AFL_LLVM_NGRAM_SIZE");
306   if (!ngram_size_str) ngram_size_str = getenv("AFL_NGRAM_SIZE");
307   char *ctx_k_str = getenv("AFL_LLVM_CTX_K");
308   if (!ctx_k_str) ctx_k_str = getenv("AFL_CTX_K");
309   ctx_str = getenv("AFL_LLVM_CTX");
310   caller_str = getenv("AFL_LLVM_CALLER");
311 
312   bool instrument_ctx = ctx_str || caller_str;
313 
314 #ifdef AFL_HAVE_VECTOR_INTRINSICS
315   /* Decide previous location vector size (must be a power of two) */
316   VectorType *PrevLocTy = NULL;
317 
318   if (ngram_size_str)
319     if (sscanf(ngram_size_str, "%u", &ngram_size) != 1 || ngram_size < 2 ||
320         ngram_size > NGRAM_SIZE_MAX)
321       FATAL(
322           "Bad value of AFL_NGRAM_SIZE (must be between 2 and NGRAM_SIZE_MAX "
323           "(%u))",
324           NGRAM_SIZE_MAX);
325 
326   if (ngram_size == 1) ngram_size = 0;
327   if (ngram_size)
328     PrevLocSize = ngram_size - 1;
329   else
330     PrevLocSize = 1;
331 
332   /* Decide K-ctx vector size (must be a power of two) */
333   VectorType *PrevCallerTy = NULL;
334 
335   if (ctx_k_str)
336     if (sscanf(ctx_k_str, "%u", &ctx_k) != 1 || ctx_k < 1 || ctx_k > CTX_MAX_K)
337       FATAL("Bad value of AFL_CTX_K (must be between 1 and CTX_MAX_K (%u))",
338             CTX_MAX_K);
339 
340   if (ctx_k == 1) {
341 
342     ctx_k = 0;
343     instrument_ctx = true;
344     caller_str = ctx_k_str;  // Enable CALLER instead
345 
346   }
347 
348   if (ctx_k) {
349 
350     PrevCallerSize = ctx_k;
351     instrument_ctx = true;
352 
353   }
354 
355 #else
356   if (ngram_size_str)
357   #ifndef LLVM_VERSION_PATCH
358     FATAL(
359         "Sorry, NGRAM branch coverage is not supported with llvm version "
360         "%d.%d.%d!",
361         LLVM_VERSION_MAJOR, LLVM_VERSION_MINOR, 0);
362   #else
363     FATAL(
364         "Sorry, NGRAM branch coverage is not supported with llvm version "
365         "%d.%d.%d!",
366         LLVM_VERSION_MAJOR, LLVM_VERSION_MINOR, LLVM_VERSION_PATCH);
367   #endif
368   if (ctx_k_str)
369   #ifndef LLVM_VERSION_PATCH
370     FATAL(
371         "Sorry, K-CTX branch coverage is not supported with llvm version "
372         "%d.%d.%d!",
373         LLVM_VERSION_MAJOR, LLVM_VERSION_MINOR, 0);
374   #else
375     FATAL(
376         "Sorry, K-CTX branch coverage is not supported with llvm version "
377         "%d.%d.%d!",
378         LLVM_VERSION_MAJOR, LLVM_VERSION_MINOR, LLVM_VERSION_PATCH);
379   #endif
380   PrevLocSize = 1;
381 #endif
382 
383 #ifdef AFL_HAVE_VECTOR_INTRINSICS
384   int PrevLocVecSize = PowerOf2Ceil(PrevLocSize);
385   if (ngram_size)
386     PrevLocTy = VectorType::get(IntLocTy, PrevLocVecSize
387   #if LLVM_VERSION_MAJOR >= 12
388                                 ,
389                                 false
390   #endif
391     );
392 #endif
393 
394 #ifdef AFL_HAVE_VECTOR_INTRINSICS
395   int PrevCallerVecSize = PowerOf2Ceil(PrevCallerSize);
396   if (ctx_k)
397     PrevCallerTy = VectorType::get(IntLocTy, PrevCallerVecSize
398   #if LLVM_VERSION_MAJOR >= 12
399                                    ,
400                                    false
401   #endif
402     );
403 #endif
404 
405   /* Get globals for the SHM region and the previous location. Note that
406      __afl_prev_loc is thread-local. */
407 
408   GlobalVariable *AFLMapPtr =
409       new GlobalVariable(M, PointerType::get(Int8Ty, 0), false,
410                          GlobalValue::ExternalLinkage, 0, "__afl_area_ptr");
411   GlobalVariable *AFLPrevLoc;
412   GlobalVariable *AFLPrevCaller;
413   GlobalVariable *AFLContext = NULL;
414 
415   if (ctx_str || caller_str)
416 #if defined(__ANDROID__) || defined(__HAIKU__) || defined(NO_TLS)
417     AFLContext = new GlobalVariable(
418         M, Int32Ty, false, GlobalValue::ExternalLinkage, 0, "__afl_prev_ctx");
419 #else
420     AFLContext = new GlobalVariable(
421         M, Int32Ty, false, GlobalValue::ExternalLinkage, 0, "__afl_prev_ctx", 0,
422         GlobalVariable::GeneralDynamicTLSModel, 0, false);
423 #endif
424 
425 #ifdef AFL_HAVE_VECTOR_INTRINSICS
426   if (ngram_size)
427   #if defined(__ANDROID__) || defined(__HAIKU__) || defined(NO_TLS)
428     AFLPrevLoc = new GlobalVariable(
429         M, PrevLocTy, /* isConstant */ false, GlobalValue::ExternalLinkage,
430         /* Initializer */ nullptr, "__afl_prev_loc");
431   #else
432     AFLPrevLoc = new GlobalVariable(
433         M, PrevLocTy, /* isConstant */ false, GlobalValue::ExternalLinkage,
434         /* Initializer */ nullptr, "__afl_prev_loc",
435         /* InsertBefore */ nullptr, GlobalVariable::GeneralDynamicTLSModel,
436         /* AddressSpace */ 0, /* IsExternallyInitialized */ false);
437   #endif
438   else
439 #endif
440 #if defined(__ANDROID__) || defined(__HAIKU__) || defined(NO_TLS)
441     AFLPrevLoc = new GlobalVariable(
442         M, Int32Ty, false, GlobalValue::ExternalLinkage, 0, "__afl_prev_loc");
443 #else
444   AFLPrevLoc = new GlobalVariable(
445       M, Int32Ty, false, GlobalValue::ExternalLinkage, 0, "__afl_prev_loc", 0,
446       GlobalVariable::GeneralDynamicTLSModel, 0, false);
447 #endif
448 
449 #ifdef AFL_HAVE_VECTOR_INTRINSICS
450   if (ctx_k)
451   #if defined(__ANDROID__) || defined(__HAIKU__) || defined(NO_TLS)
452     AFLPrevCaller = new GlobalVariable(
453         M, PrevCallerTy, /* isConstant */ false, GlobalValue::ExternalLinkage,
454         /* Initializer */ nullptr, "__afl_prev_caller");
455   #else
456     AFLPrevCaller = new GlobalVariable(
457         M, PrevCallerTy, /* isConstant */ false, GlobalValue::ExternalLinkage,
458         /* Initializer */ nullptr, "__afl_prev_caller",
459         /* InsertBefore */ nullptr, GlobalVariable::GeneralDynamicTLSModel,
460         /* AddressSpace */ 0, /* IsExternallyInitialized */ false);
461   #endif
462   else
463 #endif
464 #if defined(__ANDROID__) || defined(__HAIKU__) || defined(NO_TLS)
465     AFLPrevCaller =
466         new GlobalVariable(M, Int32Ty, false, GlobalValue::ExternalLinkage, 0,
467                            "__afl_prev_caller");
468 #else
469   AFLPrevCaller = new GlobalVariable(
470       M, Int32Ty, false, GlobalValue::ExternalLinkage, 0, "__afl_prev_caller",
471       0, GlobalVariable::GeneralDynamicTLSModel, 0, false);
472 #endif
473 
474 #ifdef AFL_HAVE_VECTOR_INTRINSICS
475   /* Create the vector shuffle mask for updating the previous block history.
476      Note that the first element of the vector will store cur_loc, so just set
477      it to undef to allow the optimizer to do its thing. */
478 
479   SmallVector<Constant *, 32> PrevLocShuffle = {UndefValue::get(Int32Ty)};
480 
481   for (unsigned I = 0; I < PrevLocSize - 1; ++I)
482     PrevLocShuffle.push_back(ConstantInt::get(Int32Ty, I));
483 
484   for (int I = PrevLocSize; I < PrevLocVecSize; ++I)
485     PrevLocShuffle.push_back(ConstantInt::get(Int32Ty, PrevLocSize));
486 
487   Constant *PrevLocShuffleMask = ConstantVector::get(PrevLocShuffle);
488 
489   Constant                   *PrevCallerShuffleMask = NULL;
490   SmallVector<Constant *, 32> PrevCallerShuffle = {UndefValue::get(Int32Ty)};
491 
492   if (ctx_k) {
493 
494     for (unsigned I = 0; I < PrevCallerSize - 1; ++I)
495       PrevCallerShuffle.push_back(ConstantInt::get(Int32Ty, I));
496 
497     for (int I = PrevCallerSize; I < PrevCallerVecSize; ++I)
498       PrevCallerShuffle.push_back(ConstantInt::get(Int32Ty, PrevCallerSize));
499 
500     PrevCallerShuffleMask = ConstantVector::get(PrevCallerShuffle);
501 
502   }
503 
504 #endif
505 
506   // other constants we need
507   ConstantInt *One = ConstantInt::get(Int8Ty, 1);
508 
509   Value    *PrevCtx = NULL;     // CTX sensitive coverage
510   LoadInst *PrevCaller = NULL;  // K-CTX coverage
511 
512   /* Instrument all the things! */
513 
514   int inst_blocks = 0;
515   scanForDangerousFunctions(&M);
516 
517   for (auto &F : M) {
518 
519     int has_calls = 0;
520     if (debug)
521       fprintf(stderr, "FUNCTION: %s (%zu)\n", F.getName().str().c_str(),
522               F.size());
523 
524     if (!isInInstrumentList(&F, MNAME)) { continue; }
525 
526     if (F.size() < function_minimum_size) { continue; }
527 
528     std::list<Value *> todo;
529     for (auto &BB : F) {
530 
531       BasicBlock::iterator IP = BB.getFirstInsertionPt();
532       IRBuilder<>          IRB(&(*IP));
533 
534       // Context sensitive coverage
535       if (instrument_ctx && &BB == &F.getEntryBlock()) {
536 
537 #ifdef AFL_HAVE_VECTOR_INTRINSICS
538         if (ctx_k) {
539 
540           PrevCaller = IRB.CreateLoad(
541   #if LLVM_VERSION_MAJOR >= 14
542               PrevCallerTy,
543   #endif
544               AFLPrevCaller);
545           PrevCaller->setMetadata(M.getMDKindID("nosanitize"),
546                                   MDNode::get(C, None));
547           PrevCtx =
548               IRB.CreateZExt(IRB.CreateXorReduce(PrevCaller), IRB.getInt32Ty());
549 
550         } else
551 
552 #endif
553         {
554 
555           // load the context ID of the previous function and write to a
556           // local variable on the stack
557           LoadInst *PrevCtxLoad = IRB.CreateLoad(
558 #if LLVM_VERSION_MAJOR >= 14
559               IRB.getInt32Ty(),
560 #endif
561               AFLContext);
562           PrevCtxLoad->setMetadata(M.getMDKindID("nosanitize"),
563                                    MDNode::get(C, None));
564           PrevCtx = PrevCtxLoad;
565 
566         }
567 
568         // does the function have calls? and is any of the calls larger than one
569         // basic block?
570         for (auto &BB_2 : F) {
571 
572           if (has_calls) break;
573           for (auto &IN : BB_2) {
574 
575             CallInst *callInst = nullptr;
576             if ((callInst = dyn_cast<CallInst>(&IN))) {
577 
578               Function *Callee = callInst->getCalledFunction();
579               if (!Callee || Callee->size() < function_minimum_size)
580                 continue;
581               else {
582 
583                 has_calls = 1;
584                 break;
585 
586               }
587 
588             }
589 
590           }
591 
592         }
593 
594         // if yes we store a context ID for this function in the global var
595         if (has_calls) {
596 
597           Value *NewCtx = ConstantInt::get(Int32Ty, AFL_R(map_size));
598 #ifdef AFL_HAVE_VECTOR_INTRINSICS
599           if (ctx_k) {
600 
601             Value *ShuffledPrevCaller = IRB.CreateShuffleVector(
602                 PrevCaller, UndefValue::get(PrevCallerTy),
603                 PrevCallerShuffleMask);
604             Value *UpdatedPrevCaller = IRB.CreateInsertElement(
605                 ShuffledPrevCaller, NewCtx, (uint64_t)0);
606 
607             StoreInst *Store =
608                 IRB.CreateStore(UpdatedPrevCaller, AFLPrevCaller);
609             Store->setMetadata(M.getMDKindID("nosanitize"),
610                                MDNode::get(C, None));
611 
612           } else
613 
614 #endif
615           {
616 
617             if (ctx_str) NewCtx = IRB.CreateXor(PrevCtx, NewCtx);
618             StoreInst *StoreCtx = IRB.CreateStore(NewCtx, AFLContext);
619             StoreCtx->setMetadata(M.getMDKindID("nosanitize"),
620                                   MDNode::get(C, None));
621 
622           }
623 
624         }
625 
626       }
627 
628       if (AFL_R(100) >= inst_ratio) continue;
629 
630       /* Make up cur_loc */
631 
632       // cur_loc++;
633       cur_loc = AFL_R(map_size);
634 
635 /* There is a problem with Ubuntu 18.04 and llvm 6.0 (see issue #63).
636    The inline function successors() is not inlined and also not found at runtime
637    :-( As I am unable to detect Ubuntu18.04 here, the next best thing is to
638    disable this optional optimization for LLVM 6.0.0 and Linux */
639 #if !(LLVM_VERSION_MAJOR == 6 && LLVM_VERSION_MINOR == 0) || !defined __linux__
640       // only instrument if this basic block is the destination of a previous
641       // basic block that has multiple successors
642       // this gets rid of ~5-10% of instrumentations that are unnecessary
643       // result: a little more speed and less map pollution
644       int more_than_one = -1;
645       // fprintf(stderr, "BB %u: ", cur_loc);
646       for (pred_iterator PI = pred_begin(&BB), E = pred_end(&BB); PI != E;
647            ++PI) {
648 
649         BasicBlock *Pred = *PI;
650 
651         int count = 0;
652         if (more_than_one == -1) more_than_one = 0;
653         // fprintf(stderr, " %p=>", Pred);
654 
655         for (succ_iterator SI = succ_begin(Pred), E = succ_end(Pred); SI != E;
656              ++SI) {
657 
658           BasicBlock *Succ = *SI;
659 
660           // if (count > 0)
661           //  fprintf(stderr, "|");
662           if (Succ != NULL) count++;
663           // fprintf(stderr, "%p", Succ);
664 
665         }
666 
667         if (count > 1) more_than_one = 1;
668 
669       }
670 
671       // fprintf(stderr, " == %d\n", more_than_one);
672       if (F.size() > 1 && more_than_one != 1) {
673 
674         // in CTX mode we have to restore the original context for the caller -
675         // she might be calling other functions which need the correct CTX
676         if (instrument_ctx && has_calls) {
677 
678           Instruction *Inst = BB.getTerminator();
679           if (isa<ReturnInst>(Inst) || isa<ResumeInst>(Inst)) {
680 
681             IRBuilder<> Post_IRB(Inst);
682 
683             StoreInst *RestoreCtx;
684   #ifdef AFL_HAVE_VECTOR_INTRINSICS
685             if (ctx_k)
686               RestoreCtx = IRB.CreateStore(PrevCaller, AFLPrevCaller);
687             else
688   #endif
689               RestoreCtx = Post_IRB.CreateStore(PrevCtx, AFLContext);
690             RestoreCtx->setMetadata(M.getMDKindID("nosanitize"),
691                                     MDNode::get(C, None));
692 
693           }
694 
695         }
696 
697         continue;
698 
699       }
700 
701 #endif
702 
703       ConstantInt *CurLoc;
704 
705 #ifdef AFL_HAVE_VECTOR_INTRINSICS
706       if (ngram_size)
707         CurLoc = ConstantInt::get(IntLocTy, cur_loc);
708       else
709 #endif
710         CurLoc = ConstantInt::get(Int32Ty, cur_loc);
711 
712       /* Load prev_loc */
713 
714       LoadInst *PrevLoc;
715 
716       if (ngram_size) {
717 
718         PrevLoc = IRB.CreateLoad(
719 #if LLVM_VERSION_MAJOR >= 14
720             PrevLocTy,
721 #endif
722             AFLPrevLoc);
723 
724       } else {
725 
726         PrevLoc = IRB.CreateLoad(
727 #if LLVM_VERSION_MAJOR >= 14
728             IRB.getInt32Ty(),
729 #endif
730             AFLPrevLoc);
731 
732       }
733 
734       PrevLoc->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None));
735       Value *PrevLocTrans;
736 
737 #ifdef AFL_HAVE_VECTOR_INTRINSICS
738       /* "For efficiency, we propose to hash the tuple as a key into the
739          hit_count map as (prev_block_trans << 1) ^ curr_block_trans, where
740          prev_block_trans = (block_trans_1 ^ ... ^ block_trans_(n-1)" */
741 
742       if (ngram_size)
743         PrevLocTrans =
744             IRB.CreateZExt(IRB.CreateXorReduce(PrevLoc), IRB.getInt32Ty());
745       else
746 #endif
747         PrevLocTrans = PrevLoc;
748 
749       if (instrument_ctx)
750         PrevLocTrans =
751             IRB.CreateZExt(IRB.CreateXor(PrevLocTrans, PrevCtx), Int32Ty);
752       else
753         PrevLocTrans = IRB.CreateZExt(PrevLocTrans, IRB.getInt32Ty());
754 
755       /* Load SHM pointer */
756 
757       LoadInst *MapPtr = IRB.CreateLoad(
758 #if LLVM_VERSION_MAJOR >= 14
759           PointerType::get(Int8Ty, 0),
760 #endif
761           AFLMapPtr);
762       MapPtr->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None));
763 
764       Value *MapPtrIdx;
765 #ifdef AFL_HAVE_VECTOR_INTRINSICS
766       if (ngram_size)
767         MapPtrIdx = IRB.CreateGEP(
768             Int8Ty, MapPtr,
769             IRB.CreateZExt(
770                 IRB.CreateXor(PrevLocTrans, IRB.CreateZExt(CurLoc, Int32Ty)),
771                 Int32Ty));
772       else
773 #endif
774         MapPtrIdx = IRB.CreateGEP(
775 #if LLVM_VERSION_MAJOR >= 14
776             Int8Ty,
777 #endif
778             MapPtr, IRB.CreateXor(PrevLocTrans, CurLoc));
779 
780       /* Update bitmap */
781 
782       if (use_threadsafe_counters) {                              /* Atomic */
783 
784         IRB.CreateAtomicRMW(llvm::AtomicRMWInst::BinOp::Add, MapPtrIdx, One,
785 #if LLVM_VERSION_MAJOR >= 13
786                             llvm::MaybeAlign(1),
787 #endif
788                             llvm::AtomicOrdering::Monotonic);
789         /*
790 
791                 }
792 
793         */
794 
795       } else {
796 
797         LoadInst *Counter = IRB.CreateLoad(
798 #if LLVM_VERSION_MAJOR >= 14
799             IRB.getInt8Ty(),
800 #endif
801             MapPtrIdx);
802         Counter->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None));
803 
804         Value *Incr = IRB.CreateAdd(Counter, One);
805 
806 #if LLVM_VERSION_MAJOR >= 9
807         if (!skip_nozero) {
808 
809 #else
810         if (neverZero_counters_str != NULL) {
811 
812 #endif
813           /* hexcoder: Realize a counter that skips zero during overflow.
814            * Once this counter reaches its maximum value, it next increments to
815            * 1
816            *
817            * Instead of
818            * Counter + 1 -> Counter
819            * we inject now this
820            * Counter + 1 -> {Counter, OverflowFlag}
821            * Counter + OverflowFlag -> Counter
822            */
823 
824           ConstantInt *Zero = ConstantInt::get(Int8Ty, 0);
825           auto         cf = IRB.CreateICmpEQ(Incr, Zero);
826           auto         carry = IRB.CreateZExt(cf, Int8Ty);
827           Incr = IRB.CreateAdd(Incr, carry);
828 
829         }
830 
831         IRB.CreateStore(Incr, MapPtrIdx)
832             ->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None));
833 
834       }                                                  /* non atomic case */
835 
836       /* Update prev_loc history vector (by placing cur_loc at the head of the
837          vector and shuffle the other elements back by one) */
838 
839       StoreInst *Store;
840 
841 #ifdef AFL_HAVE_VECTOR_INTRINSICS
842       if (ngram_size) {
843 
844         Value *ShuffledPrevLoc = IRB.CreateShuffleVector(
845             PrevLoc, UndefValue::get(PrevLocTy), PrevLocShuffleMask);
846         Value *UpdatedPrevLoc = IRB.CreateInsertElement(
847             ShuffledPrevLoc, IRB.CreateLShr(CurLoc, (uint64_t)1), (uint64_t)0);
848 
849         Store = IRB.CreateStore(UpdatedPrevLoc, AFLPrevLoc);
850         Store->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None));
851 
852       } else
853 
854 #endif
855       {
856 
857         Store = IRB.CreateStore(ConstantInt::get(Int32Ty, cur_loc >> 1),
858                                 AFLPrevLoc);
859         Store->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None));
860 
861       }
862 
863       // in CTX mode we have to restore the original context for the caller -
864       // she might be calling other functions which need the correct CTX.
865       // Currently this is only needed for the Ubuntu clang-6.0 bug
866       if (instrument_ctx && has_calls) {
867 
868         Instruction *Inst = BB.getTerminator();
869         if (isa<ReturnInst>(Inst) || isa<ResumeInst>(Inst)) {
870 
871           IRBuilder<> Post_IRB(Inst);
872 
873           StoreInst *RestoreCtx;
874 #ifdef AFL_HAVE_VECTOR_INTRINSICS
875           if (ctx_k)
876             RestoreCtx = IRB.CreateStore(PrevCaller, AFLPrevCaller);
877           else
878 #endif
879             RestoreCtx = Post_IRB.CreateStore(PrevCtx, AFLContext);
880           RestoreCtx->setMetadata(M.getMDKindID("nosanitize"),
881                                   MDNode::get(C, None));
882 
883         }
884 
885       }
886 
887       inst_blocks++;
888 
889     }
890 
891 #if 0
892     if (use_threadsafe_counters) {                       /*Atomic NeverZero */
893       // handle the list of registered blocks to instrument
894       for (auto val : todo) {
895 
896         /* hexcoder: Realize a thread-safe counter that skips zero during
897          * overflow. Once this counter reaches its maximum value, it next
898          * increments to 1
899          *
900          * Instead of
901          * Counter + 1 -> Counter
902          * we inject now this
903          * Counter + 1 -> {Counter, OverflowFlag}
904          * Counter + OverflowFlag -> Counter
905          */
906 
907         /* equivalent c code looks like this
908          * Thanks to
909          https://preshing.com/20150402/you-can-do-any-kind-of-atomic-read-modify-write-operation/
910 
911             int old = atomic_load_explicit(&Counter, memory_order_relaxed);
912             int new;
913             do {
914 
915                  if (old == 255) {
916 
917                    new = 1;
918 
919                  } else {
920 
921                    new = old + 1;
922 
923                  }
924 
925             } while (!atomic_compare_exchange_weak_explicit(&Counter, &old, new,
926 
927          memory_order_relaxed, memory_order_relaxed));
928 
929          */
930 
931         Value *              MapPtrIdx = val;
932         Instruction *        MapPtrIdxInst = cast<Instruction>(val);
933         BasicBlock::iterator it0(&(*MapPtrIdxInst));
934         ++it0;
935         IRBuilder<> IRB(&(*it0));
936 
937         // load the old counter value atomically
938         LoadInst *Counter = IRB.CreateLoad(
939   #if LLVM_VERSION_MAJOR >= 14
940         IRB.getInt8Ty(),
941   #endif
942         MapPtrIdx);
943         Counter->setAlignment(llvm::Align());
944         Counter->setAtomic(llvm::AtomicOrdering::Monotonic);
945         Counter->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None));
946 
947         BasicBlock *BB = IRB.GetInsertBlock();
948         // insert a basic block with the corpus of a do while loop
949         // the calculation may need to repeat, if atomic compare_exchange is not
950         // successful
951 
952         BasicBlock::iterator it(*Counter);
953         it++;  // split after load counter
954         BasicBlock *end_bb = BB->splitBasicBlock(it);
955         end_bb->setName("injected");
956 
957         // insert the block before the second half of the split
958         BasicBlock *do_while_bb =
959             BasicBlock::Create(C, "injected", end_bb->getParent(), end_bb);
960 
961         // set terminator of BB from target end_bb to target do_while_bb
962         auto term = BB->getTerminator();
963         BranchInst::Create(do_while_bb, BB);
964         term->eraseFromParent();
965 
966         // continue to fill instructions into the do_while loop
967         IRB.SetInsertPoint(do_while_bb, do_while_bb->getFirstInsertionPt());
968 
969         PHINode *PN = IRB.CreatePHI(Int8Ty, 2);
970 
971         // compare with maximum value 0xff
972         auto *Cmp = IRB.CreateICmpEQ(Counter, ConstantInt::get(Int8Ty, -1));
973 
974         // increment the counter
975         Value *Incr = IRB.CreateAdd(Counter, One);
976 
977         // select the counter value or 1
978         auto *Select = IRB.CreateSelect(Cmp, One, Incr);
979 
980         // try to save back the new counter value
981         auto *CmpXchg = IRB.CreateAtomicCmpXchg(
982             MapPtrIdx, PN, Select, llvm::AtomicOrdering::Monotonic,
983             llvm::AtomicOrdering::Monotonic);
984         CmpXchg->setAlignment(llvm::Align());
985         CmpXchg->setWeak(true);
986         CmpXchg->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None));
987 
988         // get the result of trying to update the Counter
989         Value *Success =
990             IRB.CreateExtractValue(CmpXchg, ArrayRef<unsigned>({1}));
991         // get the (possibly updated) value of Counter
992         Value *OldVal =
993             IRB.CreateExtractValue(CmpXchg, ArrayRef<unsigned>({0}));
994 
995         // initially we use Counter
996         PN->addIncoming(Counter, BB);
997         // on retry, we use the updated value
998         PN->addIncoming(OldVal, do_while_bb);
999 
1000         // if the cmpXchg was not successful, retry
1001         IRB.CreateCondBr(Success, end_bb, do_while_bb);
1002 
1003       }
1004 
1005     }
1006 
1007 #endif
1008 
1009   }
1010 
1011   /*
1012     // This is currently disabled because we not only need to create/insert a
1013     // function (easy), but also add it as a constructor with an ID < 5
1014 
1015     if (getenv("AFL_LLVM_DONTWRITEID") == NULL) {
1016 
1017       // yes we could create our own function, insert it into ctors ...
1018       // but this would be a pain in the butt ... so we use afl-llvm-rt.o
1019 
1020       Function *f = ...
1021 
1022       if (!f) {
1023 
1024         fprintf(stderr,
1025                 "Error: init function could not be created (this should not
1026     happen)\n"); exit(-1);
1027 
1028       }
1029 
1030       ... constructor for f = 4
1031 
1032       BasicBlock *bb = &f->getEntryBlock();
1033       if (!bb) {
1034 
1035         fprintf(stderr,
1036                 "Error: init function does not have an EntryBlock (this should
1037     not happen)\n"); exit(-1);
1038 
1039       }
1040 
1041       BasicBlock::iterator IP = bb->getFirstInsertionPt();
1042       IRBuilder<>          IRB(&(*IP));
1043 
1044       if (map_size <= 0x800000) {
1045 
1046         GlobalVariable *AFLFinalLoc = new GlobalVariable(
1047             M, Int32Ty, true, GlobalValue::ExternalLinkage, 0,
1048             "__afl_final_loc");
1049         ConstantInt *const_loc = ConstantInt::get(Int32Ty, map_size);
1050         StoreInst *  StoreFinalLoc = IRB.CreateStore(const_loc, AFLFinalLoc);
1051         StoreFinalLoc->setMetadata(M.getMDKindID("nosanitize"),
1052                                      MDNode::get(C, None));
1053 
1054       }
1055 
1056     }
1057 
1058   */
1059 
1060   /* Say something nice. */
1061 
1062   if (!be_quiet) {
1063 
1064     if (!inst_blocks)
1065       WARNF("No instrumentation targets found.");
1066     else {
1067 
1068       char modeline[100];
1069       snprintf(modeline, sizeof(modeline), "%s%s%s%s%s%s",
1070                getenv("AFL_HARDEN") ? "hardened" : "non-hardened",
1071                getenv("AFL_USE_ASAN") ? ", ASAN" : "",
1072                getenv("AFL_USE_MSAN") ? ", MSAN" : "",
1073                getenv("AFL_USE_CFISAN") ? ", CFISAN" : "",
1074                getenv("AFL_USE_TSAN") ? ", TSAN" : "",
1075                getenv("AFL_USE_UBSAN") ? ", UBSAN" : "");
1076       OKF("Instrumented %d locations (%s mode, ratio %u%%).", inst_blocks,
1077           modeline, inst_ratio);
1078 
1079     }
1080 
1081   }
1082 
1083 #if LLVM_VERSION_MAJOR >= 11                        /* use new pass manager */
1084   return PA;
1085 #else
1086   return true;
1087 #endif
1088 
1089 }
1090 
1091 #if LLVM_VERSION_MAJOR < 11                         /* use old pass manager */
1092 static void registerAFLPass(const PassManagerBuilder &,
1093                             legacy::PassManagerBase &PM) {
1094 
1095   PM.add(new AFLCoverage());
1096 
1097 }
1098 
1099 static RegisterStandardPasses RegisterAFLPass(
1100     PassManagerBuilder::EP_OptimizerLast, registerAFLPass);
1101 
1102 static RegisterStandardPasses RegisterAFLPass0(
1103     PassManagerBuilder::EP_EnabledOnOptLevel0, registerAFLPass);
1104 #endif
1105 
1106