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