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