xref: /aosp_15_r20/external/AFLplusplus/instrumentation/afl-llvm-lto-instrumentlist.so.cc (revision 08b48e0b10e97b33e7b60c5b6e2243bd915777f2)
1*08b48e0bSAndroid Build Coastguard Worker /*
2*08b48e0bSAndroid Build Coastguard Worker    american fuzzy lop++ - LLVM-mode instrumentation pass
3*08b48e0bSAndroid Build Coastguard Worker    ---------------------------------------------------
4*08b48e0bSAndroid Build Coastguard Worker 
5*08b48e0bSAndroid Build Coastguard Worker    Written by Laszlo Szekeres <[email protected]> and
6*08b48e0bSAndroid Build Coastguard Worker               Michal Zalewski
7*08b48e0bSAndroid Build Coastguard Worker 
8*08b48e0bSAndroid Build Coastguard Worker    LLVM integration design comes from Laszlo Szekeres. C bits copied-and-pasted
9*08b48e0bSAndroid Build Coastguard Worker    from afl-as.c are Michal's fault.
10*08b48e0bSAndroid Build Coastguard Worker 
11*08b48e0bSAndroid Build Coastguard Worker    Copyright 2015, 2016 Google Inc. All rights reserved.
12*08b48e0bSAndroid Build Coastguard Worker    Copyright 2019-2024 AFLplusplus Project. All rights reserved.
13*08b48e0bSAndroid Build Coastguard Worker 
14*08b48e0bSAndroid Build Coastguard Worker    Licensed under the Apache License, Version 2.0 (the "License");
15*08b48e0bSAndroid Build Coastguard Worker    you may not use this file except in compliance with the License.
16*08b48e0bSAndroid Build Coastguard Worker    You may obtain a copy of the License at:
17*08b48e0bSAndroid Build Coastguard Worker 
18*08b48e0bSAndroid Build Coastguard Worker      https://www.apache.org/licenses/LICENSE-2.0
19*08b48e0bSAndroid Build Coastguard Worker 
20*08b48e0bSAndroid Build Coastguard Worker    This library is plugged into LLVM when invoking clang through afl-clang-fast.
21*08b48e0bSAndroid Build Coastguard Worker    It tells the compiler to add code roughly equivalent to the bits discussed
22*08b48e0bSAndroid Build Coastguard Worker    in ../afl-as.h.
23*08b48e0bSAndroid Build Coastguard Worker 
24*08b48e0bSAndroid Build Coastguard Worker  */
25*08b48e0bSAndroid Build Coastguard Worker 
26*08b48e0bSAndroid Build Coastguard Worker #define AFL_LLVM_PASS
27*08b48e0bSAndroid Build Coastguard Worker 
28*08b48e0bSAndroid Build Coastguard Worker #include "config.h"
29*08b48e0bSAndroid Build Coastguard Worker #include "debug.h"
30*08b48e0bSAndroid Build Coastguard Worker 
31*08b48e0bSAndroid Build Coastguard Worker #include <stdio.h>
32*08b48e0bSAndroid Build Coastguard Worker #include <stdlib.h>
33*08b48e0bSAndroid Build Coastguard Worker #include <unistd.h>
34*08b48e0bSAndroid Build Coastguard Worker 
35*08b48e0bSAndroid Build Coastguard Worker #include <list>
36*08b48e0bSAndroid Build Coastguard Worker #include <string>
37*08b48e0bSAndroid Build Coastguard Worker #include <fstream>
38*08b48e0bSAndroid Build Coastguard Worker #include <sys/time.h>
39*08b48e0bSAndroid Build Coastguard Worker #include <fnmatch.h>
40*08b48e0bSAndroid Build Coastguard Worker 
41*08b48e0bSAndroid Build Coastguard Worker #include "llvm/IR/DebugInfo.h"
42*08b48e0bSAndroid Build Coastguard Worker #include "llvm/IR/BasicBlock.h"
43*08b48e0bSAndroid Build Coastguard Worker #include "llvm/IR/IRBuilder.h"
44*08b48e0bSAndroid Build Coastguard Worker #include "llvm/IR/LegacyPassManager.h"
45*08b48e0bSAndroid Build Coastguard Worker #include "llvm/IR/Module.h"
46*08b48e0bSAndroid Build Coastguard Worker #include "llvm/Pass.h"
47*08b48e0bSAndroid Build Coastguard Worker #include "llvm/Support/Debug.h"
48*08b48e0bSAndroid Build Coastguard Worker // #include "llvm/Transforms/IPO/PassManagerBuilder.h"
49*08b48e0bSAndroid Build Coastguard Worker #include "llvm/Passes/PassPlugin.h"
50*08b48e0bSAndroid Build Coastguard Worker #include "llvm/Passes/PassBuilder.h"
51*08b48e0bSAndroid Build Coastguard Worker #include "llvm/IR/PassManager.h"
52*08b48e0bSAndroid Build Coastguard Worker #include "llvm/IR/CFG.h"
53*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 14                /* how about stable interfaces? */
54*08b48e0bSAndroid Build Coastguard Worker   #include "llvm/Passes/OptimizationLevel.h"
55*08b48e0bSAndroid Build Coastguard Worker #endif
56*08b48e0bSAndroid Build Coastguard Worker 
57*08b48e0bSAndroid Build Coastguard Worker #include "afl-llvm-common.h"
58*08b48e0bSAndroid Build Coastguard Worker 
59*08b48e0bSAndroid Build Coastguard Worker using namespace llvm;
60*08b48e0bSAndroid Build Coastguard Worker 
61*08b48e0bSAndroid Build Coastguard Worker namespace {
62*08b48e0bSAndroid Build Coastguard Worker 
63*08b48e0bSAndroid Build Coastguard Worker class AFLcheckIfInstrument : public PassInfoMixin<AFLcheckIfInstrument> {
64*08b48e0bSAndroid Build Coastguard Worker 
65*08b48e0bSAndroid Build Coastguard Worker  public:
AFLcheckIfInstrument()66*08b48e0bSAndroid Build Coastguard Worker   AFLcheckIfInstrument() {
67*08b48e0bSAndroid Build Coastguard Worker 
68*08b48e0bSAndroid Build Coastguard Worker     if (getenv("AFL_DEBUG")) debug = 1;
69*08b48e0bSAndroid Build Coastguard Worker 
70*08b48e0bSAndroid Build Coastguard Worker     initInstrumentList();
71*08b48e0bSAndroid Build Coastguard Worker 
72*08b48e0bSAndroid Build Coastguard Worker   }
73*08b48e0bSAndroid Build Coastguard Worker 
74*08b48e0bSAndroid Build Coastguard Worker   PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
75*08b48e0bSAndroid Build Coastguard Worker 
76*08b48e0bSAndroid Build Coastguard Worker  protected:
77*08b48e0bSAndroid Build Coastguard Worker   std::list<std::string> myInstrumentList;
78*08b48e0bSAndroid Build Coastguard Worker 
79*08b48e0bSAndroid Build Coastguard Worker };
80*08b48e0bSAndroid Build Coastguard Worker 
81*08b48e0bSAndroid Build Coastguard Worker }  // namespace
82*08b48e0bSAndroid Build Coastguard Worker 
83*08b48e0bSAndroid Build Coastguard Worker extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK
llvmGetPassPluginInfo()84*08b48e0bSAndroid Build Coastguard Worker llvmGetPassPluginInfo() {
85*08b48e0bSAndroid Build Coastguard Worker 
86*08b48e0bSAndroid Build Coastguard Worker   return {LLVM_PLUGIN_API_VERSION, "AFLcheckIfInstrument", "v0.1",
87*08b48e0bSAndroid Build Coastguard Worker           /* lambda to insert our pass into the pass pipeline. */
88*08b48e0bSAndroid Build Coastguard Worker           [](PassBuilder &PB) {
89*08b48e0bSAndroid Build Coastguard Worker 
90*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR <= 13
91*08b48e0bSAndroid Build Coastguard Worker             using OptimizationLevel = typename PassBuilder::OptimizationLevel;
92*08b48e0bSAndroid Build Coastguard Worker #endif
93*08b48e0bSAndroid Build Coastguard Worker             PB.registerOptimizerLastEPCallback(
94*08b48e0bSAndroid Build Coastguard Worker                 [](ModulePassManager &MPM, OptimizationLevel OL) {
95*08b48e0bSAndroid Build Coastguard Worker 
96*08b48e0bSAndroid Build Coastguard Worker                   MPM.addPass(AFLcheckIfInstrument());
97*08b48e0bSAndroid Build Coastguard Worker 
98*08b48e0bSAndroid Build Coastguard Worker                 });
99*08b48e0bSAndroid Build Coastguard Worker 
100*08b48e0bSAndroid Build Coastguard Worker           }};
101*08b48e0bSAndroid Build Coastguard Worker 
102*08b48e0bSAndroid Build Coastguard Worker }
103*08b48e0bSAndroid Build Coastguard Worker 
run(Module & M,ModuleAnalysisManager & MAM)104*08b48e0bSAndroid Build Coastguard Worker PreservedAnalyses AFLcheckIfInstrument::run(Module                &M,
105*08b48e0bSAndroid Build Coastguard Worker                                             ModuleAnalysisManager &MAM) {
106*08b48e0bSAndroid Build Coastguard Worker 
107*08b48e0bSAndroid Build Coastguard Worker   /* Show a banner */
108*08b48e0bSAndroid Build Coastguard Worker 
109*08b48e0bSAndroid Build Coastguard Worker   setvbuf(stdout, NULL, _IONBF, 0);
110*08b48e0bSAndroid Build Coastguard Worker 
111*08b48e0bSAndroid Build Coastguard Worker   if ((isatty(2) && !getenv("AFL_QUIET")) || getenv("AFL_DEBUG") != NULL) {
112*08b48e0bSAndroid Build Coastguard Worker 
113*08b48e0bSAndroid Build Coastguard Worker     SAYF(cCYA "afl-llvm-lto-instrumentlist" VERSION cRST
114*08b48e0bSAndroid Build Coastguard Worker               " by Marc \"vanHauser\" Heuse <[email protected]>\n");
115*08b48e0bSAndroid Build Coastguard Worker 
116*08b48e0bSAndroid Build Coastguard Worker   } else if (getenv("AFL_QUIET"))
117*08b48e0bSAndroid Build Coastguard Worker 
118*08b48e0bSAndroid Build Coastguard Worker     be_quiet = 1;
119*08b48e0bSAndroid Build Coastguard Worker 
120*08b48e0bSAndroid Build Coastguard Worker   for (auto &F : M) {
121*08b48e0bSAndroid Build Coastguard Worker 
122*08b48e0bSAndroid Build Coastguard Worker     if (F.size() < 1) continue;
123*08b48e0bSAndroid Build Coastguard Worker 
124*08b48e0bSAndroid Build Coastguard Worker     // fprintf(stderr, "F:%s\n", F.getName().str().c_str());
125*08b48e0bSAndroid Build Coastguard Worker 
126*08b48e0bSAndroid Build Coastguard Worker     if (isInInstrumentList(&F, MNAME)) {
127*08b48e0bSAndroid Build Coastguard Worker 
128*08b48e0bSAndroid Build Coastguard Worker       if (debug)
129*08b48e0bSAndroid Build Coastguard Worker         DEBUGF("function %s is in the instrument file list\n",
130*08b48e0bSAndroid Build Coastguard Worker                F.getName().str().c_str());
131*08b48e0bSAndroid Build Coastguard Worker 
132*08b48e0bSAndroid Build Coastguard Worker     } else {
133*08b48e0bSAndroid Build Coastguard Worker 
134*08b48e0bSAndroid Build Coastguard Worker       if (debug)
135*08b48e0bSAndroid Build Coastguard Worker         DEBUGF("function %s is NOT in the instrument file list\n",
136*08b48e0bSAndroid Build Coastguard Worker                F.getName().str().c_str());
137*08b48e0bSAndroid Build Coastguard Worker 
138*08b48e0bSAndroid Build Coastguard Worker       auto         &Ctx = F.getContext();
139*08b48e0bSAndroid Build Coastguard Worker       AttributeList Attrs = F.getAttributes();
140*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 14
141*08b48e0bSAndroid Build Coastguard Worker       AttributeList NewAttrs = Attrs.addFnAttribute(Ctx, "skipinstrument");
142*08b48e0bSAndroid Build Coastguard Worker       F.setAttributes(NewAttrs);
143*08b48e0bSAndroid Build Coastguard Worker #else
144*08b48e0bSAndroid Build Coastguard Worker       AttrBuilder NewAttrs;
145*08b48e0bSAndroid Build Coastguard Worker       NewAttrs.addAttribute("skipinstrument");
146*08b48e0bSAndroid Build Coastguard Worker       F.setAttributes(
147*08b48e0bSAndroid Build Coastguard Worker           Attrs.addAttributes(Ctx, AttributeList::FunctionIndex, NewAttrs));
148*08b48e0bSAndroid Build Coastguard Worker #endif
149*08b48e0bSAndroid Build Coastguard Worker 
150*08b48e0bSAndroid Build Coastguard Worker     }
151*08b48e0bSAndroid Build Coastguard Worker 
152*08b48e0bSAndroid Build Coastguard Worker   }
153*08b48e0bSAndroid Build Coastguard Worker 
154*08b48e0bSAndroid Build Coastguard Worker   auto PA = PreservedAnalyses::all();
155*08b48e0bSAndroid Build Coastguard Worker   return PA;
156*08b48e0bSAndroid Build Coastguard Worker 
157*08b48e0bSAndroid Build Coastguard Worker }
158*08b48e0bSAndroid Build Coastguard Worker 
159*08b48e0bSAndroid Build Coastguard Worker #if 0
160*08b48e0bSAndroid Build Coastguard Worker static void registerAFLcheckIfInstrumentpass(const PassManagerBuilder &,
161*08b48e0bSAndroid Build Coastguard Worker                                              legacy::PassManagerBase &PM) {
162*08b48e0bSAndroid Build Coastguard Worker 
163*08b48e0bSAndroid Build Coastguard Worker   PM.add(new AFLcheckIfInstrument());
164*08b48e0bSAndroid Build Coastguard Worker 
165*08b48e0bSAndroid Build Coastguard Worker }
166*08b48e0bSAndroid Build Coastguard Worker 
167*08b48e0bSAndroid Build Coastguard Worker static RegisterStandardPasses RegisterAFLcheckIfInstrumentpass(
168*08b48e0bSAndroid Build Coastguard Worker     PassManagerBuilder::EP_ModuleOptimizerEarly,
169*08b48e0bSAndroid Build Coastguard Worker     registerAFLcheckIfInstrumentpass);
170*08b48e0bSAndroid Build Coastguard Worker 
171*08b48e0bSAndroid Build Coastguard Worker static RegisterStandardPasses RegisterAFLcheckIfInstrumentpass0(
172*08b48e0bSAndroid Build Coastguard Worker     PassManagerBuilder::EP_EnabledOnOptLevel0,
173*08b48e0bSAndroid Build Coastguard Worker     registerAFLcheckIfInstrumentpass);
174*08b48e0bSAndroid Build Coastguard Worker #endif
175*08b48e0bSAndroid Build Coastguard Worker 
176