xref: /aosp_15_r20/external/AFLplusplus/instrumentation/cmplog-routines-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 <list>
23*08b48e0bSAndroid Build Coastguard Worker #include <string>
24*08b48e0bSAndroid Build Coastguard Worker #include <fstream>
25*08b48e0bSAndroid Build Coastguard Worker #include <sys/time.h>
26*08b48e0bSAndroid Build Coastguard Worker #include "llvm/Config/llvm-config.h"
27*08b48e0bSAndroid Build Coastguard Worker 
28*08b48e0bSAndroid Build Coastguard Worker #include "llvm/ADT/Statistic.h"
29*08b48e0bSAndroid Build Coastguard Worker #include "llvm/IR/IRBuilder.h"
30*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 11                        /* use new pass manager */
31*08b48e0bSAndroid Build Coastguard Worker   #include "llvm/Passes/PassPlugin.h"
32*08b48e0bSAndroid Build Coastguard Worker   #include "llvm/Passes/PassBuilder.h"
33*08b48e0bSAndroid Build Coastguard Worker   #include "llvm/IR/PassManager.h"
34*08b48e0bSAndroid Build Coastguard Worker #else
35*08b48e0bSAndroid Build Coastguard Worker   #include "llvm/IR/LegacyPassManager.h"
36*08b48e0bSAndroid Build Coastguard Worker   #include "llvm/Transforms/IPO/PassManagerBuilder.h"
37*08b48e0bSAndroid Build Coastguard Worker #endif
38*08b48e0bSAndroid Build Coastguard Worker #include "llvm/IR/Module.h"
39*08b48e0bSAndroid Build Coastguard Worker #include "llvm/Support/Debug.h"
40*08b48e0bSAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
41*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR < 17
42*08b48e0bSAndroid Build Coastguard Worker   #include "llvm/Transforms/IPO/PassManagerBuilder.h"
43*08b48e0bSAndroid Build Coastguard Worker #endif
44*08b48e0bSAndroid Build Coastguard Worker #include "llvm/Transforms/Utils/BasicBlockUtils.h"
45*08b48e0bSAndroid Build Coastguard Worker #include "llvm/Pass.h"
46*08b48e0bSAndroid Build Coastguard Worker #include "llvm/Analysis/ValueTracking.h"
47*08b48e0bSAndroid Build Coastguard Worker 
48*08b48e0bSAndroid Build Coastguard Worker #include "llvm/IR/IRBuilder.h"
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 #else
54*08b48e0bSAndroid Build Coastguard Worker   #include "llvm/Analysis/Verifier.h"
55*08b48e0bSAndroid Build Coastguard Worker   #include "llvm/DebugInfo.h"
56*08b48e0bSAndroid Build Coastguard Worker   #define nullptr 0
57*08b48e0bSAndroid Build Coastguard Worker #endif
58*08b48e0bSAndroid Build Coastguard Worker 
59*08b48e0bSAndroid Build Coastguard Worker #include <set>
60*08b48e0bSAndroid Build Coastguard Worker #include "afl-llvm-common.h"
61*08b48e0bSAndroid Build Coastguard Worker 
62*08b48e0bSAndroid Build Coastguard Worker using namespace llvm;
63*08b48e0bSAndroid Build Coastguard Worker 
64*08b48e0bSAndroid Build Coastguard Worker namespace {
65*08b48e0bSAndroid Build Coastguard Worker 
66*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 11                        /* use new pass manager */
67*08b48e0bSAndroid Build Coastguard Worker class CmpLogRoutines : public PassInfoMixin<CmpLogRoutines> {
68*08b48e0bSAndroid Build Coastguard Worker 
69*08b48e0bSAndroid Build Coastguard Worker  public:
CmpLogRoutines()70*08b48e0bSAndroid Build Coastguard Worker   CmpLogRoutines() {
71*08b48e0bSAndroid Build Coastguard Worker 
72*08b48e0bSAndroid Build Coastguard Worker #else
73*08b48e0bSAndroid Build Coastguard Worker class CmpLogRoutines : public ModulePass {
74*08b48e0bSAndroid Build Coastguard Worker 
75*08b48e0bSAndroid Build Coastguard Worker  public:
76*08b48e0bSAndroid Build Coastguard Worker   static char ID;
77*08b48e0bSAndroid Build Coastguard Worker   CmpLogRoutines() : ModulePass(ID) {
78*08b48e0bSAndroid Build Coastguard Worker 
79*08b48e0bSAndroid Build Coastguard Worker #endif
80*08b48e0bSAndroid Build Coastguard Worker 
81*08b48e0bSAndroid Build Coastguard Worker     initInstrumentList();
82*08b48e0bSAndroid Build Coastguard Worker 
83*08b48e0bSAndroid Build Coastguard Worker   }
84*08b48e0bSAndroid Build Coastguard Worker 
85*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 11                        /* use new pass manager */
86*08b48e0bSAndroid Build Coastguard Worker   PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
87*08b48e0bSAndroid Build Coastguard Worker #else
88*08b48e0bSAndroid Build Coastguard Worker   bool runOnModule(Module &M) override;
89*08b48e0bSAndroid Build Coastguard Worker 
90*08b48e0bSAndroid Build Coastguard Worker   #if LLVM_VERSION_MAJOR >= 4
91*08b48e0bSAndroid Build Coastguard Worker   StringRef getPassName() const override {
92*08b48e0bSAndroid Build Coastguard Worker 
93*08b48e0bSAndroid Build Coastguard Worker   #else
94*08b48e0bSAndroid Build Coastguard Worker   const char *getPassName() const override {
95*08b48e0bSAndroid Build Coastguard Worker 
96*08b48e0bSAndroid Build Coastguard Worker   #endif
97*08b48e0bSAndroid Build Coastguard Worker     return "cmplog routines";
98*08b48e0bSAndroid Build Coastguard Worker 
99*08b48e0bSAndroid Build Coastguard Worker   }
100*08b48e0bSAndroid Build Coastguard Worker 
101*08b48e0bSAndroid Build Coastguard Worker #endif
102*08b48e0bSAndroid Build Coastguard Worker 
103*08b48e0bSAndroid Build Coastguard Worker  private:
104*08b48e0bSAndroid Build Coastguard Worker   bool hookRtns(Module &M);
105*08b48e0bSAndroid Build Coastguard Worker 
106*08b48e0bSAndroid Build Coastguard Worker };
107*08b48e0bSAndroid Build Coastguard Worker 
108*08b48e0bSAndroid Build Coastguard Worker }  // namespace
109*08b48e0bSAndroid Build Coastguard Worker 
110*08b48e0bSAndroid Build Coastguard Worker #if LLVM_MAJOR >= 11
111*08b48e0bSAndroid Build Coastguard Worker extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK
112*08b48e0bSAndroid Build Coastguard Worker llvmGetPassPluginInfo() {
113*08b48e0bSAndroid Build Coastguard Worker 
114*08b48e0bSAndroid Build Coastguard Worker   return {LLVM_PLUGIN_API_VERSION, "cmplogroutines", "v0.1",
115*08b48e0bSAndroid Build Coastguard Worker           /* lambda to insert our pass into the pass pipeline. */
116*08b48e0bSAndroid Build Coastguard Worker           [](PassBuilder &PB) {
117*08b48e0bSAndroid Build Coastguard Worker 
118*08b48e0bSAndroid Build Coastguard Worker   #if LLVM_VERSION_MAJOR <= 13
119*08b48e0bSAndroid Build Coastguard Worker             using OptimizationLevel = typename PassBuilder::OptimizationLevel;
120*08b48e0bSAndroid Build Coastguard Worker   #endif
121*08b48e0bSAndroid Build Coastguard Worker             PB.registerOptimizerLastEPCallback(
122*08b48e0bSAndroid Build Coastguard Worker                 [](ModulePassManager &MPM, OptimizationLevel OL) {
123*08b48e0bSAndroid Build Coastguard Worker 
124*08b48e0bSAndroid Build Coastguard Worker                   MPM.addPass(CmpLogRoutines());
125*08b48e0bSAndroid Build Coastguard Worker 
126*08b48e0bSAndroid Build Coastguard Worker                 });
127*08b48e0bSAndroid Build Coastguard Worker 
128*08b48e0bSAndroid Build Coastguard Worker           }};
129*08b48e0bSAndroid Build Coastguard Worker 
130*08b48e0bSAndroid Build Coastguard Worker }
131*08b48e0bSAndroid Build Coastguard Worker 
132*08b48e0bSAndroid Build Coastguard Worker #else
133*08b48e0bSAndroid Build Coastguard Worker char CmpLogRoutines::ID = 0;
134*08b48e0bSAndroid Build Coastguard Worker #endif
135*08b48e0bSAndroid Build Coastguard Worker 
136*08b48e0bSAndroid Build Coastguard Worker bool CmpLogRoutines::hookRtns(Module &M) {
137*08b48e0bSAndroid Build Coastguard Worker 
138*08b48e0bSAndroid Build Coastguard Worker   std::vector<CallInst *> calls, llvmStdStd, llvmStdC, gccStdStd, gccStdC,
139*08b48e0bSAndroid Build Coastguard Worker       Memcmp, Strcmp, Strncmp;
140*08b48e0bSAndroid Build Coastguard Worker   LLVMContext &C = M.getContext();
141*08b48e0bSAndroid Build Coastguard Worker 
142*08b48e0bSAndroid Build Coastguard Worker   Type *VoidTy = Type::getVoidTy(C);
143*08b48e0bSAndroid Build Coastguard Worker   // PointerType *VoidPtrTy = PointerType::get(VoidTy, 0);
144*08b48e0bSAndroid Build Coastguard Worker   IntegerType *Int8Ty = IntegerType::getInt8Ty(C);
145*08b48e0bSAndroid Build Coastguard Worker   IntegerType *Int64Ty = IntegerType::getInt64Ty(C);
146*08b48e0bSAndroid Build Coastguard Worker   PointerType *i8PtrTy = PointerType::get(Int8Ty, 0);
147*08b48e0bSAndroid Build Coastguard Worker 
148*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 9
149*08b48e0bSAndroid Build Coastguard Worker   FunctionCallee
150*08b48e0bSAndroid Build Coastguard Worker #else
151*08b48e0bSAndroid Build Coastguard Worker   Constant *
152*08b48e0bSAndroid Build Coastguard Worker #endif
153*08b48e0bSAndroid Build Coastguard Worker       c = M.getOrInsertFunction("__cmplog_rtn_hook", VoidTy, i8PtrTy, i8PtrTy
154*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR < 5
155*08b48e0bSAndroid Build Coastguard Worker                                 ,
156*08b48e0bSAndroid Build Coastguard Worker                                 NULL
157*08b48e0bSAndroid Build Coastguard Worker #endif
158*08b48e0bSAndroid Build Coastguard Worker       );
159*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 9
160*08b48e0bSAndroid Build Coastguard Worker   FunctionCallee cmplogHookFn = c;
161*08b48e0bSAndroid Build Coastguard Worker #else
162*08b48e0bSAndroid Build Coastguard Worker   Function *cmplogHookFn = cast<Function>(c);
163*08b48e0bSAndroid Build Coastguard Worker #endif
164*08b48e0bSAndroid Build Coastguard Worker 
165*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 9
166*08b48e0bSAndroid Build Coastguard Worker   FunctionCallee
167*08b48e0bSAndroid Build Coastguard Worker #else
168*08b48e0bSAndroid Build Coastguard Worker   Constant *
169*08b48e0bSAndroid Build Coastguard Worker #endif
170*08b48e0bSAndroid Build Coastguard Worker       c1 = M.getOrInsertFunction("__cmplog_rtn_llvm_stdstring_stdstring",
171*08b48e0bSAndroid Build Coastguard Worker                                  VoidTy, i8PtrTy, i8PtrTy
172*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR < 5
173*08b48e0bSAndroid Build Coastguard Worker                                  ,
174*08b48e0bSAndroid Build Coastguard Worker                                  NULL
175*08b48e0bSAndroid Build Coastguard Worker #endif
176*08b48e0bSAndroid Build Coastguard Worker       );
177*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 9
178*08b48e0bSAndroid Build Coastguard Worker   FunctionCallee cmplogLlvmStdStd = c1;
179*08b48e0bSAndroid Build Coastguard Worker #else
180*08b48e0bSAndroid Build Coastguard Worker   Function *cmplogLlvmStdStd = cast<Function>(c1);
181*08b48e0bSAndroid Build Coastguard Worker #endif
182*08b48e0bSAndroid Build Coastguard Worker 
183*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 9
184*08b48e0bSAndroid Build Coastguard Worker   FunctionCallee
185*08b48e0bSAndroid Build Coastguard Worker #else
186*08b48e0bSAndroid Build Coastguard Worker   Constant *
187*08b48e0bSAndroid Build Coastguard Worker #endif
188*08b48e0bSAndroid Build Coastguard Worker       c2 = M.getOrInsertFunction("__cmplog_rtn_llvm_stdstring_cstring", VoidTy,
189*08b48e0bSAndroid Build Coastguard Worker                                  i8PtrTy, i8PtrTy
190*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR < 5
191*08b48e0bSAndroid Build Coastguard Worker                                  ,
192*08b48e0bSAndroid Build Coastguard Worker                                  NULL
193*08b48e0bSAndroid Build Coastguard Worker #endif
194*08b48e0bSAndroid Build Coastguard Worker       );
195*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 9
196*08b48e0bSAndroid Build Coastguard Worker   FunctionCallee cmplogLlvmStdC = c2;
197*08b48e0bSAndroid Build Coastguard Worker #else
198*08b48e0bSAndroid Build Coastguard Worker   Function *cmplogLlvmStdC = cast<Function>(c2);
199*08b48e0bSAndroid Build Coastguard Worker #endif
200*08b48e0bSAndroid Build Coastguard Worker 
201*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 9
202*08b48e0bSAndroid Build Coastguard Worker   FunctionCallee
203*08b48e0bSAndroid Build Coastguard Worker #else
204*08b48e0bSAndroid Build Coastguard Worker   Constant *
205*08b48e0bSAndroid Build Coastguard Worker #endif
206*08b48e0bSAndroid Build Coastguard Worker       c3 = M.getOrInsertFunction("__cmplog_rtn_gcc_stdstring_stdstring", VoidTy,
207*08b48e0bSAndroid Build Coastguard Worker                                  i8PtrTy, i8PtrTy
208*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR < 5
209*08b48e0bSAndroid Build Coastguard Worker                                  ,
210*08b48e0bSAndroid Build Coastguard Worker                                  NULL
211*08b48e0bSAndroid Build Coastguard Worker #endif
212*08b48e0bSAndroid Build Coastguard Worker       );
213*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 9
214*08b48e0bSAndroid Build Coastguard Worker   FunctionCallee cmplogGccStdStd = c3;
215*08b48e0bSAndroid Build Coastguard Worker #else
216*08b48e0bSAndroid Build Coastguard Worker   Function *cmplogGccStdStd = cast<Function>(c3);
217*08b48e0bSAndroid Build Coastguard Worker #endif
218*08b48e0bSAndroid Build Coastguard Worker 
219*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 9
220*08b48e0bSAndroid Build Coastguard Worker   FunctionCallee
221*08b48e0bSAndroid Build Coastguard Worker #else
222*08b48e0bSAndroid Build Coastguard Worker   Constant *
223*08b48e0bSAndroid Build Coastguard Worker #endif
224*08b48e0bSAndroid Build Coastguard Worker       c4 = M.getOrInsertFunction("__cmplog_rtn_gcc_stdstring_cstring", VoidTy,
225*08b48e0bSAndroid Build Coastguard Worker                                  i8PtrTy, i8PtrTy
226*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR < 5
227*08b48e0bSAndroid Build Coastguard Worker                                  ,
228*08b48e0bSAndroid Build Coastguard Worker                                  NULL
229*08b48e0bSAndroid Build Coastguard Worker #endif
230*08b48e0bSAndroid Build Coastguard Worker       );
231*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 9
232*08b48e0bSAndroid Build Coastguard Worker   FunctionCallee cmplogGccStdC = c4;
233*08b48e0bSAndroid Build Coastguard Worker #else
234*08b48e0bSAndroid Build Coastguard Worker   Function *cmplogGccStdC = cast<Function>(c4);
235*08b48e0bSAndroid Build Coastguard Worker #endif
236*08b48e0bSAndroid Build Coastguard Worker 
237*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 9
238*08b48e0bSAndroid Build Coastguard Worker   FunctionCallee
239*08b48e0bSAndroid Build Coastguard Worker #else
240*08b48e0bSAndroid Build Coastguard Worker   Constant *
241*08b48e0bSAndroid Build Coastguard Worker #endif
242*08b48e0bSAndroid Build Coastguard Worker       c5 = M.getOrInsertFunction("__cmplog_rtn_hook_n", VoidTy, i8PtrTy,
243*08b48e0bSAndroid Build Coastguard Worker                                  i8PtrTy, Int64Ty
244*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR < 5
245*08b48e0bSAndroid Build Coastguard Worker                                  ,
246*08b48e0bSAndroid Build Coastguard Worker                                  NULL
247*08b48e0bSAndroid Build Coastguard Worker #endif
248*08b48e0bSAndroid Build Coastguard Worker       );
249*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 9
250*08b48e0bSAndroid Build Coastguard Worker   FunctionCallee cmplogHookFnN = c5;
251*08b48e0bSAndroid Build Coastguard Worker #else
252*08b48e0bSAndroid Build Coastguard Worker   Function *cmplogHookFnN = cast<Function>(c5);
253*08b48e0bSAndroid Build Coastguard Worker #endif
254*08b48e0bSAndroid Build Coastguard Worker 
255*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 9
256*08b48e0bSAndroid Build Coastguard Worker   FunctionCallee
257*08b48e0bSAndroid Build Coastguard Worker #else
258*08b48e0bSAndroid Build Coastguard Worker   Constant *
259*08b48e0bSAndroid Build Coastguard Worker #endif
260*08b48e0bSAndroid Build Coastguard Worker       c6 = M.getOrInsertFunction("__cmplog_rtn_hook_strn", VoidTy, i8PtrTy,
261*08b48e0bSAndroid Build Coastguard Worker                                  i8PtrTy, Int64Ty
262*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR < 5
263*08b48e0bSAndroid Build Coastguard Worker                                  ,
264*08b48e0bSAndroid Build Coastguard Worker                                  NULL
265*08b48e0bSAndroid Build Coastguard Worker #endif
266*08b48e0bSAndroid Build Coastguard Worker       );
267*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 9
268*08b48e0bSAndroid Build Coastguard Worker   FunctionCallee cmplogHookFnStrN = c6;
269*08b48e0bSAndroid Build Coastguard Worker #else
270*08b48e0bSAndroid Build Coastguard Worker   Function *cmplogHookFnStrN = cast<Function>(c6);
271*08b48e0bSAndroid Build Coastguard Worker #endif
272*08b48e0bSAndroid Build Coastguard Worker 
273*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 9
274*08b48e0bSAndroid Build Coastguard Worker   FunctionCallee
275*08b48e0bSAndroid Build Coastguard Worker #else
276*08b48e0bSAndroid Build Coastguard Worker   Constant *
277*08b48e0bSAndroid Build Coastguard Worker #endif
278*08b48e0bSAndroid Build Coastguard Worker       c7 = M.getOrInsertFunction("__cmplog_rtn_hook_str", VoidTy, i8PtrTy,
279*08b48e0bSAndroid Build Coastguard Worker                                  i8PtrTy
280*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR < 5
281*08b48e0bSAndroid Build Coastguard Worker                                  ,
282*08b48e0bSAndroid Build Coastguard Worker                                  NULL
283*08b48e0bSAndroid Build Coastguard Worker #endif
284*08b48e0bSAndroid Build Coastguard Worker       );
285*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 9
286*08b48e0bSAndroid Build Coastguard Worker   FunctionCallee cmplogHookFnStr = c7;
287*08b48e0bSAndroid Build Coastguard Worker #else
288*08b48e0bSAndroid Build Coastguard Worker   Function *cmplogHookFnStr = cast<Function>(c7);
289*08b48e0bSAndroid Build Coastguard Worker #endif
290*08b48e0bSAndroid Build Coastguard Worker 
291*08b48e0bSAndroid Build Coastguard Worker   GlobalVariable *AFLCmplogPtr = M.getNamedGlobal("__afl_cmp_map");
292*08b48e0bSAndroid Build Coastguard Worker 
293*08b48e0bSAndroid Build Coastguard Worker   if (!AFLCmplogPtr) {
294*08b48e0bSAndroid Build Coastguard Worker 
295*08b48e0bSAndroid Build Coastguard Worker     AFLCmplogPtr = new GlobalVariable(M, PointerType::get(Int8Ty, 0), false,
296*08b48e0bSAndroid Build Coastguard Worker                                       GlobalValue::ExternalWeakLinkage, 0,
297*08b48e0bSAndroid Build Coastguard Worker                                       "__afl_cmp_map");
298*08b48e0bSAndroid Build Coastguard Worker 
299*08b48e0bSAndroid Build Coastguard Worker   }
300*08b48e0bSAndroid Build Coastguard Worker 
301*08b48e0bSAndroid Build Coastguard Worker   Constant *Null = Constant::getNullValue(PointerType::get(Int8Ty, 0));
302*08b48e0bSAndroid Build Coastguard Worker 
303*08b48e0bSAndroid Build Coastguard Worker   /* iterate over all functions, bbs and instruction and add suitable calls */
304*08b48e0bSAndroid Build Coastguard Worker   for (auto &F : M) {
305*08b48e0bSAndroid Build Coastguard Worker 
306*08b48e0bSAndroid Build Coastguard Worker     if (!isInInstrumentList(&F, MNAME)) continue;
307*08b48e0bSAndroid Build Coastguard Worker 
308*08b48e0bSAndroid Build Coastguard Worker     for (auto &BB : F) {
309*08b48e0bSAndroid Build Coastguard Worker 
310*08b48e0bSAndroid Build Coastguard Worker       for (auto &IN : BB) {
311*08b48e0bSAndroid Build Coastguard Worker 
312*08b48e0bSAndroid Build Coastguard Worker         CallInst *callInst = nullptr;
313*08b48e0bSAndroid Build Coastguard Worker 
314*08b48e0bSAndroid Build Coastguard Worker         if ((callInst = dyn_cast<CallInst>(&IN))) {
315*08b48e0bSAndroid Build Coastguard Worker 
316*08b48e0bSAndroid Build Coastguard Worker           Function *Callee = callInst->getCalledFunction();
317*08b48e0bSAndroid Build Coastguard Worker           if (!Callee) continue;
318*08b48e0bSAndroid Build Coastguard Worker           if (callInst->getCallingConv() != llvm::CallingConv::C) continue;
319*08b48e0bSAndroid Build Coastguard Worker 
320*08b48e0bSAndroid Build Coastguard Worker           FunctionType *FT = Callee->getFunctionType();
321*08b48e0bSAndroid Build Coastguard Worker           std::string   FuncName = Callee->getName().str();
322*08b48e0bSAndroid Build Coastguard Worker 
323*08b48e0bSAndroid Build Coastguard Worker           bool isPtrRtn = FT->getNumParams() >= 2 &&
324*08b48e0bSAndroid Build Coastguard Worker                           !FT->getReturnType()->isVoidTy() &&
325*08b48e0bSAndroid Build Coastguard Worker                           FT->getParamType(0) == FT->getParamType(1) &&
326*08b48e0bSAndroid Build Coastguard Worker                           FT->getParamType(0)->isPointerTy();
327*08b48e0bSAndroid Build Coastguard Worker 
328*08b48e0bSAndroid Build Coastguard Worker           bool isPtrRtnN = FT->getNumParams() >= 3 &&
329*08b48e0bSAndroid Build Coastguard Worker                            !FT->getReturnType()->isVoidTy() &&
330*08b48e0bSAndroid Build Coastguard Worker                            FT->getParamType(0) == FT->getParamType(1) &&
331*08b48e0bSAndroid Build Coastguard Worker                            FT->getParamType(0)->isPointerTy() &&
332*08b48e0bSAndroid Build Coastguard Worker                            FT->getParamType(2)->isIntegerTy();
333*08b48e0bSAndroid Build Coastguard Worker           if (isPtrRtnN) {
334*08b48e0bSAndroid Build Coastguard Worker 
335*08b48e0bSAndroid Build Coastguard Worker             auto intTyOp =
336*08b48e0bSAndroid Build Coastguard Worker                 dyn_cast<IntegerType>(callInst->getArgOperand(2)->getType());
337*08b48e0bSAndroid Build Coastguard Worker             if (intTyOp) {
338*08b48e0bSAndroid Build Coastguard Worker 
339*08b48e0bSAndroid Build Coastguard Worker               if (intTyOp->getBitWidth() != 32 &&
340*08b48e0bSAndroid Build Coastguard Worker                   intTyOp->getBitWidth() != 64) {
341*08b48e0bSAndroid Build Coastguard Worker 
342*08b48e0bSAndroid Build Coastguard Worker                 isPtrRtnN = false;
343*08b48e0bSAndroid Build Coastguard Worker 
344*08b48e0bSAndroid Build Coastguard Worker               }
345*08b48e0bSAndroid Build Coastguard Worker 
346*08b48e0bSAndroid Build Coastguard Worker             }
347*08b48e0bSAndroid Build Coastguard Worker 
348*08b48e0bSAndroid Build Coastguard Worker           }
349*08b48e0bSAndroid Build Coastguard Worker 
350*08b48e0bSAndroid Build Coastguard Worker           bool isMemcmp =
351*08b48e0bSAndroid Build Coastguard Worker               (!FuncName.compare("memcmp") || !FuncName.compare("bcmp") ||
352*08b48e0bSAndroid Build Coastguard Worker                !FuncName.compare("CRYPTO_memcmp") ||
353*08b48e0bSAndroid Build Coastguard Worker                !FuncName.compare("OPENSSL_memcmp") ||
354*08b48e0bSAndroid Build Coastguard Worker                !FuncName.compare("memcmp_const_time") ||
355*08b48e0bSAndroid Build Coastguard Worker                !FuncName.compare("memcmpct"));
356*08b48e0bSAndroid Build Coastguard Worker           isMemcmp &= FT->getNumParams() == 3 &&
357*08b48e0bSAndroid Build Coastguard Worker                       FT->getReturnType()->isIntegerTy(32) &&
358*08b48e0bSAndroid Build Coastguard Worker                       FT->getParamType(0)->isPointerTy() &&
359*08b48e0bSAndroid Build Coastguard Worker                       FT->getParamType(1)->isPointerTy() &&
360*08b48e0bSAndroid Build Coastguard Worker                       FT->getParamType(2)->isIntegerTy();
361*08b48e0bSAndroid Build Coastguard Worker 
362*08b48e0bSAndroid Build Coastguard Worker           bool isStrcmp =
363*08b48e0bSAndroid Build Coastguard Worker               (!FuncName.compare("strcmp") || !FuncName.compare("xmlStrcmp") ||
364*08b48e0bSAndroid Build Coastguard Worker                !FuncName.compare("xmlStrEqual") ||
365*08b48e0bSAndroid Build Coastguard Worker                !FuncName.compare("g_strcmp0") ||
366*08b48e0bSAndroid Build Coastguard Worker                !FuncName.compare("curl_strequal") ||
367*08b48e0bSAndroid Build Coastguard Worker                !FuncName.compare("strcsequal") ||
368*08b48e0bSAndroid Build Coastguard Worker                !FuncName.compare("strcasecmp") ||
369*08b48e0bSAndroid Build Coastguard Worker                !FuncName.compare("stricmp") ||
370*08b48e0bSAndroid Build Coastguard Worker                !FuncName.compare("ap_cstr_casecmp") ||
371*08b48e0bSAndroid Build Coastguard Worker                !FuncName.compare("OPENSSL_strcasecmp") ||
372*08b48e0bSAndroid Build Coastguard Worker                !FuncName.compare("xmlStrcasecmp") ||
373*08b48e0bSAndroid Build Coastguard Worker                !FuncName.compare("g_strcasecmp") ||
374*08b48e0bSAndroid Build Coastguard Worker                !FuncName.compare("g_ascii_strcasecmp") ||
375*08b48e0bSAndroid Build Coastguard Worker                !FuncName.compare("Curl_strcasecompare") ||
376*08b48e0bSAndroid Build Coastguard Worker                !FuncName.compare("Curl_safe_strcasecompare") ||
377*08b48e0bSAndroid Build Coastguard Worker                !FuncName.compare("cmsstrcasecmp") ||
378*08b48e0bSAndroid Build Coastguard Worker                !FuncName.compare("strstr") ||
379*08b48e0bSAndroid Build Coastguard Worker                !FuncName.compare("g_strstr_len") ||
380*08b48e0bSAndroid Build Coastguard Worker                !FuncName.compare("ap_strcasestr") ||
381*08b48e0bSAndroid Build Coastguard Worker                !FuncName.compare("xmlStrstr") ||
382*08b48e0bSAndroid Build Coastguard Worker                !FuncName.compare("xmlStrcasestr") ||
383*08b48e0bSAndroid Build Coastguard Worker                !FuncName.compare("g_str_has_prefix") ||
384*08b48e0bSAndroid Build Coastguard Worker                !FuncName.compare("g_str_has_suffix"));
385*08b48e0bSAndroid Build Coastguard Worker           isStrcmp &=
386*08b48e0bSAndroid Build Coastguard Worker               FT->getNumParams() == 2 && FT->getReturnType()->isIntegerTy(32) &&
387*08b48e0bSAndroid Build Coastguard Worker               FT->getParamType(0) == FT->getParamType(1) &&
388*08b48e0bSAndroid Build Coastguard Worker               FT->getParamType(0) ==
389*08b48e0bSAndroid Build Coastguard Worker                   IntegerType::getInt8Ty(M.getContext())->getPointerTo(0);
390*08b48e0bSAndroid Build Coastguard Worker 
391*08b48e0bSAndroid Build Coastguard Worker           bool isStrncmp = (!FuncName.compare("strncmp") ||
392*08b48e0bSAndroid Build Coastguard Worker                             !FuncName.compare("xmlStrncmp") ||
393*08b48e0bSAndroid Build Coastguard Worker                             !FuncName.compare("curl_strnequal") ||
394*08b48e0bSAndroid Build Coastguard Worker                             !FuncName.compare("strncasecmp") ||
395*08b48e0bSAndroid Build Coastguard Worker                             !FuncName.compare("strnicmp") ||
396*08b48e0bSAndroid Build Coastguard Worker                             !FuncName.compare("ap_cstr_casecmpn") ||
397*08b48e0bSAndroid Build Coastguard Worker                             !FuncName.compare("OPENSSL_strncasecmp") ||
398*08b48e0bSAndroid Build Coastguard Worker                             !FuncName.compare("xmlStrncasecmp") ||
399*08b48e0bSAndroid Build Coastguard Worker                             !FuncName.compare("g_ascii_strncasecmp") ||
400*08b48e0bSAndroid Build Coastguard Worker                             !FuncName.compare("Curl_strncasecompare") ||
401*08b48e0bSAndroid Build Coastguard Worker                             !FuncName.compare("g_strncasecmp"));
402*08b48e0bSAndroid Build Coastguard Worker           isStrncmp &=
403*08b48e0bSAndroid Build Coastguard Worker               FT->getNumParams() == 3 && FT->getReturnType()->isIntegerTy(32) &&
404*08b48e0bSAndroid Build Coastguard Worker               FT->getParamType(0) == FT->getParamType(1) &&
405*08b48e0bSAndroid Build Coastguard Worker               FT->getParamType(0) ==
406*08b48e0bSAndroid Build Coastguard Worker                   IntegerType::getInt8Ty(M.getContext())->getPointerTo(0) &&
407*08b48e0bSAndroid Build Coastguard Worker               FT->getParamType(2)->isIntegerTy();
408*08b48e0bSAndroid Build Coastguard Worker 
409*08b48e0bSAndroid Build Coastguard Worker           bool isGccStdStringStdString =
410*08b48e0bSAndroid Build Coastguard Worker               Callee->getName().find("__is_charIT_EE7__value") !=
411*08b48e0bSAndroid Build Coastguard Worker                   std::string::npos &&
412*08b48e0bSAndroid Build Coastguard Worker               Callee->getName().find(
413*08b48e0bSAndroid Build Coastguard Worker                   "St7__cxx1112basic_stringIS2_St11char_traits") !=
414*08b48e0bSAndroid Build Coastguard Worker                   std::string::npos &&
415*08b48e0bSAndroid Build Coastguard Worker               FT->getNumParams() >= 2 &&
416*08b48e0bSAndroid Build Coastguard Worker               FT->getParamType(0) == FT->getParamType(1) &&
417*08b48e0bSAndroid Build Coastguard Worker               FT->getParamType(0)->isPointerTy();
418*08b48e0bSAndroid Build Coastguard Worker 
419*08b48e0bSAndroid Build Coastguard Worker           bool isGccStdStringCString =
420*08b48e0bSAndroid Build Coastguard Worker               Callee->getName().find(
421*08b48e0bSAndroid Build Coastguard Worker                   "St7__cxx1112basic_stringIcSt11char_"
422*08b48e0bSAndroid Build Coastguard Worker                   "traitsIcESaIcEE7compareEPK") != std::string::npos &&
423*08b48e0bSAndroid Build Coastguard Worker               FT->getNumParams() >= 2 && FT->getParamType(0)->isPointerTy() &&
424*08b48e0bSAndroid Build Coastguard Worker               FT->getParamType(1)->isPointerTy();
425*08b48e0bSAndroid Build Coastguard Worker 
426*08b48e0bSAndroid Build Coastguard Worker           bool isLlvmStdStringStdString =
427*08b48e0bSAndroid Build Coastguard Worker               Callee->getName().find("_ZNSt3__1eqI") != std::string::npos &&
428*08b48e0bSAndroid Build Coastguard Worker               Callee->getName().find("_12basic_stringI") != std::string::npos &&
429*08b48e0bSAndroid Build Coastguard Worker               Callee->getName().find("_11char_traits") != std::string::npos &&
430*08b48e0bSAndroid Build Coastguard Worker               FT->getNumParams() >= 2 && FT->getParamType(0)->isPointerTy() &&
431*08b48e0bSAndroid Build Coastguard Worker               FT->getParamType(1)->isPointerTy();
432*08b48e0bSAndroid Build Coastguard Worker 
433*08b48e0bSAndroid Build Coastguard Worker           bool isLlvmStdStringCString =
434*08b48e0bSAndroid Build Coastguard Worker               Callee->getName().find("_ZNSt3__1eqI") != std::string::npos &&
435*08b48e0bSAndroid Build Coastguard Worker               Callee->getName().find("_12basic_stringI") != std::string::npos &&
436*08b48e0bSAndroid Build Coastguard Worker               FT->getNumParams() >= 2 && FT->getParamType(0)->isPointerTy() &&
437*08b48e0bSAndroid Build Coastguard Worker               FT->getParamType(1)->isPointerTy();
438*08b48e0bSAndroid Build Coastguard Worker 
439*08b48e0bSAndroid Build Coastguard Worker           /*
440*08b48e0bSAndroid Build Coastguard Worker                     {
441*08b48e0bSAndroid Build Coastguard Worker 
442*08b48e0bSAndroid Build Coastguard Worker                        fprintf(stderr, "F:%s C:%s argc:%u\n",
443*08b48e0bSAndroid Build Coastguard Worker                        F.getName().str().c_str(),
444*08b48e0bSAndroid Build Coastguard Worker              Callee->getName().str().c_str(), FT->getNumParams());
445*08b48e0bSAndroid Build Coastguard Worker                        fprintf(stderr, "ptr0:%u ptr1:%u ptr2:%u\n",
446*08b48e0bSAndroid Build Coastguard Worker                               FT->getParamType(0)->isPointerTy(),
447*08b48e0bSAndroid Build Coastguard Worker                               FT->getParamType(1)->isPointerTy(),
448*08b48e0bSAndroid Build Coastguard Worker                               FT->getNumParams() > 2 ?
449*08b48e0bSAndroid Build Coastguard Worker              FT->getParamType(2)->isPointerTy() : 22 );
450*08b48e0bSAndroid Build Coastguard Worker 
451*08b48e0bSAndroid Build Coastguard Worker                     }
452*08b48e0bSAndroid Build Coastguard Worker 
453*08b48e0bSAndroid Build Coastguard Worker           */
454*08b48e0bSAndroid Build Coastguard Worker 
455*08b48e0bSAndroid Build Coastguard Worker           if (isGccStdStringCString || isGccStdStringStdString ||
456*08b48e0bSAndroid Build Coastguard Worker               isLlvmStdStringStdString || isLlvmStdStringCString || isMemcmp ||
457*08b48e0bSAndroid Build Coastguard Worker               isStrcmp || isStrncmp) {
458*08b48e0bSAndroid Build Coastguard Worker 
459*08b48e0bSAndroid Build Coastguard Worker             isPtrRtnN = isPtrRtn = false;
460*08b48e0bSAndroid Build Coastguard Worker 
461*08b48e0bSAndroid Build Coastguard Worker           }
462*08b48e0bSAndroid Build Coastguard Worker 
463*08b48e0bSAndroid Build Coastguard Worker           if (isPtrRtnN) { isPtrRtn = false; }
464*08b48e0bSAndroid Build Coastguard Worker 
465*08b48e0bSAndroid Build Coastguard Worker           if (isPtrRtn) { calls.push_back(callInst); }
466*08b48e0bSAndroid Build Coastguard Worker           if (isMemcmp || isPtrRtnN) { Memcmp.push_back(callInst); }
467*08b48e0bSAndroid Build Coastguard Worker           if (isStrcmp) { Strcmp.push_back(callInst); }
468*08b48e0bSAndroid Build Coastguard Worker           if (isStrncmp) { Strncmp.push_back(callInst); }
469*08b48e0bSAndroid Build Coastguard Worker           if (isGccStdStringStdString) { gccStdStd.push_back(callInst); }
470*08b48e0bSAndroid Build Coastguard Worker           if (isGccStdStringCString) { gccStdC.push_back(callInst); }
471*08b48e0bSAndroid Build Coastguard Worker           if (isLlvmStdStringStdString) { llvmStdStd.push_back(callInst); }
472*08b48e0bSAndroid Build Coastguard Worker           if (isLlvmStdStringCString) { llvmStdC.push_back(callInst); }
473*08b48e0bSAndroid Build Coastguard Worker 
474*08b48e0bSAndroid Build Coastguard Worker         }
475*08b48e0bSAndroid Build Coastguard Worker 
476*08b48e0bSAndroid Build Coastguard Worker       }
477*08b48e0bSAndroid Build Coastguard Worker 
478*08b48e0bSAndroid Build Coastguard Worker     }
479*08b48e0bSAndroid Build Coastguard Worker 
480*08b48e0bSAndroid Build Coastguard Worker   }
481*08b48e0bSAndroid Build Coastguard Worker 
482*08b48e0bSAndroid Build Coastguard Worker   if (!calls.size() && !gccStdStd.size() && !gccStdC.size() &&
483*08b48e0bSAndroid Build Coastguard Worker       !llvmStdStd.size() && !llvmStdC.size() && !Memcmp.size() &&
484*08b48e0bSAndroid Build Coastguard Worker       Strcmp.size() && Strncmp.size())
485*08b48e0bSAndroid Build Coastguard Worker     return false;
486*08b48e0bSAndroid Build Coastguard Worker 
487*08b48e0bSAndroid Build Coastguard Worker   /*
488*08b48e0bSAndroid Build Coastguard Worker     if (!be_quiet)
489*08b48e0bSAndroid Build Coastguard Worker       errs() << "Hooking " << calls.size()
490*08b48e0bSAndroid Build Coastguard Worker              << " calls with pointers as arguments\n";
491*08b48e0bSAndroid Build Coastguard Worker   */
492*08b48e0bSAndroid Build Coastguard Worker 
493*08b48e0bSAndroid Build Coastguard Worker   for (auto &callInst : calls) {
494*08b48e0bSAndroid Build Coastguard Worker 
495*08b48e0bSAndroid Build Coastguard Worker     Value *v1P = callInst->getArgOperand(0), *v2P = callInst->getArgOperand(1);
496*08b48e0bSAndroid Build Coastguard Worker 
497*08b48e0bSAndroid Build Coastguard Worker     IRBuilder<> IRB2(callInst->getParent());
498*08b48e0bSAndroid Build Coastguard Worker     IRB2.SetInsertPoint(callInst);
499*08b48e0bSAndroid Build Coastguard Worker 
500*08b48e0bSAndroid Build Coastguard Worker     LoadInst *CmpPtr = IRB2.CreateLoad(
501*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 14
502*08b48e0bSAndroid Build Coastguard Worker         PointerType::get(Int8Ty, 0),
503*08b48e0bSAndroid Build Coastguard Worker #endif
504*08b48e0bSAndroid Build Coastguard Worker         AFLCmplogPtr);
505*08b48e0bSAndroid Build Coastguard Worker     CmpPtr->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None));
506*08b48e0bSAndroid Build Coastguard Worker     auto is_not_null = IRB2.CreateICmpNE(CmpPtr, Null);
507*08b48e0bSAndroid Build Coastguard Worker     auto ThenTerm = SplitBlockAndInsertIfThen(is_not_null, callInst, false);
508*08b48e0bSAndroid Build Coastguard Worker 
509*08b48e0bSAndroid Build Coastguard Worker     IRBuilder<> IRB(ThenTerm);
510*08b48e0bSAndroid Build Coastguard Worker 
511*08b48e0bSAndroid Build Coastguard Worker     std::vector<Value *> args;
512*08b48e0bSAndroid Build Coastguard Worker     Value               *v1Pcasted = IRB.CreatePointerCast(v1P, i8PtrTy);
513*08b48e0bSAndroid Build Coastguard Worker     Value               *v2Pcasted = IRB.CreatePointerCast(v2P, i8PtrTy);
514*08b48e0bSAndroid Build Coastguard Worker     args.push_back(v1Pcasted);
515*08b48e0bSAndroid Build Coastguard Worker     args.push_back(v2Pcasted);
516*08b48e0bSAndroid Build Coastguard Worker 
517*08b48e0bSAndroid Build Coastguard Worker     IRB.CreateCall(cmplogHookFn, args);
518*08b48e0bSAndroid Build Coastguard Worker 
519*08b48e0bSAndroid Build Coastguard Worker     // errs() << callInst->getCalledFunction()->getName() << "\n";
520*08b48e0bSAndroid Build Coastguard Worker 
521*08b48e0bSAndroid Build Coastguard Worker   }
522*08b48e0bSAndroid Build Coastguard Worker 
523*08b48e0bSAndroid Build Coastguard Worker   for (auto &callInst : Memcmp) {
524*08b48e0bSAndroid Build Coastguard Worker 
525*08b48e0bSAndroid Build Coastguard Worker     Value *v1P = callInst->getArgOperand(0), *v2P = callInst->getArgOperand(1),
526*08b48e0bSAndroid Build Coastguard Worker           *v3P = callInst->getArgOperand(2);
527*08b48e0bSAndroid Build Coastguard Worker 
528*08b48e0bSAndroid Build Coastguard Worker     IRBuilder<> IRB2(callInst->getParent());
529*08b48e0bSAndroid Build Coastguard Worker     IRB2.SetInsertPoint(callInst);
530*08b48e0bSAndroid Build Coastguard Worker 
531*08b48e0bSAndroid Build Coastguard Worker     LoadInst *CmpPtr = IRB2.CreateLoad(
532*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 14
533*08b48e0bSAndroid Build Coastguard Worker         PointerType::get(Int8Ty, 0),
534*08b48e0bSAndroid Build Coastguard Worker #endif
535*08b48e0bSAndroid Build Coastguard Worker         AFLCmplogPtr);
536*08b48e0bSAndroid Build Coastguard Worker     CmpPtr->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None));
537*08b48e0bSAndroid Build Coastguard Worker     auto is_not_null = IRB2.CreateICmpNE(CmpPtr, Null);
538*08b48e0bSAndroid Build Coastguard Worker     auto ThenTerm = SplitBlockAndInsertIfThen(is_not_null, callInst, false);
539*08b48e0bSAndroid Build Coastguard Worker 
540*08b48e0bSAndroid Build Coastguard Worker     IRBuilder<> IRB(ThenTerm);
541*08b48e0bSAndroid Build Coastguard Worker 
542*08b48e0bSAndroid Build Coastguard Worker     std::vector<Value *> args;
543*08b48e0bSAndroid Build Coastguard Worker     Value               *v1Pcasted = IRB.CreatePointerCast(v1P, i8PtrTy);
544*08b48e0bSAndroid Build Coastguard Worker     Value               *v2Pcasted = IRB.CreatePointerCast(v2P, i8PtrTy);
545*08b48e0bSAndroid Build Coastguard Worker     Value               *v3Pbitcast = IRB.CreateBitCast(
546*08b48e0bSAndroid Build Coastguard Worker         v3P, IntegerType::get(C, v3P->getType()->getPrimitiveSizeInBits()));
547*08b48e0bSAndroid Build Coastguard Worker     Value *v3Pcasted =
548*08b48e0bSAndroid Build Coastguard Worker         IRB.CreateIntCast(v3Pbitcast, IntegerType::get(C, 64), false);
549*08b48e0bSAndroid Build Coastguard Worker     args.push_back(v1Pcasted);
550*08b48e0bSAndroid Build Coastguard Worker     args.push_back(v2Pcasted);
551*08b48e0bSAndroid Build Coastguard Worker     args.push_back(v3Pcasted);
552*08b48e0bSAndroid Build Coastguard Worker 
553*08b48e0bSAndroid Build Coastguard Worker     IRB.CreateCall(cmplogHookFnN, args);
554*08b48e0bSAndroid Build Coastguard Worker 
555*08b48e0bSAndroid Build Coastguard Worker     // errs() << callInst->getCalledFunction()->getName() << "\n";
556*08b48e0bSAndroid Build Coastguard Worker 
557*08b48e0bSAndroid Build Coastguard Worker   }
558*08b48e0bSAndroid Build Coastguard Worker 
559*08b48e0bSAndroid Build Coastguard Worker   for (auto &callInst : Strcmp) {
560*08b48e0bSAndroid Build Coastguard Worker 
561*08b48e0bSAndroid Build Coastguard Worker     Value *v1P = callInst->getArgOperand(0), *v2P = callInst->getArgOperand(1);
562*08b48e0bSAndroid Build Coastguard Worker 
563*08b48e0bSAndroid Build Coastguard Worker     IRBuilder<> IRB2(callInst->getParent());
564*08b48e0bSAndroid Build Coastguard Worker     IRB2.SetInsertPoint(callInst);
565*08b48e0bSAndroid Build Coastguard Worker 
566*08b48e0bSAndroid Build Coastguard Worker     LoadInst *CmpPtr = IRB2.CreateLoad(
567*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 14
568*08b48e0bSAndroid Build Coastguard Worker         PointerType::get(Int8Ty, 0),
569*08b48e0bSAndroid Build Coastguard Worker #endif
570*08b48e0bSAndroid Build Coastguard Worker         AFLCmplogPtr);
571*08b48e0bSAndroid Build Coastguard Worker     CmpPtr->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None));
572*08b48e0bSAndroid Build Coastguard Worker     auto is_not_null = IRB2.CreateICmpNE(CmpPtr, Null);
573*08b48e0bSAndroid Build Coastguard Worker     auto ThenTerm = SplitBlockAndInsertIfThen(is_not_null, callInst, false);
574*08b48e0bSAndroid Build Coastguard Worker 
575*08b48e0bSAndroid Build Coastguard Worker     IRBuilder<> IRB(ThenTerm);
576*08b48e0bSAndroid Build Coastguard Worker 
577*08b48e0bSAndroid Build Coastguard Worker     std::vector<Value *> args;
578*08b48e0bSAndroid Build Coastguard Worker     Value               *v1Pcasted = IRB.CreatePointerCast(v1P, i8PtrTy);
579*08b48e0bSAndroid Build Coastguard Worker     Value               *v2Pcasted = IRB.CreatePointerCast(v2P, i8PtrTy);
580*08b48e0bSAndroid Build Coastguard Worker     args.push_back(v1Pcasted);
581*08b48e0bSAndroid Build Coastguard Worker     args.push_back(v2Pcasted);
582*08b48e0bSAndroid Build Coastguard Worker 
583*08b48e0bSAndroid Build Coastguard Worker     IRB.CreateCall(cmplogHookFnStr, args);
584*08b48e0bSAndroid Build Coastguard Worker 
585*08b48e0bSAndroid Build Coastguard Worker     // errs() << callInst->getCalledFunction()->getName() << "\n";
586*08b48e0bSAndroid Build Coastguard Worker 
587*08b48e0bSAndroid Build Coastguard Worker   }
588*08b48e0bSAndroid Build Coastguard Worker 
589*08b48e0bSAndroid Build Coastguard Worker   for (auto &callInst : Strncmp) {
590*08b48e0bSAndroid Build Coastguard Worker 
591*08b48e0bSAndroid Build Coastguard Worker     Value *v1P = callInst->getArgOperand(0), *v2P = callInst->getArgOperand(1),
592*08b48e0bSAndroid Build Coastguard Worker           *v3P = callInst->getArgOperand(2);
593*08b48e0bSAndroid Build Coastguard Worker 
594*08b48e0bSAndroid Build Coastguard Worker     IRBuilder<> IRB2(callInst->getParent());
595*08b48e0bSAndroid Build Coastguard Worker     IRB2.SetInsertPoint(callInst);
596*08b48e0bSAndroid Build Coastguard Worker 
597*08b48e0bSAndroid Build Coastguard Worker     LoadInst *CmpPtr = IRB2.CreateLoad(
598*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 14
599*08b48e0bSAndroid Build Coastguard Worker         PointerType::get(Int8Ty, 0),
600*08b48e0bSAndroid Build Coastguard Worker #endif
601*08b48e0bSAndroid Build Coastguard Worker         AFLCmplogPtr);
602*08b48e0bSAndroid Build Coastguard Worker     CmpPtr->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None));
603*08b48e0bSAndroid Build Coastguard Worker     auto is_not_null = IRB2.CreateICmpNE(CmpPtr, Null);
604*08b48e0bSAndroid Build Coastguard Worker     auto ThenTerm = SplitBlockAndInsertIfThen(is_not_null, callInst, false);
605*08b48e0bSAndroid Build Coastguard Worker 
606*08b48e0bSAndroid Build Coastguard Worker     IRBuilder<> IRB(ThenTerm);
607*08b48e0bSAndroid Build Coastguard Worker 
608*08b48e0bSAndroid Build Coastguard Worker     std::vector<Value *> args;
609*08b48e0bSAndroid Build Coastguard Worker     Value               *v1Pcasted = IRB.CreatePointerCast(v1P, i8PtrTy);
610*08b48e0bSAndroid Build Coastguard Worker     Value               *v2Pcasted = IRB.CreatePointerCast(v2P, i8PtrTy);
611*08b48e0bSAndroid Build Coastguard Worker     Value               *v3Pbitcast = IRB.CreateBitCast(
612*08b48e0bSAndroid Build Coastguard Worker         v3P, IntegerType::get(C, v3P->getType()->getPrimitiveSizeInBits()));
613*08b48e0bSAndroid Build Coastguard Worker     Value *v3Pcasted =
614*08b48e0bSAndroid Build Coastguard Worker         IRB.CreateIntCast(v3Pbitcast, IntegerType::get(C, 64), false);
615*08b48e0bSAndroid Build Coastguard Worker     args.push_back(v1Pcasted);
616*08b48e0bSAndroid Build Coastguard Worker     args.push_back(v2Pcasted);
617*08b48e0bSAndroid Build Coastguard Worker     args.push_back(v3Pcasted);
618*08b48e0bSAndroid Build Coastguard Worker 
619*08b48e0bSAndroid Build Coastguard Worker     IRB.CreateCall(cmplogHookFnStrN, args);
620*08b48e0bSAndroid Build Coastguard Worker 
621*08b48e0bSAndroid Build Coastguard Worker     // errs() << callInst->getCalledFunction()->getName() << "\n";
622*08b48e0bSAndroid Build Coastguard Worker 
623*08b48e0bSAndroid Build Coastguard Worker   }
624*08b48e0bSAndroid Build Coastguard Worker 
625*08b48e0bSAndroid Build Coastguard Worker   for (auto &callInst : gccStdStd) {
626*08b48e0bSAndroid Build Coastguard Worker 
627*08b48e0bSAndroid Build Coastguard Worker     Value *v1P = callInst->getArgOperand(0), *v2P = callInst->getArgOperand(1);
628*08b48e0bSAndroid Build Coastguard Worker 
629*08b48e0bSAndroid Build Coastguard Worker     IRBuilder<> IRB2(callInst->getParent());
630*08b48e0bSAndroid Build Coastguard Worker     IRB2.SetInsertPoint(callInst);
631*08b48e0bSAndroid Build Coastguard Worker 
632*08b48e0bSAndroid Build Coastguard Worker     LoadInst *CmpPtr = IRB2.CreateLoad(
633*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 14
634*08b48e0bSAndroid Build Coastguard Worker         PointerType::get(Int8Ty, 0),
635*08b48e0bSAndroid Build Coastguard Worker #endif
636*08b48e0bSAndroid Build Coastguard Worker         AFLCmplogPtr);
637*08b48e0bSAndroid Build Coastguard Worker     CmpPtr->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None));
638*08b48e0bSAndroid Build Coastguard Worker     auto is_not_null = IRB2.CreateICmpNE(CmpPtr, Null);
639*08b48e0bSAndroid Build Coastguard Worker     auto ThenTerm = SplitBlockAndInsertIfThen(is_not_null, callInst, false);
640*08b48e0bSAndroid Build Coastguard Worker 
641*08b48e0bSAndroid Build Coastguard Worker     IRBuilder<> IRB(ThenTerm);
642*08b48e0bSAndroid Build Coastguard Worker 
643*08b48e0bSAndroid Build Coastguard Worker     std::vector<Value *> args;
644*08b48e0bSAndroid Build Coastguard Worker     Value               *v1Pcasted = IRB.CreatePointerCast(v1P, i8PtrTy);
645*08b48e0bSAndroid Build Coastguard Worker     Value               *v2Pcasted = IRB.CreatePointerCast(v2P, i8PtrTy);
646*08b48e0bSAndroid Build Coastguard Worker     args.push_back(v1Pcasted);
647*08b48e0bSAndroid Build Coastguard Worker     args.push_back(v2Pcasted);
648*08b48e0bSAndroid Build Coastguard Worker 
649*08b48e0bSAndroid Build Coastguard Worker     IRB.CreateCall(cmplogGccStdStd, args);
650*08b48e0bSAndroid Build Coastguard Worker 
651*08b48e0bSAndroid Build Coastguard Worker     // errs() << callInst->getCalledFunction()->getName() << "\n";
652*08b48e0bSAndroid Build Coastguard Worker 
653*08b48e0bSAndroid Build Coastguard Worker   }
654*08b48e0bSAndroid Build Coastguard Worker 
655*08b48e0bSAndroid Build Coastguard Worker   for (auto &callInst : gccStdC) {
656*08b48e0bSAndroid Build Coastguard Worker 
657*08b48e0bSAndroid Build Coastguard Worker     Value *v1P = callInst->getArgOperand(0), *v2P = callInst->getArgOperand(1);
658*08b48e0bSAndroid Build Coastguard Worker 
659*08b48e0bSAndroid Build Coastguard Worker     IRBuilder<> IRB2(callInst->getParent());
660*08b48e0bSAndroid Build Coastguard Worker     IRB2.SetInsertPoint(callInst);
661*08b48e0bSAndroid Build Coastguard Worker 
662*08b48e0bSAndroid Build Coastguard Worker     LoadInst *CmpPtr = IRB2.CreateLoad(
663*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 14
664*08b48e0bSAndroid Build Coastguard Worker         PointerType::get(Int8Ty, 0),
665*08b48e0bSAndroid Build Coastguard Worker #endif
666*08b48e0bSAndroid Build Coastguard Worker         AFLCmplogPtr);
667*08b48e0bSAndroid Build Coastguard Worker     CmpPtr->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None));
668*08b48e0bSAndroid Build Coastguard Worker     auto is_not_null = IRB2.CreateICmpNE(CmpPtr, Null);
669*08b48e0bSAndroid Build Coastguard Worker     auto ThenTerm = SplitBlockAndInsertIfThen(is_not_null, callInst, false);
670*08b48e0bSAndroid Build Coastguard Worker 
671*08b48e0bSAndroid Build Coastguard Worker     IRBuilder<> IRB(ThenTerm);
672*08b48e0bSAndroid Build Coastguard Worker 
673*08b48e0bSAndroid Build Coastguard Worker     std::vector<Value *> args;
674*08b48e0bSAndroid Build Coastguard Worker     Value               *v1Pcasted = IRB.CreatePointerCast(v1P, i8PtrTy);
675*08b48e0bSAndroid Build Coastguard Worker     Value               *v2Pcasted = IRB.CreatePointerCast(v2P, i8PtrTy);
676*08b48e0bSAndroid Build Coastguard Worker     args.push_back(v1Pcasted);
677*08b48e0bSAndroid Build Coastguard Worker     args.push_back(v2Pcasted);
678*08b48e0bSAndroid Build Coastguard Worker 
679*08b48e0bSAndroid Build Coastguard Worker     IRB.CreateCall(cmplogGccStdC, args);
680*08b48e0bSAndroid Build Coastguard Worker 
681*08b48e0bSAndroid Build Coastguard Worker     // errs() << callInst->getCalledFunction()->getName() << "\n";
682*08b48e0bSAndroid Build Coastguard Worker 
683*08b48e0bSAndroid Build Coastguard Worker   }
684*08b48e0bSAndroid Build Coastguard Worker 
685*08b48e0bSAndroid Build Coastguard Worker   for (auto &callInst : llvmStdStd) {
686*08b48e0bSAndroid Build Coastguard Worker 
687*08b48e0bSAndroid Build Coastguard Worker     Value *v1P = callInst->getArgOperand(0), *v2P = callInst->getArgOperand(1);
688*08b48e0bSAndroid Build Coastguard Worker 
689*08b48e0bSAndroid Build Coastguard Worker     IRBuilder<> IRB2(callInst->getParent());
690*08b48e0bSAndroid Build Coastguard Worker     IRB2.SetInsertPoint(callInst);
691*08b48e0bSAndroid Build Coastguard Worker 
692*08b48e0bSAndroid Build Coastguard Worker     LoadInst *CmpPtr = IRB2.CreateLoad(
693*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 14
694*08b48e0bSAndroid Build Coastguard Worker         PointerType::get(Int8Ty, 0),
695*08b48e0bSAndroid Build Coastguard Worker #endif
696*08b48e0bSAndroid Build Coastguard Worker         AFLCmplogPtr);
697*08b48e0bSAndroid Build Coastguard Worker     CmpPtr->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None));
698*08b48e0bSAndroid Build Coastguard Worker     auto is_not_null = IRB2.CreateICmpNE(CmpPtr, Null);
699*08b48e0bSAndroid Build Coastguard Worker     auto ThenTerm = SplitBlockAndInsertIfThen(is_not_null, callInst, false);
700*08b48e0bSAndroid Build Coastguard Worker 
701*08b48e0bSAndroid Build Coastguard Worker     IRBuilder<> IRB(ThenTerm);
702*08b48e0bSAndroid Build Coastguard Worker 
703*08b48e0bSAndroid Build Coastguard Worker     std::vector<Value *> args;
704*08b48e0bSAndroid Build Coastguard Worker     Value               *v1Pcasted = IRB.CreatePointerCast(v1P, i8PtrTy);
705*08b48e0bSAndroid Build Coastguard Worker     Value               *v2Pcasted = IRB.CreatePointerCast(v2P, i8PtrTy);
706*08b48e0bSAndroid Build Coastguard Worker     args.push_back(v1Pcasted);
707*08b48e0bSAndroid Build Coastguard Worker     args.push_back(v2Pcasted);
708*08b48e0bSAndroid Build Coastguard Worker 
709*08b48e0bSAndroid Build Coastguard Worker     IRB.CreateCall(cmplogLlvmStdStd, args);
710*08b48e0bSAndroid Build Coastguard Worker 
711*08b48e0bSAndroid Build Coastguard Worker     // errs() << callInst->getCalledFunction()->getName() << "\n";
712*08b48e0bSAndroid Build Coastguard Worker 
713*08b48e0bSAndroid Build Coastguard Worker   }
714*08b48e0bSAndroid Build Coastguard Worker 
715*08b48e0bSAndroid Build Coastguard Worker   for (auto &callInst : llvmStdC) {
716*08b48e0bSAndroid Build Coastguard Worker 
717*08b48e0bSAndroid Build Coastguard Worker     Value *v1P = callInst->getArgOperand(0), *v2P = callInst->getArgOperand(1);
718*08b48e0bSAndroid Build Coastguard Worker 
719*08b48e0bSAndroid Build Coastguard Worker     IRBuilder<> IRB2(callInst->getParent());
720*08b48e0bSAndroid Build Coastguard Worker     IRB2.SetInsertPoint(callInst);
721*08b48e0bSAndroid Build Coastguard Worker 
722*08b48e0bSAndroid Build Coastguard Worker     LoadInst *CmpPtr = IRB2.CreateLoad(
723*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 14
724*08b48e0bSAndroid Build Coastguard Worker         PointerType::get(Int8Ty, 0),
725*08b48e0bSAndroid Build Coastguard Worker #endif
726*08b48e0bSAndroid Build Coastguard Worker         AFLCmplogPtr);
727*08b48e0bSAndroid Build Coastguard Worker     CmpPtr->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None));
728*08b48e0bSAndroid Build Coastguard Worker     auto is_not_null = IRB2.CreateICmpNE(CmpPtr, Null);
729*08b48e0bSAndroid Build Coastguard Worker     auto ThenTerm = SplitBlockAndInsertIfThen(is_not_null, callInst, false);
730*08b48e0bSAndroid Build Coastguard Worker 
731*08b48e0bSAndroid Build Coastguard Worker     IRBuilder<> IRB(ThenTerm);
732*08b48e0bSAndroid Build Coastguard Worker 
733*08b48e0bSAndroid Build Coastguard Worker     std::vector<Value *> args;
734*08b48e0bSAndroid Build Coastguard Worker     Value               *v1Pcasted = IRB.CreatePointerCast(v1P, i8PtrTy);
735*08b48e0bSAndroid Build Coastguard Worker     Value               *v2Pcasted = IRB.CreatePointerCast(v2P, i8PtrTy);
736*08b48e0bSAndroid Build Coastguard Worker     args.push_back(v1Pcasted);
737*08b48e0bSAndroid Build Coastguard Worker     args.push_back(v2Pcasted);
738*08b48e0bSAndroid Build Coastguard Worker 
739*08b48e0bSAndroid Build Coastguard Worker     IRB.CreateCall(cmplogLlvmStdC, args);
740*08b48e0bSAndroid Build Coastguard Worker 
741*08b48e0bSAndroid Build Coastguard Worker     // errs() << callInst->getCalledFunction()->getName() << "\n";
742*08b48e0bSAndroid Build Coastguard Worker 
743*08b48e0bSAndroid Build Coastguard Worker   }
744*08b48e0bSAndroid Build Coastguard Worker 
745*08b48e0bSAndroid Build Coastguard Worker   return true;
746*08b48e0bSAndroid Build Coastguard Worker 
747*08b48e0bSAndroid Build Coastguard Worker }
748*08b48e0bSAndroid Build Coastguard Worker 
749*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 11                        /* use new pass manager */
750*08b48e0bSAndroid Build Coastguard Worker PreservedAnalyses CmpLogRoutines::run(Module &M, ModuleAnalysisManager &MAM) {
751*08b48e0bSAndroid Build Coastguard Worker 
752*08b48e0bSAndroid Build Coastguard Worker #else
753*08b48e0bSAndroid Build Coastguard Worker bool CmpLogRoutines::runOnModule(Module &M) {
754*08b48e0bSAndroid Build Coastguard Worker 
755*08b48e0bSAndroid Build Coastguard Worker #endif
756*08b48e0bSAndroid Build Coastguard Worker 
757*08b48e0bSAndroid Build Coastguard Worker   if (getenv("AFL_QUIET") == NULL)
758*08b48e0bSAndroid Build Coastguard Worker     printf("Running cmplog-routines-pass by [email protected]\n");
759*08b48e0bSAndroid Build Coastguard Worker   else
760*08b48e0bSAndroid Build Coastguard Worker     be_quiet = 1;
761*08b48e0bSAndroid Build Coastguard Worker   hookRtns(M);
762*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 11                        /* use new pass manager */
763*08b48e0bSAndroid Build Coastguard Worker   auto PA = PreservedAnalyses::all();
764*08b48e0bSAndroid Build Coastguard Worker #endif
765*08b48e0bSAndroid Build Coastguard Worker   verifyModule(M);
766*08b48e0bSAndroid Build Coastguard Worker 
767*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 11                        /* use new pass manager */
768*08b48e0bSAndroid Build Coastguard Worker   return PA;
769*08b48e0bSAndroid Build Coastguard Worker #else
770*08b48e0bSAndroid Build Coastguard Worker   return true;
771*08b48e0bSAndroid Build Coastguard Worker #endif
772*08b48e0bSAndroid Build Coastguard Worker 
773*08b48e0bSAndroid Build Coastguard Worker }
774*08b48e0bSAndroid Build Coastguard Worker 
775*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR < 11                         /* use old pass manager */
776*08b48e0bSAndroid Build Coastguard Worker static void registerCmpLogRoutinesPass(const PassManagerBuilder &,
777*08b48e0bSAndroid Build Coastguard Worker                                        legacy::PassManagerBase &PM) {
778*08b48e0bSAndroid Build Coastguard Worker 
779*08b48e0bSAndroid Build Coastguard Worker   auto p = new CmpLogRoutines();
780*08b48e0bSAndroid Build Coastguard Worker   PM.add(p);
781*08b48e0bSAndroid Build Coastguard Worker 
782*08b48e0bSAndroid Build Coastguard Worker }
783*08b48e0bSAndroid Build Coastguard Worker 
784*08b48e0bSAndroid Build Coastguard Worker static RegisterStandardPasses RegisterCmpLogRoutinesPass(
785*08b48e0bSAndroid Build Coastguard Worker     PassManagerBuilder::EP_OptimizerLast, registerCmpLogRoutinesPass);
786*08b48e0bSAndroid Build Coastguard Worker 
787*08b48e0bSAndroid Build Coastguard Worker static RegisterStandardPasses RegisterCmpLogRoutinesPass0(
788*08b48e0bSAndroid Build Coastguard Worker     PassManagerBuilder::EP_EnabledOnOptLevel0, registerCmpLogRoutinesPass);
789*08b48e0bSAndroid Build Coastguard Worker 
790*08b48e0bSAndroid Build Coastguard Worker   #if LLVM_VERSION_MAJOR >= 11
791*08b48e0bSAndroid Build Coastguard Worker static RegisterStandardPasses RegisterCmpLogRoutinesPassLTO(
792*08b48e0bSAndroid Build Coastguard Worker     PassManagerBuilder::EP_FullLinkTimeOptimizationLast,
793*08b48e0bSAndroid Build Coastguard Worker     registerCmpLogRoutinesPass);
794*08b48e0bSAndroid Build Coastguard Worker   #endif
795*08b48e0bSAndroid Build Coastguard Worker #endif
796*08b48e0bSAndroid Build Coastguard Worker 
797