xref: /aosp_15_r20/external/AFLplusplus/instrumentation/cmplog-instructions-pass.cc (revision 08b48e0b10e97b33e7b60c5b6e2243bd915777f2)
1*08b48e0bSAndroid Build Coastguard Worker /*
2*08b48e0bSAndroid Build Coastguard Worker    american fuzzy lop++ - LLVM CmpLog instrumentation
3*08b48e0bSAndroid Build Coastguard Worker    --------------------------------------------------
4*08b48e0bSAndroid Build Coastguard Worker 
5*08b48e0bSAndroid Build Coastguard Worker    Written by Andrea Fioraldi <[email protected]>
6*08b48e0bSAndroid Build Coastguard Worker 
7*08b48e0bSAndroid Build Coastguard Worker    Copyright 2015, 2016 Google Inc. All rights reserved.
8*08b48e0bSAndroid Build Coastguard Worker    Copyright 2019-2024 AFLplusplus Project. All rights reserved.
9*08b48e0bSAndroid Build Coastguard Worker 
10*08b48e0bSAndroid Build Coastguard Worker    Licensed under the Apache License, Version 2.0 (the "License");
11*08b48e0bSAndroid Build Coastguard Worker    you may not use this file except in compliance with the License.
12*08b48e0bSAndroid Build Coastguard Worker    You may obtain a copy of the License at:
13*08b48e0bSAndroid Build Coastguard Worker 
14*08b48e0bSAndroid Build Coastguard Worker      https://www.apache.org/licenses/LICENSE-2.0
15*08b48e0bSAndroid Build Coastguard Worker 
16*08b48e0bSAndroid Build Coastguard Worker */
17*08b48e0bSAndroid Build Coastguard Worker 
18*08b48e0bSAndroid Build Coastguard Worker #include <stdio.h>
19*08b48e0bSAndroid Build Coastguard Worker #include <stdlib.h>
20*08b48e0bSAndroid Build Coastguard Worker #include <unistd.h>
21*08b48e0bSAndroid Build Coastguard Worker 
22*08b48e0bSAndroid Build Coastguard Worker #include <iostream>
23*08b48e0bSAndroid Build Coastguard Worker #include <list>
24*08b48e0bSAndroid Build Coastguard Worker #include <string>
25*08b48e0bSAndroid Build Coastguard Worker #include <fstream>
26*08b48e0bSAndroid Build Coastguard Worker #include <sys/time.h>
27*08b48e0bSAndroid Build Coastguard Worker 
28*08b48e0bSAndroid Build Coastguard Worker #include "llvm/Config/llvm-config.h"
29*08b48e0bSAndroid Build Coastguard Worker #include "llvm/ADT/Statistic.h"
30*08b48e0bSAndroid Build Coastguard Worker #include "llvm/IR/IRBuilder.h"
31*08b48e0bSAndroid Build Coastguard Worker #include "llvm/IR/Module.h"
32*08b48e0bSAndroid Build Coastguard Worker #include "llvm/Support/Debug.h"
33*08b48e0bSAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
34*08b48e0bSAndroid Build Coastguard Worker #if LLVM_MAJOR >= 11
35*08b48e0bSAndroid Build Coastguard Worker   #include "llvm/Passes/PassPlugin.h"
36*08b48e0bSAndroid Build Coastguard Worker   #include "llvm/Passes/PassBuilder.h"
37*08b48e0bSAndroid Build Coastguard Worker   #include "llvm/IR/PassManager.h"
38*08b48e0bSAndroid Build Coastguard Worker #else
39*08b48e0bSAndroid Build Coastguard Worker   #include "llvm/IR/LegacyPassManager.h"
40*08b48e0bSAndroid Build Coastguard Worker   #include "llvm/Transforms/IPO/PassManagerBuilder.h"
41*08b48e0bSAndroid Build Coastguard Worker #endif
42*08b48e0bSAndroid Build Coastguard Worker #include "llvm/Transforms/Utils/BasicBlockUtils.h"
43*08b48e0bSAndroid Build Coastguard Worker #include "llvm/Pass.h"
44*08b48e0bSAndroid Build Coastguard Worker #include "llvm/Analysis/ValueTracking.h"
45*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 14                /* how about stable interfaces? */
46*08b48e0bSAndroid Build Coastguard Worker   #include "llvm/Passes/OptimizationLevel.h"
47*08b48e0bSAndroid Build Coastguard Worker #endif
48*08b48e0bSAndroid Build Coastguard Worker 
49*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 4 || \
50*08b48e0bSAndroid Build Coastguard Worker     (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR > 4)
51*08b48e0bSAndroid Build Coastguard Worker   #include "llvm/IR/Verifier.h"
52*08b48e0bSAndroid Build Coastguard Worker   #include "llvm/IR/DebugInfo.h"
53*08b48e0bSAndroid Build Coastguard Worker   #include "llvm/Support/raw_ostream.h"
54*08b48e0bSAndroid Build Coastguard Worker #else
55*08b48e0bSAndroid Build Coastguard Worker   #include "llvm/Analysis/Verifier.h"
56*08b48e0bSAndroid Build Coastguard Worker   #include "llvm/DebugInfo.h"
57*08b48e0bSAndroid Build Coastguard Worker   #define nullptr 0
58*08b48e0bSAndroid Build Coastguard Worker #endif
59*08b48e0bSAndroid Build Coastguard Worker 
60*08b48e0bSAndroid Build Coastguard Worker #include <set>
61*08b48e0bSAndroid Build Coastguard Worker #include "afl-llvm-common.h"
62*08b48e0bSAndroid Build Coastguard Worker 
63*08b48e0bSAndroid Build Coastguard Worker using namespace llvm;
64*08b48e0bSAndroid Build Coastguard Worker 
65*08b48e0bSAndroid Build Coastguard Worker namespace {
66*08b48e0bSAndroid Build Coastguard Worker 
67*08b48e0bSAndroid Build Coastguard Worker #if LLVM_MAJOR >= 11                                /* use new pass manager */
68*08b48e0bSAndroid Build Coastguard Worker class CmpLogInstructions : public PassInfoMixin<CmpLogInstructions> {
69*08b48e0bSAndroid Build Coastguard Worker 
70*08b48e0bSAndroid Build Coastguard Worker  public:
CmpLogInstructions()71*08b48e0bSAndroid Build Coastguard Worker   CmpLogInstructions() {
72*08b48e0bSAndroid Build Coastguard Worker 
73*08b48e0bSAndroid Build Coastguard Worker     initInstrumentList();
74*08b48e0bSAndroid Build Coastguard Worker 
75*08b48e0bSAndroid Build Coastguard Worker   }
76*08b48e0bSAndroid Build Coastguard Worker 
77*08b48e0bSAndroid Build Coastguard Worker #else
78*08b48e0bSAndroid Build Coastguard Worker class CmpLogInstructions : public ModulePass {
79*08b48e0bSAndroid Build Coastguard Worker 
80*08b48e0bSAndroid Build Coastguard Worker  public:
81*08b48e0bSAndroid Build Coastguard Worker   static char ID;
82*08b48e0bSAndroid Build Coastguard Worker   CmpLogInstructions() : ModulePass(ID) {
83*08b48e0bSAndroid Build Coastguard Worker 
84*08b48e0bSAndroid Build Coastguard Worker     initInstrumentList();
85*08b48e0bSAndroid Build Coastguard Worker 
86*08b48e0bSAndroid Build Coastguard Worker   }
87*08b48e0bSAndroid Build Coastguard Worker 
88*08b48e0bSAndroid Build Coastguard Worker #endif
89*08b48e0bSAndroid Build Coastguard Worker 
90*08b48e0bSAndroid Build Coastguard Worker #if LLVM_MAJOR >= 11                                /* use new pass manager */
91*08b48e0bSAndroid Build Coastguard Worker   PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
92*08b48e0bSAndroid Build Coastguard Worker #else
93*08b48e0bSAndroid Build Coastguard Worker   bool runOnModule(Module &M) override;
94*08b48e0bSAndroid Build Coastguard Worker 
95*08b48e0bSAndroid Build Coastguard Worker   #if LLVM_VERSION_MAJOR >= 4
getPassName() const96*08b48e0bSAndroid Build Coastguard Worker   StringRef getPassName() const override {
97*08b48e0bSAndroid Build Coastguard Worker 
98*08b48e0bSAndroid Build Coastguard Worker   #else
99*08b48e0bSAndroid Build Coastguard Worker   const char *getPassName() const override {
100*08b48e0bSAndroid Build Coastguard Worker 
101*08b48e0bSAndroid Build Coastguard Worker   #endif
102*08b48e0bSAndroid Build Coastguard Worker     return "cmplog instructions";
103*08b48e0bSAndroid Build Coastguard Worker 
104*08b48e0bSAndroid Build Coastguard Worker   }
105*08b48e0bSAndroid Build Coastguard Worker 
106*08b48e0bSAndroid Build Coastguard Worker #endif
107*08b48e0bSAndroid Build Coastguard Worker 
108*08b48e0bSAndroid Build Coastguard Worker  private:
109*08b48e0bSAndroid Build Coastguard Worker   bool hookInstrs(Module &M);
110*08b48e0bSAndroid Build Coastguard Worker 
111*08b48e0bSAndroid Build Coastguard Worker };
112*08b48e0bSAndroid Build Coastguard Worker 
113*08b48e0bSAndroid Build Coastguard Worker }  // namespace
114*08b48e0bSAndroid Build Coastguard Worker 
115*08b48e0bSAndroid Build Coastguard Worker #if LLVM_MAJOR >= 11
116*08b48e0bSAndroid Build Coastguard Worker extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK
llvmGetPassPluginInfo()117*08b48e0bSAndroid Build Coastguard Worker llvmGetPassPluginInfo() {
118*08b48e0bSAndroid Build Coastguard Worker 
119*08b48e0bSAndroid Build Coastguard Worker   return {LLVM_PLUGIN_API_VERSION, "cmploginstructions", "v0.1",
120*08b48e0bSAndroid Build Coastguard Worker           /* lambda to insert our pass into the pass pipeline. */
121*08b48e0bSAndroid Build Coastguard Worker           [](PassBuilder &PB) {
122*08b48e0bSAndroid Build Coastguard Worker 
123*08b48e0bSAndroid Build Coastguard Worker   #if LLVM_VERSION_MAJOR <= 13
124*08b48e0bSAndroid Build Coastguard Worker             using OptimizationLevel = typename PassBuilder::OptimizationLevel;
125*08b48e0bSAndroid Build Coastguard Worker   #endif
126*08b48e0bSAndroid Build Coastguard Worker             PB.registerOptimizerLastEPCallback(
127*08b48e0bSAndroid Build Coastguard Worker                 [](ModulePassManager &MPM, OptimizationLevel OL) {
128*08b48e0bSAndroid Build Coastguard Worker 
129*08b48e0bSAndroid Build Coastguard Worker                   MPM.addPass(CmpLogInstructions());
130*08b48e0bSAndroid Build Coastguard Worker 
131*08b48e0bSAndroid Build Coastguard Worker                 });
132*08b48e0bSAndroid Build Coastguard Worker 
133*08b48e0bSAndroid Build Coastguard Worker           }};
134*08b48e0bSAndroid Build Coastguard Worker 
135*08b48e0bSAndroid Build Coastguard Worker }
136*08b48e0bSAndroid Build Coastguard Worker 
137*08b48e0bSAndroid Build Coastguard Worker #else
138*08b48e0bSAndroid Build Coastguard Worker char CmpLogInstructions::ID = 0;
139*08b48e0bSAndroid Build Coastguard Worker #endif
140*08b48e0bSAndroid Build Coastguard Worker 
141*08b48e0bSAndroid Build Coastguard Worker template <class Iterator>
Unique(Iterator first,Iterator last)142*08b48e0bSAndroid Build Coastguard Worker Iterator Unique(Iterator first, Iterator last) {
143*08b48e0bSAndroid Build Coastguard Worker 
144*08b48e0bSAndroid Build Coastguard Worker   while (first != last) {
145*08b48e0bSAndroid Build Coastguard Worker 
146*08b48e0bSAndroid Build Coastguard Worker     Iterator next(first);
147*08b48e0bSAndroid Build Coastguard Worker     last = std::remove(++next, last, *first);
148*08b48e0bSAndroid Build Coastguard Worker     first = next;
149*08b48e0bSAndroid Build Coastguard Worker 
150*08b48e0bSAndroid Build Coastguard Worker   }
151*08b48e0bSAndroid Build Coastguard Worker 
152*08b48e0bSAndroid Build Coastguard Worker   return last;
153*08b48e0bSAndroid Build Coastguard Worker 
154*08b48e0bSAndroid Build Coastguard Worker }
155*08b48e0bSAndroid Build Coastguard Worker 
hookInstrs(Module & M)156*08b48e0bSAndroid Build Coastguard Worker bool CmpLogInstructions::hookInstrs(Module &M) {
157*08b48e0bSAndroid Build Coastguard Worker 
158*08b48e0bSAndroid Build Coastguard Worker   std::vector<Instruction *> icomps;
159*08b48e0bSAndroid Build Coastguard Worker   LLVMContext               &C = M.getContext();
160*08b48e0bSAndroid Build Coastguard Worker 
161*08b48e0bSAndroid Build Coastguard Worker   Type        *VoidTy = Type::getVoidTy(C);
162*08b48e0bSAndroid Build Coastguard Worker   IntegerType *Int8Ty = IntegerType::getInt8Ty(C);
163*08b48e0bSAndroid Build Coastguard Worker   IntegerType *Int16Ty = IntegerType::getInt16Ty(C);
164*08b48e0bSAndroid Build Coastguard Worker   IntegerType *Int32Ty = IntegerType::getInt32Ty(C);
165*08b48e0bSAndroid Build Coastguard Worker   IntegerType *Int64Ty = IntegerType::getInt64Ty(C);
166*08b48e0bSAndroid Build Coastguard Worker   IntegerType *Int128Ty = IntegerType::getInt128Ty(C);
167*08b48e0bSAndroid Build Coastguard Worker 
168*08b48e0bSAndroid Build Coastguard Worker   /*
169*08b48e0bSAndroid Build Coastguard Worker   #if LLVM_VERSION_MAJOR >= 9
170*08b48e0bSAndroid Build Coastguard Worker     FunctionCallee
171*08b48e0bSAndroid Build Coastguard Worker   #else
172*08b48e0bSAndroid Build Coastguard Worker     Constant *
173*08b48e0bSAndroid Build Coastguard Worker   #endif
174*08b48e0bSAndroid Build Coastguard Worker         c1 = M.getOrInsertFunction("__cmplog_ins_hook1", VoidTy, Int8Ty, Int8Ty,
175*08b48e0bSAndroid Build Coastguard Worker                                    Int8Ty
176*08b48e0bSAndroid Build Coastguard Worker   #if LLVM_VERSION_MAJOR < 5
177*08b48e0bSAndroid Build Coastguard Worker                                    ,
178*08b48e0bSAndroid Build Coastguard Worker                                    NULL
179*08b48e0bSAndroid Build Coastguard Worker   #endif
180*08b48e0bSAndroid Build Coastguard Worker         );
181*08b48e0bSAndroid Build Coastguard Worker   #if LLVM_VERSION_MAJOR >= 9
182*08b48e0bSAndroid Build Coastguard Worker     FunctionCallee cmplogHookIns1 = c1;
183*08b48e0bSAndroid Build Coastguard Worker   #else
184*08b48e0bSAndroid Build Coastguard Worker     Function *cmplogHookIns1 = cast<Function>(c1);
185*08b48e0bSAndroid Build Coastguard Worker   #endif
186*08b48e0bSAndroid Build Coastguard Worker   */
187*08b48e0bSAndroid Build Coastguard Worker 
188*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 9
189*08b48e0bSAndroid Build Coastguard Worker   FunctionCallee
190*08b48e0bSAndroid Build Coastguard Worker #else
191*08b48e0bSAndroid Build Coastguard Worker   Constant *
192*08b48e0bSAndroid Build Coastguard Worker #endif
193*08b48e0bSAndroid Build Coastguard Worker       c2 = M.getOrInsertFunction("__cmplog_ins_hook2", VoidTy, Int16Ty, Int16Ty,
194*08b48e0bSAndroid Build Coastguard Worker                                  Int8Ty
195*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR < 5
196*08b48e0bSAndroid Build Coastguard Worker                                  ,
197*08b48e0bSAndroid Build Coastguard Worker                                  NULL
198*08b48e0bSAndroid Build Coastguard Worker #endif
199*08b48e0bSAndroid Build Coastguard Worker       );
200*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 9
201*08b48e0bSAndroid Build Coastguard Worker   FunctionCallee cmplogHookIns2 = c2;
202*08b48e0bSAndroid Build Coastguard Worker #else
203*08b48e0bSAndroid Build Coastguard Worker   Function *cmplogHookIns2 = cast<Function>(c2);
204*08b48e0bSAndroid Build Coastguard Worker #endif
205*08b48e0bSAndroid Build Coastguard Worker 
206*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 9
207*08b48e0bSAndroid Build Coastguard Worker   FunctionCallee
208*08b48e0bSAndroid Build Coastguard Worker #else
209*08b48e0bSAndroid Build Coastguard Worker   Constant *
210*08b48e0bSAndroid Build Coastguard Worker #endif
211*08b48e0bSAndroid Build Coastguard Worker       c4 = M.getOrInsertFunction("__cmplog_ins_hook4", VoidTy, Int32Ty, Int32Ty,
212*08b48e0bSAndroid Build Coastguard Worker                                  Int8Ty
213*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR < 5
214*08b48e0bSAndroid Build Coastguard Worker                                  ,
215*08b48e0bSAndroid Build Coastguard Worker                                  NULL
216*08b48e0bSAndroid Build Coastguard Worker #endif
217*08b48e0bSAndroid Build Coastguard Worker       );
218*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 9
219*08b48e0bSAndroid Build Coastguard Worker   FunctionCallee cmplogHookIns4 = c4;
220*08b48e0bSAndroid Build Coastguard Worker #else
221*08b48e0bSAndroid Build Coastguard Worker   Function *cmplogHookIns4 = cast<Function>(c4);
222*08b48e0bSAndroid Build Coastguard Worker #endif
223*08b48e0bSAndroid Build Coastguard Worker 
224*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 9
225*08b48e0bSAndroid Build Coastguard Worker   FunctionCallee
226*08b48e0bSAndroid Build Coastguard Worker #else
227*08b48e0bSAndroid Build Coastguard Worker   Constant *
228*08b48e0bSAndroid Build Coastguard Worker #endif
229*08b48e0bSAndroid Build Coastguard Worker       c8 = M.getOrInsertFunction("__cmplog_ins_hook8", VoidTy, Int64Ty, Int64Ty,
230*08b48e0bSAndroid Build Coastguard Worker                                  Int8Ty
231*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR < 5
232*08b48e0bSAndroid Build Coastguard Worker                                  ,
233*08b48e0bSAndroid Build Coastguard Worker                                  NULL
234*08b48e0bSAndroid Build Coastguard Worker #endif
235*08b48e0bSAndroid Build Coastguard Worker       );
236*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 9
237*08b48e0bSAndroid Build Coastguard Worker   FunctionCallee cmplogHookIns8 = c8;
238*08b48e0bSAndroid Build Coastguard Worker #else
239*08b48e0bSAndroid Build Coastguard Worker   Function *cmplogHookIns8 = cast<Function>(c8);
240*08b48e0bSAndroid Build Coastguard Worker #endif
241*08b48e0bSAndroid Build Coastguard Worker 
242*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 9
243*08b48e0bSAndroid Build Coastguard Worker   FunctionCallee
244*08b48e0bSAndroid Build Coastguard Worker #else
245*08b48e0bSAndroid Build Coastguard Worker   Constant *
246*08b48e0bSAndroid Build Coastguard Worker #endif
247*08b48e0bSAndroid Build Coastguard Worker       c16 = M.getOrInsertFunction("__cmplog_ins_hook16", VoidTy, Int128Ty,
248*08b48e0bSAndroid Build Coastguard Worker                                   Int128Ty, Int8Ty
249*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR < 5
250*08b48e0bSAndroid Build Coastguard Worker                                   ,
251*08b48e0bSAndroid Build Coastguard Worker                                   NULL
252*08b48e0bSAndroid Build Coastguard Worker #endif
253*08b48e0bSAndroid Build Coastguard Worker       );
254*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR < 9
255*08b48e0bSAndroid Build Coastguard Worker   Function *cmplogHookIns16 = cast<Function>(c16);
256*08b48e0bSAndroid Build Coastguard Worker #else
257*08b48e0bSAndroid Build Coastguard Worker   FunctionCallee cmplogHookIns16 = c16;
258*08b48e0bSAndroid Build Coastguard Worker #endif
259*08b48e0bSAndroid Build Coastguard Worker 
260*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 9
261*08b48e0bSAndroid Build Coastguard Worker   FunctionCallee
262*08b48e0bSAndroid Build Coastguard Worker #else
263*08b48e0bSAndroid Build Coastguard Worker   Constant *
264*08b48e0bSAndroid Build Coastguard Worker #endif
265*08b48e0bSAndroid Build Coastguard Worker       cN = M.getOrInsertFunction("__cmplog_ins_hookN", VoidTy, Int128Ty,
266*08b48e0bSAndroid Build Coastguard Worker                                  Int128Ty, Int8Ty, Int8Ty
267*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR < 5
268*08b48e0bSAndroid Build Coastguard Worker                                  ,
269*08b48e0bSAndroid Build Coastguard Worker                                  NULL
270*08b48e0bSAndroid Build Coastguard Worker #endif
271*08b48e0bSAndroid Build Coastguard Worker       );
272*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 9
273*08b48e0bSAndroid Build Coastguard Worker   FunctionCallee cmplogHookInsN = cN;
274*08b48e0bSAndroid Build Coastguard Worker #else
275*08b48e0bSAndroid Build Coastguard Worker   Function *cmplogHookInsN = cast<Function>(cN);
276*08b48e0bSAndroid Build Coastguard Worker #endif
277*08b48e0bSAndroid Build Coastguard Worker 
278*08b48e0bSAndroid Build Coastguard Worker   GlobalVariable *AFLCmplogPtr = M.getNamedGlobal("__afl_cmp_map");
279*08b48e0bSAndroid Build Coastguard Worker 
280*08b48e0bSAndroid Build Coastguard Worker   if (!AFLCmplogPtr) {
281*08b48e0bSAndroid Build Coastguard Worker 
282*08b48e0bSAndroid Build Coastguard Worker     AFLCmplogPtr = new GlobalVariable(M, PointerType::get(Int8Ty, 0), false,
283*08b48e0bSAndroid Build Coastguard Worker                                       GlobalValue::ExternalWeakLinkage, 0,
284*08b48e0bSAndroid Build Coastguard Worker                                       "__afl_cmp_map");
285*08b48e0bSAndroid Build Coastguard Worker 
286*08b48e0bSAndroid Build Coastguard Worker   }
287*08b48e0bSAndroid Build Coastguard Worker 
288*08b48e0bSAndroid Build Coastguard Worker   Constant *Null = Constant::getNullValue(PointerType::get(Int8Ty, 0));
289*08b48e0bSAndroid Build Coastguard Worker 
290*08b48e0bSAndroid Build Coastguard Worker   /* iterate over all functions, bbs and instruction and add suitable calls */
291*08b48e0bSAndroid Build Coastguard Worker   for (auto &F : M) {
292*08b48e0bSAndroid Build Coastguard Worker 
293*08b48e0bSAndroid Build Coastguard Worker     if (!isInInstrumentList(&F, MNAME)) continue;
294*08b48e0bSAndroid Build Coastguard Worker 
295*08b48e0bSAndroid Build Coastguard Worker     for (auto &BB : F) {
296*08b48e0bSAndroid Build Coastguard Worker 
297*08b48e0bSAndroid Build Coastguard Worker       for (auto &IN : BB) {
298*08b48e0bSAndroid Build Coastguard Worker 
299*08b48e0bSAndroid Build Coastguard Worker         CmpInst *selectcmpInst = nullptr;
300*08b48e0bSAndroid Build Coastguard Worker         if ((selectcmpInst = dyn_cast<CmpInst>(&IN))) {
301*08b48e0bSAndroid Build Coastguard Worker 
302*08b48e0bSAndroid Build Coastguard Worker           icomps.push_back(selectcmpInst);
303*08b48e0bSAndroid Build Coastguard Worker 
304*08b48e0bSAndroid Build Coastguard Worker         }
305*08b48e0bSAndroid Build Coastguard Worker 
306*08b48e0bSAndroid Build Coastguard Worker       }
307*08b48e0bSAndroid Build Coastguard Worker 
308*08b48e0bSAndroid Build Coastguard Worker     }
309*08b48e0bSAndroid Build Coastguard Worker 
310*08b48e0bSAndroid Build Coastguard Worker   }
311*08b48e0bSAndroid Build Coastguard Worker 
312*08b48e0bSAndroid Build Coastguard Worker   if (icomps.size()) {
313*08b48e0bSAndroid Build Coastguard Worker 
314*08b48e0bSAndroid Build Coastguard Worker     // if (!be_quiet) errs() << "Hooking " << icomps.size() <<
315*08b48e0bSAndroid Build Coastguard Worker     //                          " cmp instructions\n";
316*08b48e0bSAndroid Build Coastguard Worker 
317*08b48e0bSAndroid Build Coastguard Worker     for (auto &selectcmpInst : icomps) {
318*08b48e0bSAndroid Build Coastguard Worker 
319*08b48e0bSAndroid Build Coastguard Worker       IRBuilder<> IRB2(selectcmpInst->getParent());
320*08b48e0bSAndroid Build Coastguard Worker       IRB2.SetInsertPoint(selectcmpInst);
321*08b48e0bSAndroid Build Coastguard Worker       LoadInst *CmpPtr = IRB2.CreateLoad(
322*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 14
323*08b48e0bSAndroid Build Coastguard Worker           PointerType::get(Int8Ty, 0),
324*08b48e0bSAndroid Build Coastguard Worker #endif
325*08b48e0bSAndroid Build Coastguard Worker           AFLCmplogPtr);
326*08b48e0bSAndroid Build Coastguard Worker       CmpPtr->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None));
327*08b48e0bSAndroid Build Coastguard Worker       auto is_not_null = IRB2.CreateICmpNE(CmpPtr, Null);
328*08b48e0bSAndroid Build Coastguard Worker       auto ThenTerm =
329*08b48e0bSAndroid Build Coastguard Worker           SplitBlockAndInsertIfThen(is_not_null, selectcmpInst, false);
330*08b48e0bSAndroid Build Coastguard Worker 
331*08b48e0bSAndroid Build Coastguard Worker       IRBuilder<> IRB(ThenTerm);
332*08b48e0bSAndroid Build Coastguard Worker 
333*08b48e0bSAndroid Build Coastguard Worker       Value *op0 = selectcmpInst->getOperand(0);
334*08b48e0bSAndroid Build Coastguard Worker       Value *op1 = selectcmpInst->getOperand(1);
335*08b48e0bSAndroid Build Coastguard Worker       Value *op0_saved = op0, *op1_saved = op1;
336*08b48e0bSAndroid Build Coastguard Worker       auto   ty0 = op0->getType();
337*08b48e0bSAndroid Build Coastguard Worker       auto   ty1 = op1->getType();
338*08b48e0bSAndroid Build Coastguard Worker 
339*08b48e0bSAndroid Build Coastguard Worker       IntegerType *intTyOp0 = NULL;
340*08b48e0bSAndroid Build Coastguard Worker       IntegerType *intTyOp1 = NULL;
341*08b48e0bSAndroid Build Coastguard Worker       unsigned     max_size = 0, cast_size = 0;
342*08b48e0bSAndroid Build Coastguard Worker       unsigned     attr = 0, vector_cnt = 0, is_fp = 0;
343*08b48e0bSAndroid Build Coastguard Worker       CmpInst     *cmpInst = dyn_cast<CmpInst>(selectcmpInst);
344*08b48e0bSAndroid Build Coastguard Worker 
345*08b48e0bSAndroid Build Coastguard Worker       if (!cmpInst) { continue; }
346*08b48e0bSAndroid Build Coastguard Worker 
347*08b48e0bSAndroid Build Coastguard Worker       switch (cmpInst->getPredicate()) {
348*08b48e0bSAndroid Build Coastguard Worker 
349*08b48e0bSAndroid Build Coastguard Worker         case CmpInst::ICMP_NE:
350*08b48e0bSAndroid Build Coastguard Worker         case CmpInst::FCMP_UNE:
351*08b48e0bSAndroid Build Coastguard Worker         case CmpInst::FCMP_ONE:
352*08b48e0bSAndroid Build Coastguard Worker           break;
353*08b48e0bSAndroid Build Coastguard Worker         case CmpInst::ICMP_EQ:
354*08b48e0bSAndroid Build Coastguard Worker         case CmpInst::FCMP_UEQ:
355*08b48e0bSAndroid Build Coastguard Worker         case CmpInst::FCMP_OEQ:
356*08b48e0bSAndroid Build Coastguard Worker           attr += 1;
357*08b48e0bSAndroid Build Coastguard Worker           break;
358*08b48e0bSAndroid Build Coastguard Worker         case CmpInst::ICMP_UGT:
359*08b48e0bSAndroid Build Coastguard Worker         case CmpInst::ICMP_SGT:
360*08b48e0bSAndroid Build Coastguard Worker         case CmpInst::FCMP_OGT:
361*08b48e0bSAndroid Build Coastguard Worker         case CmpInst::FCMP_UGT:
362*08b48e0bSAndroid Build Coastguard Worker           attr += 2;
363*08b48e0bSAndroid Build Coastguard Worker           break;
364*08b48e0bSAndroid Build Coastguard Worker         case CmpInst::ICMP_UGE:
365*08b48e0bSAndroid Build Coastguard Worker         case CmpInst::ICMP_SGE:
366*08b48e0bSAndroid Build Coastguard Worker         case CmpInst::FCMP_OGE:
367*08b48e0bSAndroid Build Coastguard Worker         case CmpInst::FCMP_UGE:
368*08b48e0bSAndroid Build Coastguard Worker           attr += 3;
369*08b48e0bSAndroid Build Coastguard Worker           break;
370*08b48e0bSAndroid Build Coastguard Worker         case CmpInst::ICMP_ULT:
371*08b48e0bSAndroid Build Coastguard Worker         case CmpInst::ICMP_SLT:
372*08b48e0bSAndroid Build Coastguard Worker         case CmpInst::FCMP_OLT:
373*08b48e0bSAndroid Build Coastguard Worker         case CmpInst::FCMP_ULT:
374*08b48e0bSAndroid Build Coastguard Worker           attr += 4;
375*08b48e0bSAndroid Build Coastguard Worker           break;
376*08b48e0bSAndroid Build Coastguard Worker         case CmpInst::ICMP_ULE:
377*08b48e0bSAndroid Build Coastguard Worker         case CmpInst::ICMP_SLE:
378*08b48e0bSAndroid Build Coastguard Worker         case CmpInst::FCMP_OLE:
379*08b48e0bSAndroid Build Coastguard Worker         case CmpInst::FCMP_ULE:
380*08b48e0bSAndroid Build Coastguard Worker           attr += 5;
381*08b48e0bSAndroid Build Coastguard Worker           break;
382*08b48e0bSAndroid Build Coastguard Worker         default:
383*08b48e0bSAndroid Build Coastguard Worker           break;
384*08b48e0bSAndroid Build Coastguard Worker 
385*08b48e0bSAndroid Build Coastguard Worker       }
386*08b48e0bSAndroid Build Coastguard Worker 
387*08b48e0bSAndroid Build Coastguard Worker       if (selectcmpInst->getOpcode() == Instruction::FCmp) {
388*08b48e0bSAndroid Build Coastguard Worker 
389*08b48e0bSAndroid Build Coastguard Worker         if (ty0->isVectorTy()) {
390*08b48e0bSAndroid Build Coastguard Worker 
391*08b48e0bSAndroid Build Coastguard Worker           VectorType *tt = dyn_cast<VectorType>(ty0);
392*08b48e0bSAndroid Build Coastguard Worker           if (!tt) {
393*08b48e0bSAndroid Build Coastguard Worker 
394*08b48e0bSAndroid Build Coastguard Worker             fprintf(stderr, "Warning: cmplog cmp vector is not a vector!\n");
395*08b48e0bSAndroid Build Coastguard Worker             continue;
396*08b48e0bSAndroid Build Coastguard Worker 
397*08b48e0bSAndroid Build Coastguard Worker           }
398*08b48e0bSAndroid Build Coastguard Worker 
399*08b48e0bSAndroid Build Coastguard Worker #if (LLVM_VERSION_MAJOR >= 12)
400*08b48e0bSAndroid Build Coastguard Worker           vector_cnt = tt->getElementCount().getKnownMinValue();
401*08b48e0bSAndroid Build Coastguard Worker           ty0 = tt->getElementType();
402*08b48e0bSAndroid Build Coastguard Worker #endif
403*08b48e0bSAndroid Build Coastguard Worker 
404*08b48e0bSAndroid Build Coastguard Worker         }
405*08b48e0bSAndroid Build Coastguard Worker 
406*08b48e0bSAndroid Build Coastguard Worker         if (ty0->isHalfTy()
407*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 11
408*08b48e0bSAndroid Build Coastguard Worker             || ty0->isBFloatTy()
409*08b48e0bSAndroid Build Coastguard Worker #endif
410*08b48e0bSAndroid Build Coastguard Worker         )
411*08b48e0bSAndroid Build Coastguard Worker           max_size = 16;
412*08b48e0bSAndroid Build Coastguard Worker         else if (ty0->isFloatTy())
413*08b48e0bSAndroid Build Coastguard Worker           max_size = 32;
414*08b48e0bSAndroid Build Coastguard Worker         else if (ty0->isDoubleTy())
415*08b48e0bSAndroid Build Coastguard Worker           max_size = 64;
416*08b48e0bSAndroid Build Coastguard Worker         else if (ty0->isX86_FP80Ty())
417*08b48e0bSAndroid Build Coastguard Worker           max_size = 80;
418*08b48e0bSAndroid Build Coastguard Worker         else if (ty0->isFP128Ty() || ty0->isPPC_FP128Ty())
419*08b48e0bSAndroid Build Coastguard Worker           max_size = 128;
420*08b48e0bSAndroid Build Coastguard Worker #if (LLVM_VERSION_MAJOR >= 12)
421*08b48e0bSAndroid Build Coastguard Worker         else if (ty0->getTypeID() != llvm::Type::PointerTyID && !be_quiet)
422*08b48e0bSAndroid Build Coastguard Worker           fprintf(stderr, "Warning: unsupported cmp type for cmplog: %u!\n",
423*08b48e0bSAndroid Build Coastguard Worker                   ty0->getTypeID());
424*08b48e0bSAndroid Build Coastguard Worker #endif
425*08b48e0bSAndroid Build Coastguard Worker 
426*08b48e0bSAndroid Build Coastguard Worker         attr += 8;
427*08b48e0bSAndroid Build Coastguard Worker         is_fp = 1;
428*08b48e0bSAndroid Build Coastguard Worker         // fprintf(stderr, "HAVE FP %u!\n", vector_cnt);
429*08b48e0bSAndroid Build Coastguard Worker 
430*08b48e0bSAndroid Build Coastguard Worker       } else {
431*08b48e0bSAndroid Build Coastguard Worker 
432*08b48e0bSAndroid Build Coastguard Worker         if (ty0->isVectorTy()) {
433*08b48e0bSAndroid Build Coastguard Worker 
434*08b48e0bSAndroid Build Coastguard Worker #if (LLVM_VERSION_MAJOR >= 12)
435*08b48e0bSAndroid Build Coastguard Worker           VectorType *tt = dyn_cast<VectorType>(ty0);
436*08b48e0bSAndroid Build Coastguard Worker           if (!tt) {
437*08b48e0bSAndroid Build Coastguard Worker 
438*08b48e0bSAndroid Build Coastguard Worker             fprintf(stderr, "Warning: cmplog cmp vector is not a vector!\n");
439*08b48e0bSAndroid Build Coastguard Worker             continue;
440*08b48e0bSAndroid Build Coastguard Worker 
441*08b48e0bSAndroid Build Coastguard Worker           }
442*08b48e0bSAndroid Build Coastguard Worker 
443*08b48e0bSAndroid Build Coastguard Worker           vector_cnt = tt->getElementCount().getKnownMinValue();
444*08b48e0bSAndroid Build Coastguard Worker           ty1 = ty0 = tt->getElementType();
445*08b48e0bSAndroid Build Coastguard Worker #endif
446*08b48e0bSAndroid Build Coastguard Worker 
447*08b48e0bSAndroid Build Coastguard Worker         }
448*08b48e0bSAndroid Build Coastguard Worker 
449*08b48e0bSAndroid Build Coastguard Worker         intTyOp0 = dyn_cast<IntegerType>(ty0);
450*08b48e0bSAndroid Build Coastguard Worker         intTyOp1 = dyn_cast<IntegerType>(ty1);
451*08b48e0bSAndroid Build Coastguard Worker 
452*08b48e0bSAndroid Build Coastguard Worker         if (intTyOp0 && intTyOp1) {
453*08b48e0bSAndroid Build Coastguard Worker 
454*08b48e0bSAndroid Build Coastguard Worker           max_size = intTyOp0->getBitWidth() > intTyOp1->getBitWidth()
455*08b48e0bSAndroid Build Coastguard Worker                          ? intTyOp0->getBitWidth()
456*08b48e0bSAndroid Build Coastguard Worker                          : intTyOp1->getBitWidth();
457*08b48e0bSAndroid Build Coastguard Worker 
458*08b48e0bSAndroid Build Coastguard Worker         } else {
459*08b48e0bSAndroid Build Coastguard Worker 
460*08b48e0bSAndroid Build Coastguard Worker #if (LLVM_VERSION_MAJOR >= 12)
461*08b48e0bSAndroid Build Coastguard Worker           if (ty0->getTypeID() != llvm::Type::PointerTyID && !be_quiet) {
462*08b48e0bSAndroid Build Coastguard Worker 
463*08b48e0bSAndroid Build Coastguard Worker             fprintf(stderr, "Warning: unsupported cmp type for cmplog: %u\n",
464*08b48e0bSAndroid Build Coastguard Worker                     ty0->getTypeID());
465*08b48e0bSAndroid Build Coastguard Worker 
466*08b48e0bSAndroid Build Coastguard Worker           }
467*08b48e0bSAndroid Build Coastguard Worker 
468*08b48e0bSAndroid Build Coastguard Worker #endif
469*08b48e0bSAndroid Build Coastguard Worker 
470*08b48e0bSAndroid Build Coastguard Worker         }
471*08b48e0bSAndroid Build Coastguard Worker 
472*08b48e0bSAndroid Build Coastguard Worker       }
473*08b48e0bSAndroid Build Coastguard Worker 
474*08b48e0bSAndroid Build Coastguard Worker       if (!max_size || max_size < 16) {
475*08b48e0bSAndroid Build Coastguard Worker 
476*08b48e0bSAndroid Build Coastguard Worker         // fprintf(stderr, "too small\n");
477*08b48e0bSAndroid Build Coastguard Worker         continue;
478*08b48e0bSAndroid Build Coastguard Worker 
479*08b48e0bSAndroid Build Coastguard Worker       }
480*08b48e0bSAndroid Build Coastguard Worker 
481*08b48e0bSAndroid Build Coastguard Worker       if (max_size % 8) { max_size = (((max_size / 8) + 1) * 8); }
482*08b48e0bSAndroid Build Coastguard Worker 
483*08b48e0bSAndroid Build Coastguard Worker       if (max_size > 128) {
484*08b48e0bSAndroid Build Coastguard Worker 
485*08b48e0bSAndroid Build Coastguard Worker         if (!be_quiet) {
486*08b48e0bSAndroid Build Coastguard Worker 
487*08b48e0bSAndroid Build Coastguard Worker           fprintf(stderr,
488*08b48e0bSAndroid Build Coastguard Worker                   "Cannot handle this compare bit size: %u (truncating)\n",
489*08b48e0bSAndroid Build Coastguard Worker                   max_size);
490*08b48e0bSAndroid Build Coastguard Worker 
491*08b48e0bSAndroid Build Coastguard Worker         }
492*08b48e0bSAndroid Build Coastguard Worker 
493*08b48e0bSAndroid Build Coastguard Worker         max_size = 128;
494*08b48e0bSAndroid Build Coastguard Worker 
495*08b48e0bSAndroid Build Coastguard Worker       }
496*08b48e0bSAndroid Build Coastguard Worker 
497*08b48e0bSAndroid Build Coastguard Worker       // do we need to cast?
498*08b48e0bSAndroid Build Coastguard Worker       switch (max_size) {
499*08b48e0bSAndroid Build Coastguard Worker 
500*08b48e0bSAndroid Build Coastguard Worker         case 8:
501*08b48e0bSAndroid Build Coastguard Worker         case 16:
502*08b48e0bSAndroid Build Coastguard Worker         case 32:
503*08b48e0bSAndroid Build Coastguard Worker         case 64:
504*08b48e0bSAndroid Build Coastguard Worker         case 128:
505*08b48e0bSAndroid Build Coastguard Worker           cast_size = max_size;
506*08b48e0bSAndroid Build Coastguard Worker           break;
507*08b48e0bSAndroid Build Coastguard Worker         default:
508*08b48e0bSAndroid Build Coastguard Worker           cast_size = 128;
509*08b48e0bSAndroid Build Coastguard Worker 
510*08b48e0bSAndroid Build Coastguard Worker       }
511*08b48e0bSAndroid Build Coastguard Worker 
512*08b48e0bSAndroid Build Coastguard Worker       // XXX FIXME BUG TODO
513*08b48e0bSAndroid Build Coastguard Worker       if (is_fp && vector_cnt) { continue; }
514*08b48e0bSAndroid Build Coastguard Worker 
515*08b48e0bSAndroid Build Coastguard Worker       uint64_t cur = 0, last_val0 = 0, last_val1 = 0, cur_val;
516*08b48e0bSAndroid Build Coastguard Worker 
517*08b48e0bSAndroid Build Coastguard Worker       while (1) {
518*08b48e0bSAndroid Build Coastguard Worker 
519*08b48e0bSAndroid Build Coastguard Worker         std::vector<Value *> args;
520*08b48e0bSAndroid Build Coastguard Worker         bool                 skip = false;
521*08b48e0bSAndroid Build Coastguard Worker 
522*08b48e0bSAndroid Build Coastguard Worker         if (vector_cnt) {
523*08b48e0bSAndroid Build Coastguard Worker 
524*08b48e0bSAndroid Build Coastguard Worker           op0 = IRB.CreateExtractElement(op0_saved, cur);
525*08b48e0bSAndroid Build Coastguard Worker           op1 = IRB.CreateExtractElement(op1_saved, cur);
526*08b48e0bSAndroid Build Coastguard Worker           /*
527*08b48e0bSAndroid Build Coastguard Worker           std::string errMsg;
528*08b48e0bSAndroid Build Coastguard Worker           raw_string_ostream os(errMsg);
529*08b48e0bSAndroid Build Coastguard Worker           op0_saved->print(os);
530*08b48e0bSAndroid Build Coastguard Worker           fprintf(stderr, "X: %s\n", os.str().c_str());
531*08b48e0bSAndroid Build Coastguard Worker           */
532*08b48e0bSAndroid Build Coastguard Worker           if (is_fp) {
533*08b48e0bSAndroid Build Coastguard Worker 
534*08b48e0bSAndroid Build Coastguard Worker             /*
535*08b48e0bSAndroid Build Coastguard Worker                         ConstantFP *i0 = dyn_cast<ConstantFP>(op0);
536*08b48e0bSAndroid Build Coastguard Worker                         ConstantFP *i1 = dyn_cast<ConstantFP>(op1);
537*08b48e0bSAndroid Build Coastguard Worker                         // BUG FIXME TODO: this is null ... but why?
538*08b48e0bSAndroid Build Coastguard Worker                         // fprintf(stderr, "%p %p\n", i0, i1);
539*08b48e0bSAndroid Build Coastguard Worker                         if (i0) {
540*08b48e0bSAndroid Build Coastguard Worker 
541*08b48e0bSAndroid Build Coastguard Worker                           cur_val = (uint64_t)i0->getValue().convertToDouble();
542*08b48e0bSAndroid Build Coastguard Worker                           if (last_val0 && last_val0 == cur_val) { skip = true;
543*08b48e0bSAndroid Build Coastguard Worker 
544*08b48e0bSAndroid Build Coastguard Worker                } last_val0 = cur_val;
545*08b48e0bSAndroid Build Coastguard Worker 
546*08b48e0bSAndroid Build Coastguard Worker                         }
547*08b48e0bSAndroid Build Coastguard Worker 
548*08b48e0bSAndroid Build Coastguard Worker                         if (i1) {
549*08b48e0bSAndroid Build Coastguard Worker 
550*08b48e0bSAndroid Build Coastguard Worker                           cur_val = (uint64_t)i1->getValue().convertToDouble();
551*08b48e0bSAndroid Build Coastguard Worker                           if (last_val1 && last_val1 == cur_val) { skip = true;
552*08b48e0bSAndroid Build Coastguard Worker 
553*08b48e0bSAndroid Build Coastguard Worker                } last_val1 = cur_val;
554*08b48e0bSAndroid Build Coastguard Worker 
555*08b48e0bSAndroid Build Coastguard Worker                         }
556*08b48e0bSAndroid Build Coastguard Worker 
557*08b48e0bSAndroid Build Coastguard Worker             */
558*08b48e0bSAndroid Build Coastguard Worker 
559*08b48e0bSAndroid Build Coastguard Worker           } else {
560*08b48e0bSAndroid Build Coastguard Worker 
561*08b48e0bSAndroid Build Coastguard Worker             ConstantInt *i0 = dyn_cast<ConstantInt>(op0);
562*08b48e0bSAndroid Build Coastguard Worker             ConstantInt *i1 = dyn_cast<ConstantInt>(op1);
563*08b48e0bSAndroid Build Coastguard Worker             if (i0 && i0->uge(0xffffffffffffffff) == false) {
564*08b48e0bSAndroid Build Coastguard Worker 
565*08b48e0bSAndroid Build Coastguard Worker               cur_val = i0->getZExtValue();
566*08b48e0bSAndroid Build Coastguard Worker               if (last_val0 && last_val0 == cur_val) { skip = true; }
567*08b48e0bSAndroid Build Coastguard Worker               last_val0 = cur_val;
568*08b48e0bSAndroid Build Coastguard Worker 
569*08b48e0bSAndroid Build Coastguard Worker             }
570*08b48e0bSAndroid Build Coastguard Worker 
571*08b48e0bSAndroid Build Coastguard Worker             if (i1 && i1->uge(0xffffffffffffffff) == false) {
572*08b48e0bSAndroid Build Coastguard Worker 
573*08b48e0bSAndroid Build Coastguard Worker               cur_val = i1->getZExtValue();
574*08b48e0bSAndroid Build Coastguard Worker               if (last_val1 && last_val1 == cur_val) { skip = true; }
575*08b48e0bSAndroid Build Coastguard Worker               last_val1 = cur_val;
576*08b48e0bSAndroid Build Coastguard Worker 
577*08b48e0bSAndroid Build Coastguard Worker             }
578*08b48e0bSAndroid Build Coastguard Worker 
579*08b48e0bSAndroid Build Coastguard Worker           }
580*08b48e0bSAndroid Build Coastguard Worker 
581*08b48e0bSAndroid Build Coastguard Worker         }
582*08b48e0bSAndroid Build Coastguard Worker 
583*08b48e0bSAndroid Build Coastguard Worker         if (!skip) {
584*08b48e0bSAndroid Build Coastguard Worker 
585*08b48e0bSAndroid Build Coastguard Worker           // errs() << "[CMPLOG] cmp  " << *cmpInst << "(in function " <<
586*08b48e0bSAndroid Build Coastguard Worker           // cmpInst->getFunction()->getName() << ")\n";
587*08b48e0bSAndroid Build Coastguard Worker 
588*08b48e0bSAndroid Build Coastguard Worker           // first bitcast to integer type of the same bitsize as the original
589*08b48e0bSAndroid Build Coastguard Worker           // type (this is a nop, if already integer)
590*08b48e0bSAndroid Build Coastguard Worker           Value *op0_i = IRB.CreateBitCast(
591*08b48e0bSAndroid Build Coastguard Worker               op0, IntegerType::get(C, ty0->getPrimitiveSizeInBits()));
592*08b48e0bSAndroid Build Coastguard Worker           // then create a int cast, which does zext, trunc or bitcast. In our
593*08b48e0bSAndroid Build Coastguard Worker           // case usually zext to the next larger supported type (this is a nop
594*08b48e0bSAndroid Build Coastguard Worker           // if already the right type)
595*08b48e0bSAndroid Build Coastguard Worker           Value *V0 =
596*08b48e0bSAndroid Build Coastguard Worker               IRB.CreateIntCast(op0_i, IntegerType::get(C, cast_size), false);
597*08b48e0bSAndroid Build Coastguard Worker           args.push_back(V0);
598*08b48e0bSAndroid Build Coastguard Worker           Value *op1_i = IRB.CreateBitCast(
599*08b48e0bSAndroid Build Coastguard Worker               op1, IntegerType::get(C, ty1->getPrimitiveSizeInBits()));
600*08b48e0bSAndroid Build Coastguard Worker           Value *V1 =
601*08b48e0bSAndroid Build Coastguard Worker               IRB.CreateIntCast(op1_i, IntegerType::get(C, cast_size), false);
602*08b48e0bSAndroid Build Coastguard Worker           args.push_back(V1);
603*08b48e0bSAndroid Build Coastguard Worker 
604*08b48e0bSAndroid Build Coastguard Worker           // errs() << "[CMPLOG] casted parameters:\n0: " << *V0 << "\n1: " <<
605*08b48e0bSAndroid Build Coastguard Worker           // *V1
606*08b48e0bSAndroid Build Coastguard Worker           // << "\n";
607*08b48e0bSAndroid Build Coastguard Worker 
608*08b48e0bSAndroid Build Coastguard Worker           ConstantInt *attribute = ConstantInt::get(Int8Ty, attr);
609*08b48e0bSAndroid Build Coastguard Worker           args.push_back(attribute);
610*08b48e0bSAndroid Build Coastguard Worker 
611*08b48e0bSAndroid Build Coastguard Worker           if (cast_size != max_size) {
612*08b48e0bSAndroid Build Coastguard Worker 
613*08b48e0bSAndroid Build Coastguard Worker             ConstantInt *bitsize = ConstantInt::get(Int8Ty, (max_size / 8) - 1);
614*08b48e0bSAndroid Build Coastguard Worker             args.push_back(bitsize);
615*08b48e0bSAndroid Build Coastguard Worker 
616*08b48e0bSAndroid Build Coastguard Worker           }
617*08b48e0bSAndroid Build Coastguard Worker 
618*08b48e0bSAndroid Build Coastguard Worker           // fprintf(stderr, "_ExtInt(%u) castTo %u with attr %u didcast %u\n",
619*08b48e0bSAndroid Build Coastguard Worker           //         max_size, cast_size, attr);
620*08b48e0bSAndroid Build Coastguard Worker 
621*08b48e0bSAndroid Build Coastguard Worker           switch (cast_size) {
622*08b48e0bSAndroid Build Coastguard Worker 
623*08b48e0bSAndroid Build Coastguard Worker             case 8:
624*08b48e0bSAndroid Build Coastguard Worker               // IRB.CreateCall(cmplogHookIns1, args);
625*08b48e0bSAndroid Build Coastguard Worker               break;
626*08b48e0bSAndroid Build Coastguard Worker             case 16:
627*08b48e0bSAndroid Build Coastguard Worker               IRB.CreateCall(cmplogHookIns2, args);
628*08b48e0bSAndroid Build Coastguard Worker               break;
629*08b48e0bSAndroid Build Coastguard Worker             case 32:
630*08b48e0bSAndroid Build Coastguard Worker               IRB.CreateCall(cmplogHookIns4, args);
631*08b48e0bSAndroid Build Coastguard Worker               break;
632*08b48e0bSAndroid Build Coastguard Worker             case 64:
633*08b48e0bSAndroid Build Coastguard Worker               IRB.CreateCall(cmplogHookIns8, args);
634*08b48e0bSAndroid Build Coastguard Worker               break;
635*08b48e0bSAndroid Build Coastguard Worker             case 128:
636*08b48e0bSAndroid Build Coastguard Worker               if (max_size == 128) {
637*08b48e0bSAndroid Build Coastguard Worker 
638*08b48e0bSAndroid Build Coastguard Worker                 IRB.CreateCall(cmplogHookIns16, args);
639*08b48e0bSAndroid Build Coastguard Worker 
640*08b48e0bSAndroid Build Coastguard Worker               } else {
641*08b48e0bSAndroid Build Coastguard Worker 
642*08b48e0bSAndroid Build Coastguard Worker                 IRB.CreateCall(cmplogHookInsN, args);
643*08b48e0bSAndroid Build Coastguard Worker 
644*08b48e0bSAndroid Build Coastguard Worker               }
645*08b48e0bSAndroid Build Coastguard Worker 
646*08b48e0bSAndroid Build Coastguard Worker               break;
647*08b48e0bSAndroid Build Coastguard Worker 
648*08b48e0bSAndroid Build Coastguard Worker           }
649*08b48e0bSAndroid Build Coastguard Worker 
650*08b48e0bSAndroid Build Coastguard Worker         }
651*08b48e0bSAndroid Build Coastguard Worker 
652*08b48e0bSAndroid Build Coastguard Worker         /* else fprintf(stderr, "skipped\n"); */
653*08b48e0bSAndroid Build Coastguard Worker 
654*08b48e0bSAndroid Build Coastguard Worker         ++cur;
655*08b48e0bSAndroid Build Coastguard Worker         if (cur >= vector_cnt) { break; }
656*08b48e0bSAndroid Build Coastguard Worker 
657*08b48e0bSAndroid Build Coastguard Worker       }
658*08b48e0bSAndroid Build Coastguard Worker 
659*08b48e0bSAndroid Build Coastguard Worker     }
660*08b48e0bSAndroid Build Coastguard Worker 
661*08b48e0bSAndroid Build Coastguard Worker   }
662*08b48e0bSAndroid Build Coastguard Worker 
663*08b48e0bSAndroid Build Coastguard Worker   if (icomps.size())
664*08b48e0bSAndroid Build Coastguard Worker     return true;
665*08b48e0bSAndroid Build Coastguard Worker   else
666*08b48e0bSAndroid Build Coastguard Worker     return false;
667*08b48e0bSAndroid Build Coastguard Worker 
668*08b48e0bSAndroid Build Coastguard Worker }
669*08b48e0bSAndroid Build Coastguard Worker 
670*08b48e0bSAndroid Build Coastguard Worker #if LLVM_MAJOR >= 11                                /* use new pass manager */
run(Module & M,ModuleAnalysisManager & MAM)671*08b48e0bSAndroid Build Coastguard Worker PreservedAnalyses CmpLogInstructions::run(Module                &M,
672*08b48e0bSAndroid Build Coastguard Worker                                           ModuleAnalysisManager &MAM) {
673*08b48e0bSAndroid Build Coastguard Worker 
674*08b48e0bSAndroid Build Coastguard Worker #else
675*08b48e0bSAndroid Build Coastguard Worker bool CmpLogInstructions::runOnModule(Module &M) {
676*08b48e0bSAndroid Build Coastguard Worker 
677*08b48e0bSAndroid Build Coastguard Worker #endif
678*08b48e0bSAndroid Build Coastguard Worker 
679*08b48e0bSAndroid Build Coastguard Worker   if (getenv("AFL_QUIET") == NULL)
680*08b48e0bSAndroid Build Coastguard Worker     printf("Running cmplog-instructions-pass by [email protected]\n");
681*08b48e0bSAndroid Build Coastguard Worker   else
682*08b48e0bSAndroid Build Coastguard Worker     be_quiet = 1;
683*08b48e0bSAndroid Build Coastguard Worker   hookInstrs(M);
684*08b48e0bSAndroid Build Coastguard Worker   verifyModule(M);
685*08b48e0bSAndroid Build Coastguard Worker 
686*08b48e0bSAndroid Build Coastguard Worker #if LLVM_MAJOR >= 11                                /* use new pass manager */
687*08b48e0bSAndroid Build Coastguard Worker   return PreservedAnalyses::all();
688*08b48e0bSAndroid Build Coastguard Worker #else
689*08b48e0bSAndroid Build Coastguard Worker   return true;
690*08b48e0bSAndroid Build Coastguard Worker #endif
691*08b48e0bSAndroid Build Coastguard Worker 
692*08b48e0bSAndroid Build Coastguard Worker }
693*08b48e0bSAndroid Build Coastguard Worker 
694*08b48e0bSAndroid Build Coastguard Worker #if LLVM_MAJOR < 11                                 /* use old pass manager */
695*08b48e0bSAndroid Build Coastguard Worker static void registerCmpLogInstructionsPass(const PassManagerBuilder &,
696*08b48e0bSAndroid Build Coastguard Worker                                            legacy::PassManagerBase &PM) {
697*08b48e0bSAndroid Build Coastguard Worker 
698*08b48e0bSAndroid Build Coastguard Worker   auto p = new CmpLogInstructions();
699*08b48e0bSAndroid Build Coastguard Worker   PM.add(p);
700*08b48e0bSAndroid Build Coastguard Worker 
701*08b48e0bSAndroid Build Coastguard Worker }
702*08b48e0bSAndroid Build Coastguard Worker 
703*08b48e0bSAndroid Build Coastguard Worker static RegisterStandardPasses RegisterCmpLogInstructionsPass(
704*08b48e0bSAndroid Build Coastguard Worker     PassManagerBuilder::EP_OptimizerLast, registerCmpLogInstructionsPass);
705*08b48e0bSAndroid Build Coastguard Worker 
706*08b48e0bSAndroid Build Coastguard Worker static RegisterStandardPasses RegisterCmpLogInstructionsPass0(
707*08b48e0bSAndroid Build Coastguard Worker     PassManagerBuilder::EP_EnabledOnOptLevel0, registerCmpLogInstructionsPass);
708*08b48e0bSAndroid Build Coastguard Worker 
709*08b48e0bSAndroid Build Coastguard Worker   #if LLVM_VERSION_MAJOR >= 11
710*08b48e0bSAndroid Build Coastguard Worker static RegisterStandardPasses RegisterCmpLogInstructionsPassLTO(
711*08b48e0bSAndroid Build Coastguard Worker     PassManagerBuilder::EP_FullLinkTimeOptimizationLast,
712*08b48e0bSAndroid Build Coastguard Worker     registerCmpLogInstructionsPass);
713*08b48e0bSAndroid Build Coastguard Worker   #endif
714*08b48e0bSAndroid Build Coastguard Worker #endif
715*08b48e0bSAndroid Build Coastguard Worker 
716