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