1*08b48e0bSAndroid Build Coastguard Worker /* 2*08b48e0bSAndroid Build Coastguard Worker american fuzzy lop++ - LLVM CmpLog instrumentation 3*08b48e0bSAndroid Build Coastguard Worker -------------------------------------------------- 4*08b48e0bSAndroid Build Coastguard Worker 5*08b48e0bSAndroid Build Coastguard Worker Written by Andrea Fioraldi <[email protected]> 6*08b48e0bSAndroid Build Coastguard Worker 7*08b48e0bSAndroid Build Coastguard Worker Copyright 2015, 2016 Google Inc. All rights reserved. 8*08b48e0bSAndroid Build Coastguard Worker Copyright 2019-2024 AFLplusplus Project. All rights reserved. 9*08b48e0bSAndroid Build Coastguard Worker 10*08b48e0bSAndroid Build Coastguard Worker Licensed under the Apache License, Version 2.0 (the "License"); 11*08b48e0bSAndroid Build Coastguard Worker you may not use this file except in compliance with the License. 12*08b48e0bSAndroid Build Coastguard Worker You may obtain a copy of the License at: 13*08b48e0bSAndroid Build Coastguard Worker 14*08b48e0bSAndroid Build Coastguard Worker https://www.apache.org/licenses/LICENSE-2.0 15*08b48e0bSAndroid Build Coastguard Worker 16*08b48e0bSAndroid Build Coastguard Worker */ 17*08b48e0bSAndroid Build Coastguard Worker 18*08b48e0bSAndroid Build Coastguard Worker #include <stdio.h> 19*08b48e0bSAndroid Build Coastguard Worker #include <stdlib.h> 20*08b48e0bSAndroid Build Coastguard Worker #include <unistd.h> 21*08b48e0bSAndroid Build Coastguard Worker 22*08b48e0bSAndroid Build Coastguard Worker #include <iostream> 23*08b48e0bSAndroid Build Coastguard Worker #include <list> 24*08b48e0bSAndroid Build Coastguard Worker #include <string> 25*08b48e0bSAndroid Build Coastguard Worker #include <fstream> 26*08b48e0bSAndroid Build Coastguard Worker #include <sys/time.h> 27*08b48e0bSAndroid Build Coastguard Worker 28*08b48e0bSAndroid Build Coastguard Worker #include "llvm/Config/llvm-config.h" 29*08b48e0bSAndroid Build Coastguard Worker #include "llvm/ADT/Statistic.h" 30*08b48e0bSAndroid Build Coastguard Worker #include "llvm/IR/IRBuilder.h" 31*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ 32*08b48e0bSAndroid Build Coastguard Worker #include "llvm/Passes/PassPlugin.h" 33*08b48e0bSAndroid Build Coastguard Worker #include "llvm/Passes/PassBuilder.h" 34*08b48e0bSAndroid Build Coastguard Worker #include "llvm/IR/PassManager.h" 35*08b48e0bSAndroid Build Coastguard Worker #else 36*08b48e0bSAndroid Build Coastguard Worker #include "llvm/IR/LegacyPassManager.h" 37*08b48e0bSAndroid Build Coastguard Worker #include "llvm/Transforms/IPO/PassManagerBuilder.h" 38*08b48e0bSAndroid Build Coastguard Worker #endif 39*08b48e0bSAndroid Build Coastguard Worker #include "llvm/IR/Module.h" 40*08b48e0bSAndroid Build Coastguard Worker #include "llvm/Support/Debug.h" 41*08b48e0bSAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h" 42*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR < 17 43*08b48e0bSAndroid Build Coastguard Worker #include "llvm/Transforms/IPO/PassManagerBuilder.h" 44*08b48e0bSAndroid Build Coastguard Worker #endif 45*08b48e0bSAndroid Build Coastguard Worker #include "llvm/Transforms/Utils/BasicBlockUtils.h" 46*08b48e0bSAndroid Build Coastguard Worker #include "llvm/Pass.h" 47*08b48e0bSAndroid Build Coastguard Worker #include "llvm/Analysis/ValueTracking.h" 48*08b48e0bSAndroid Build Coastguard Worker 49*08b48e0bSAndroid Build Coastguard Worker #include "llvm/IR/IRBuilder.h" 50*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 4 || \ 51*08b48e0bSAndroid Build Coastguard Worker (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR > 4) 52*08b48e0bSAndroid Build Coastguard Worker #include "llvm/IR/Verifier.h" 53*08b48e0bSAndroid Build Coastguard Worker #include "llvm/IR/DebugInfo.h" 54*08b48e0bSAndroid Build Coastguard Worker #else 55*08b48e0bSAndroid Build Coastguard Worker #include "llvm/Analysis/Verifier.h" 56*08b48e0bSAndroid Build Coastguard Worker #include "llvm/DebugInfo.h" 57*08b48e0bSAndroid Build Coastguard Worker #define nullptr 0 58*08b48e0bSAndroid Build Coastguard Worker #endif 59*08b48e0bSAndroid Build Coastguard Worker 60*08b48e0bSAndroid Build Coastguard Worker #include <set> 61*08b48e0bSAndroid Build Coastguard Worker #include "afl-llvm-common.h" 62*08b48e0bSAndroid Build Coastguard Worker 63*08b48e0bSAndroid Build Coastguard Worker using namespace llvm; 64*08b48e0bSAndroid Build Coastguard Worker 65*08b48e0bSAndroid Build Coastguard Worker namespace { 66*08b48e0bSAndroid Build Coastguard Worker 67*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ 68*08b48e0bSAndroid Build Coastguard Worker class CmplogSwitches : public PassInfoMixin<CmplogSwitches> { 69*08b48e0bSAndroid Build Coastguard Worker 70*08b48e0bSAndroid Build Coastguard Worker public: CmplogSwitches()71*08b48e0bSAndroid Build Coastguard Worker CmplogSwitches() { 72*08b48e0bSAndroid Build Coastguard Worker 73*08b48e0bSAndroid Build Coastguard Worker #else 74*08b48e0bSAndroid Build Coastguard Worker class CmplogSwitches : public ModulePass { 75*08b48e0bSAndroid Build Coastguard Worker 76*08b48e0bSAndroid Build Coastguard Worker public: 77*08b48e0bSAndroid Build Coastguard Worker static char ID; 78*08b48e0bSAndroid Build Coastguard Worker CmplogSwitches() : ModulePass(ID) { 79*08b48e0bSAndroid Build Coastguard Worker 80*08b48e0bSAndroid Build Coastguard Worker #endif 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 const char *getPassName() const override { 92*08b48e0bSAndroid Build Coastguard Worker 93*08b48e0bSAndroid Build Coastguard Worker #else 94*08b48e0bSAndroid Build Coastguard Worker StringRef getPassName() const override { 95*08b48e0bSAndroid Build Coastguard Worker 96*08b48e0bSAndroid Build Coastguard Worker #endif 97*08b48e0bSAndroid Build Coastguard Worker return "cmplog switch split"; 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 hookInstrs(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, "cmplogswitches", "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(CmplogSwitches()); 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 CmplogSwitches::ID = 0; 134*08b48e0bSAndroid Build Coastguard Worker #endif 135*08b48e0bSAndroid Build Coastguard Worker 136*08b48e0bSAndroid Build Coastguard Worker template <class Iterator> 137*08b48e0bSAndroid Build Coastguard Worker Iterator Unique(Iterator first, Iterator last) { 138*08b48e0bSAndroid Build Coastguard Worker 139*08b48e0bSAndroid Build Coastguard Worker while (first != last) { 140*08b48e0bSAndroid Build Coastguard Worker 141*08b48e0bSAndroid Build Coastguard Worker Iterator next(first); 142*08b48e0bSAndroid Build Coastguard Worker last = std::remove(++next, last, *first); 143*08b48e0bSAndroid Build Coastguard Worker first = next; 144*08b48e0bSAndroid Build Coastguard Worker 145*08b48e0bSAndroid Build Coastguard Worker } 146*08b48e0bSAndroid Build Coastguard Worker 147*08b48e0bSAndroid Build Coastguard Worker return last; 148*08b48e0bSAndroid Build Coastguard Worker 149*08b48e0bSAndroid Build Coastguard Worker } 150*08b48e0bSAndroid Build Coastguard Worker 151*08b48e0bSAndroid Build Coastguard Worker bool CmplogSwitches::hookInstrs(Module &M) { 152*08b48e0bSAndroid Build Coastguard Worker 153*08b48e0bSAndroid Build Coastguard Worker std::vector<SwitchInst *> switches; 154*08b48e0bSAndroid Build Coastguard Worker LLVMContext &C = M.getContext(); 155*08b48e0bSAndroid Build Coastguard Worker 156*08b48e0bSAndroid Build Coastguard Worker Type *VoidTy = Type::getVoidTy(C); 157*08b48e0bSAndroid Build Coastguard Worker IntegerType *Int8Ty = IntegerType::getInt8Ty(C); 158*08b48e0bSAndroid Build Coastguard Worker IntegerType *Int16Ty = IntegerType::getInt16Ty(C); 159*08b48e0bSAndroid Build Coastguard Worker IntegerType *Int32Ty = IntegerType::getInt32Ty(C); 160*08b48e0bSAndroid Build Coastguard Worker IntegerType *Int64Ty = IntegerType::getInt64Ty(C); 161*08b48e0bSAndroid Build Coastguard Worker 162*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 9 163*08b48e0bSAndroid Build Coastguard Worker FunctionCallee 164*08b48e0bSAndroid Build Coastguard Worker #else 165*08b48e0bSAndroid Build Coastguard Worker Constant * 166*08b48e0bSAndroid Build Coastguard Worker #endif 167*08b48e0bSAndroid Build Coastguard Worker c1 = M.getOrInsertFunction("__cmplog_ins_hook1", VoidTy, Int8Ty, Int8Ty, 168*08b48e0bSAndroid Build Coastguard Worker Int8Ty 169*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR < 5 170*08b48e0bSAndroid Build Coastguard Worker , 171*08b48e0bSAndroid Build Coastguard Worker NULL 172*08b48e0bSAndroid Build Coastguard Worker #endif 173*08b48e0bSAndroid Build Coastguard Worker ); 174*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 9 175*08b48e0bSAndroid Build Coastguard Worker FunctionCallee cmplogHookIns1 = c1; 176*08b48e0bSAndroid Build Coastguard Worker #else 177*08b48e0bSAndroid Build Coastguard Worker Function *cmplogHookIns1 = cast<Function>(c1); 178*08b48e0bSAndroid Build Coastguard Worker #endif 179*08b48e0bSAndroid Build Coastguard Worker 180*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 9 181*08b48e0bSAndroid Build Coastguard Worker FunctionCallee 182*08b48e0bSAndroid Build Coastguard Worker #else 183*08b48e0bSAndroid Build Coastguard Worker Constant * 184*08b48e0bSAndroid Build Coastguard Worker #endif 185*08b48e0bSAndroid Build Coastguard Worker c2 = M.getOrInsertFunction("__cmplog_ins_hook2", VoidTy, Int16Ty, Int16Ty, 186*08b48e0bSAndroid Build Coastguard Worker Int8Ty 187*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR < 5 188*08b48e0bSAndroid Build Coastguard Worker , 189*08b48e0bSAndroid Build Coastguard Worker NULL 190*08b48e0bSAndroid Build Coastguard Worker #endif 191*08b48e0bSAndroid Build Coastguard Worker ); 192*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 9 193*08b48e0bSAndroid Build Coastguard Worker FunctionCallee cmplogHookIns2 = c2; 194*08b48e0bSAndroid Build Coastguard Worker #else 195*08b48e0bSAndroid Build Coastguard Worker Function *cmplogHookIns2 = cast<Function>(c2); 196*08b48e0bSAndroid Build Coastguard Worker #endif 197*08b48e0bSAndroid Build Coastguard Worker 198*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 9 199*08b48e0bSAndroid Build Coastguard Worker FunctionCallee 200*08b48e0bSAndroid Build Coastguard Worker #else 201*08b48e0bSAndroid Build Coastguard Worker Constant * 202*08b48e0bSAndroid Build Coastguard Worker #endif 203*08b48e0bSAndroid Build Coastguard Worker c4 = M.getOrInsertFunction("__cmplog_ins_hook4", VoidTy, Int32Ty, Int32Ty, 204*08b48e0bSAndroid Build Coastguard Worker Int8Ty 205*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR < 5 206*08b48e0bSAndroid Build Coastguard Worker , 207*08b48e0bSAndroid Build Coastguard Worker NULL 208*08b48e0bSAndroid Build Coastguard Worker #endif 209*08b48e0bSAndroid Build Coastguard Worker ); 210*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 9 211*08b48e0bSAndroid Build Coastguard Worker FunctionCallee cmplogHookIns4 = c4; 212*08b48e0bSAndroid Build Coastguard Worker #else 213*08b48e0bSAndroid Build Coastguard Worker Function *cmplogHookIns4 = cast<Function>(c4); 214*08b48e0bSAndroid Build Coastguard Worker #endif 215*08b48e0bSAndroid Build Coastguard Worker 216*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 9 217*08b48e0bSAndroid Build Coastguard Worker FunctionCallee 218*08b48e0bSAndroid Build Coastguard Worker #else 219*08b48e0bSAndroid Build Coastguard Worker Constant * 220*08b48e0bSAndroid Build Coastguard Worker #endif 221*08b48e0bSAndroid Build Coastguard Worker c8 = M.getOrInsertFunction("__cmplog_ins_hook8", VoidTy, Int64Ty, Int64Ty, 222*08b48e0bSAndroid Build Coastguard Worker Int8Ty 223*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR < 5 224*08b48e0bSAndroid Build Coastguard Worker , 225*08b48e0bSAndroid Build Coastguard Worker NULL 226*08b48e0bSAndroid Build Coastguard Worker #endif 227*08b48e0bSAndroid Build Coastguard Worker ); 228*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 9 229*08b48e0bSAndroid Build Coastguard Worker FunctionCallee cmplogHookIns8 = c8; 230*08b48e0bSAndroid Build Coastguard Worker #else 231*08b48e0bSAndroid Build Coastguard Worker Function *cmplogHookIns8 = cast<Function>(c8); 232*08b48e0bSAndroid Build Coastguard Worker #endif 233*08b48e0bSAndroid Build Coastguard Worker 234*08b48e0bSAndroid Build Coastguard Worker GlobalVariable *AFLCmplogPtr = M.getNamedGlobal("__afl_cmp_map"); 235*08b48e0bSAndroid Build Coastguard Worker 236*08b48e0bSAndroid Build Coastguard Worker if (!AFLCmplogPtr) { 237*08b48e0bSAndroid Build Coastguard Worker 238*08b48e0bSAndroid Build Coastguard Worker AFLCmplogPtr = new GlobalVariable(M, PointerType::get(Int8Ty, 0), false, 239*08b48e0bSAndroid Build Coastguard Worker GlobalValue::ExternalWeakLinkage, 0, 240*08b48e0bSAndroid Build Coastguard Worker "__afl_cmp_map"); 241*08b48e0bSAndroid Build Coastguard Worker 242*08b48e0bSAndroid Build Coastguard Worker } 243*08b48e0bSAndroid Build Coastguard Worker 244*08b48e0bSAndroid Build Coastguard Worker Constant *Null = Constant::getNullValue(PointerType::get(Int8Ty, 0)); 245*08b48e0bSAndroid Build Coastguard Worker 246*08b48e0bSAndroid Build Coastguard Worker /* iterate over all functions, bbs and instruction and add suitable calls */ 247*08b48e0bSAndroid Build Coastguard Worker for (auto &F : M) { 248*08b48e0bSAndroid Build Coastguard Worker 249*08b48e0bSAndroid Build Coastguard Worker if (!isInInstrumentList(&F, MNAME)) continue; 250*08b48e0bSAndroid Build Coastguard Worker 251*08b48e0bSAndroid Build Coastguard Worker for (auto &BB : F) { 252*08b48e0bSAndroid Build Coastguard Worker 253*08b48e0bSAndroid Build Coastguard Worker SwitchInst *switchInst = nullptr; 254*08b48e0bSAndroid Build Coastguard Worker if ((switchInst = dyn_cast<SwitchInst>(BB.getTerminator()))) { 255*08b48e0bSAndroid Build Coastguard Worker 256*08b48e0bSAndroid Build Coastguard Worker if (switchInst->getNumCases() > 1) { switches.push_back(switchInst); } 257*08b48e0bSAndroid Build Coastguard Worker 258*08b48e0bSAndroid Build Coastguard Worker } 259*08b48e0bSAndroid Build Coastguard Worker 260*08b48e0bSAndroid Build Coastguard Worker } 261*08b48e0bSAndroid Build Coastguard Worker 262*08b48e0bSAndroid Build Coastguard Worker } 263*08b48e0bSAndroid Build Coastguard Worker 264*08b48e0bSAndroid Build Coastguard Worker // unique the collected switches 265*08b48e0bSAndroid Build Coastguard Worker switches.erase(Unique(switches.begin(), switches.end()), switches.end()); 266*08b48e0bSAndroid Build Coastguard Worker 267*08b48e0bSAndroid Build Coastguard Worker // Instrument switch values for cmplog 268*08b48e0bSAndroid Build Coastguard Worker if (switches.size()) { 269*08b48e0bSAndroid Build Coastguard Worker 270*08b48e0bSAndroid Build Coastguard Worker if (!be_quiet) 271*08b48e0bSAndroid Build Coastguard Worker errs() << "Hooking " << switches.size() << " switch instructions\n"; 272*08b48e0bSAndroid Build Coastguard Worker 273*08b48e0bSAndroid Build Coastguard Worker for (auto &SI : switches) { 274*08b48e0bSAndroid Build Coastguard Worker 275*08b48e0bSAndroid Build Coastguard Worker Value *Val = SI->getCondition(); 276*08b48e0bSAndroid Build Coastguard Worker unsigned int max_size = Val->getType()->getIntegerBitWidth(), cast_size; 277*08b48e0bSAndroid Build Coastguard Worker unsigned char do_cast = 0; 278*08b48e0bSAndroid Build Coastguard Worker 279*08b48e0bSAndroid Build Coastguard Worker if (!SI->getNumCases() || max_size < 16) { 280*08b48e0bSAndroid Build Coastguard Worker 281*08b48e0bSAndroid Build Coastguard Worker // if (!be_quiet) errs() << "skip trivial switch..\n"; 282*08b48e0bSAndroid Build Coastguard Worker continue; 283*08b48e0bSAndroid Build Coastguard Worker 284*08b48e0bSAndroid Build Coastguard Worker } 285*08b48e0bSAndroid Build Coastguard Worker 286*08b48e0bSAndroid Build Coastguard Worker if (max_size % 8) { 287*08b48e0bSAndroid Build Coastguard Worker 288*08b48e0bSAndroid Build Coastguard Worker max_size = (((max_size / 8) + 1) * 8); 289*08b48e0bSAndroid Build Coastguard Worker do_cast = 1; 290*08b48e0bSAndroid Build Coastguard Worker 291*08b48e0bSAndroid Build Coastguard Worker } 292*08b48e0bSAndroid Build Coastguard Worker 293*08b48e0bSAndroid Build Coastguard Worker IRBuilder<> IRB2(SI->getParent()); 294*08b48e0bSAndroid Build Coastguard Worker IRB2.SetInsertPoint(SI); 295*08b48e0bSAndroid Build Coastguard Worker 296*08b48e0bSAndroid Build Coastguard Worker LoadInst *CmpPtr = IRB2.CreateLoad( 297*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 14 298*08b48e0bSAndroid Build Coastguard Worker PointerType::get(Int8Ty, 0), 299*08b48e0bSAndroid Build Coastguard Worker #endif 300*08b48e0bSAndroid Build Coastguard Worker AFLCmplogPtr); 301*08b48e0bSAndroid Build Coastguard Worker CmpPtr->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); 302*08b48e0bSAndroid Build Coastguard Worker auto is_not_null = IRB2.CreateICmpNE(CmpPtr, Null); 303*08b48e0bSAndroid Build Coastguard Worker auto ThenTerm = SplitBlockAndInsertIfThen(is_not_null, SI, false); 304*08b48e0bSAndroid Build Coastguard Worker 305*08b48e0bSAndroid Build Coastguard Worker IRBuilder<> IRB(ThenTerm); 306*08b48e0bSAndroid Build Coastguard Worker 307*08b48e0bSAndroid Build Coastguard Worker if (max_size > 128) { 308*08b48e0bSAndroid Build Coastguard Worker 309*08b48e0bSAndroid Build Coastguard Worker if (!be_quiet) { 310*08b48e0bSAndroid Build Coastguard Worker 311*08b48e0bSAndroid Build Coastguard Worker fprintf(stderr, 312*08b48e0bSAndroid Build Coastguard Worker "Cannot handle this switch bit size: %u (truncating)\n", 313*08b48e0bSAndroid Build Coastguard Worker max_size); 314*08b48e0bSAndroid Build Coastguard Worker 315*08b48e0bSAndroid Build Coastguard Worker } 316*08b48e0bSAndroid Build Coastguard Worker 317*08b48e0bSAndroid Build Coastguard Worker max_size = 128; 318*08b48e0bSAndroid Build Coastguard Worker do_cast = 1; 319*08b48e0bSAndroid Build Coastguard Worker 320*08b48e0bSAndroid Build Coastguard Worker } 321*08b48e0bSAndroid Build Coastguard Worker 322*08b48e0bSAndroid Build Coastguard Worker // do we need to cast? 323*08b48e0bSAndroid Build Coastguard Worker switch (max_size) { 324*08b48e0bSAndroid Build Coastguard Worker 325*08b48e0bSAndroid Build Coastguard Worker case 8: 326*08b48e0bSAndroid Build Coastguard Worker case 16: 327*08b48e0bSAndroid Build Coastguard Worker case 32: 328*08b48e0bSAndroid Build Coastguard Worker case 64: 329*08b48e0bSAndroid Build Coastguard Worker case 128: 330*08b48e0bSAndroid Build Coastguard Worker cast_size = max_size; 331*08b48e0bSAndroid Build Coastguard Worker break; 332*08b48e0bSAndroid Build Coastguard Worker default: 333*08b48e0bSAndroid Build Coastguard Worker cast_size = 128; 334*08b48e0bSAndroid Build Coastguard Worker do_cast = 1; 335*08b48e0bSAndroid Build Coastguard Worker 336*08b48e0bSAndroid Build Coastguard Worker } 337*08b48e0bSAndroid Build Coastguard Worker 338*08b48e0bSAndroid Build Coastguard Worker Value *CompareTo = Val; 339*08b48e0bSAndroid Build Coastguard Worker 340*08b48e0bSAndroid Build Coastguard Worker if (do_cast) { 341*08b48e0bSAndroid Build Coastguard Worker 342*08b48e0bSAndroid Build Coastguard Worker CompareTo = 343*08b48e0bSAndroid Build Coastguard Worker IRB.CreateIntCast(CompareTo, IntegerType::get(C, cast_size), false); 344*08b48e0bSAndroid Build Coastguard Worker 345*08b48e0bSAndroid Build Coastguard Worker } 346*08b48e0bSAndroid Build Coastguard Worker 347*08b48e0bSAndroid Build Coastguard Worker for (SwitchInst::CaseIt i = SI->case_begin(), e = SI->case_end(); i != e; 348*08b48e0bSAndroid Build Coastguard Worker ++i) { 349*08b48e0bSAndroid Build Coastguard Worker 350*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR < 5 351*08b48e0bSAndroid Build Coastguard Worker ConstantInt *cint = i.getCaseValue(); 352*08b48e0bSAndroid Build Coastguard Worker #else 353*08b48e0bSAndroid Build Coastguard Worker ConstantInt *cint = i->getCaseValue(); 354*08b48e0bSAndroid Build Coastguard Worker #endif 355*08b48e0bSAndroid Build Coastguard Worker 356*08b48e0bSAndroid Build Coastguard Worker if (cint) { 357*08b48e0bSAndroid Build Coastguard Worker 358*08b48e0bSAndroid Build Coastguard Worker std::vector<Value *> args; 359*08b48e0bSAndroid Build Coastguard Worker args.push_back(CompareTo); 360*08b48e0bSAndroid Build Coastguard Worker 361*08b48e0bSAndroid Build Coastguard Worker Value *new_param = cint; 362*08b48e0bSAndroid Build Coastguard Worker 363*08b48e0bSAndroid Build Coastguard Worker if (do_cast) { 364*08b48e0bSAndroid Build Coastguard Worker 365*08b48e0bSAndroid Build Coastguard Worker new_param = 366*08b48e0bSAndroid Build Coastguard Worker IRB.CreateIntCast(cint, IntegerType::get(C, cast_size), false); 367*08b48e0bSAndroid Build Coastguard Worker 368*08b48e0bSAndroid Build Coastguard Worker } 369*08b48e0bSAndroid Build Coastguard Worker 370*08b48e0bSAndroid Build Coastguard Worker if (new_param) { 371*08b48e0bSAndroid Build Coastguard Worker 372*08b48e0bSAndroid Build Coastguard Worker args.push_back(new_param); 373*08b48e0bSAndroid Build Coastguard Worker ConstantInt *attribute = ConstantInt::get(Int8Ty, 1); 374*08b48e0bSAndroid Build Coastguard Worker args.push_back(attribute); 375*08b48e0bSAndroid Build Coastguard Worker if (cast_size != max_size) { 376*08b48e0bSAndroid Build Coastguard Worker 377*08b48e0bSAndroid Build Coastguard Worker ConstantInt *bitsize = 378*08b48e0bSAndroid Build Coastguard Worker ConstantInt::get(Int8Ty, (max_size / 8) - 1); 379*08b48e0bSAndroid Build Coastguard Worker args.push_back(bitsize); 380*08b48e0bSAndroid Build Coastguard Worker 381*08b48e0bSAndroid Build Coastguard Worker } 382*08b48e0bSAndroid Build Coastguard Worker 383*08b48e0bSAndroid Build Coastguard Worker switch (cast_size) { 384*08b48e0bSAndroid Build Coastguard Worker 385*08b48e0bSAndroid Build Coastguard Worker case 8: 386*08b48e0bSAndroid Build Coastguard Worker IRB.CreateCall(cmplogHookIns1, args); 387*08b48e0bSAndroid Build Coastguard Worker break; 388*08b48e0bSAndroid Build Coastguard Worker case 16: 389*08b48e0bSAndroid Build Coastguard Worker IRB.CreateCall(cmplogHookIns2, args); 390*08b48e0bSAndroid Build Coastguard Worker break; 391*08b48e0bSAndroid Build Coastguard Worker case 32: 392*08b48e0bSAndroid Build Coastguard Worker IRB.CreateCall(cmplogHookIns4, args); 393*08b48e0bSAndroid Build Coastguard Worker break; 394*08b48e0bSAndroid Build Coastguard Worker case 64: 395*08b48e0bSAndroid Build Coastguard Worker IRB.CreateCall(cmplogHookIns8, args); 396*08b48e0bSAndroid Build Coastguard Worker break; 397*08b48e0bSAndroid Build Coastguard Worker case 128: 398*08b48e0bSAndroid Build Coastguard Worker #ifdef WORD_SIZE_64 399*08b48e0bSAndroid Build Coastguard Worker if (max_size == 128) { 400*08b48e0bSAndroid Build Coastguard Worker 401*08b48e0bSAndroid Build Coastguard Worker IRB.CreateCall(cmplogHookIns16, args); 402*08b48e0bSAndroid Build Coastguard Worker 403*08b48e0bSAndroid Build Coastguard Worker } else { 404*08b48e0bSAndroid Build Coastguard Worker 405*08b48e0bSAndroid Build Coastguard Worker IRB.CreateCall(cmplogHookInsN, args); 406*08b48e0bSAndroid Build Coastguard Worker 407*08b48e0bSAndroid Build Coastguard Worker } 408*08b48e0bSAndroid Build Coastguard Worker 409*08b48e0bSAndroid Build Coastguard Worker #endif 410*08b48e0bSAndroid Build Coastguard Worker break; 411*08b48e0bSAndroid Build Coastguard Worker default: 412*08b48e0bSAndroid Build Coastguard Worker break; 413*08b48e0bSAndroid Build Coastguard Worker 414*08b48e0bSAndroid Build Coastguard Worker } 415*08b48e0bSAndroid Build Coastguard Worker 416*08b48e0bSAndroid Build Coastguard Worker } 417*08b48e0bSAndroid Build Coastguard Worker 418*08b48e0bSAndroid Build Coastguard Worker } 419*08b48e0bSAndroid Build Coastguard Worker 420*08b48e0bSAndroid Build Coastguard Worker } 421*08b48e0bSAndroid Build Coastguard Worker 422*08b48e0bSAndroid Build Coastguard Worker } 423*08b48e0bSAndroid Build Coastguard Worker 424*08b48e0bSAndroid Build Coastguard Worker } 425*08b48e0bSAndroid Build Coastguard Worker 426*08b48e0bSAndroid Build Coastguard Worker if (switches.size()) 427*08b48e0bSAndroid Build Coastguard Worker return true; 428*08b48e0bSAndroid Build Coastguard Worker else 429*08b48e0bSAndroid Build Coastguard Worker return false; 430*08b48e0bSAndroid Build Coastguard Worker 431*08b48e0bSAndroid Build Coastguard Worker } 432*08b48e0bSAndroid Build Coastguard Worker 433*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ 434*08b48e0bSAndroid Build Coastguard Worker PreservedAnalyses CmplogSwitches::run(Module &M, ModuleAnalysisManager &MAM) { 435*08b48e0bSAndroid Build Coastguard Worker 436*08b48e0bSAndroid Build Coastguard Worker #else 437*08b48e0bSAndroid Build Coastguard Worker bool CmplogSwitches::runOnModule(Module &M) { 438*08b48e0bSAndroid Build Coastguard Worker 439*08b48e0bSAndroid Build Coastguard Worker #endif 440*08b48e0bSAndroid Build Coastguard Worker 441*08b48e0bSAndroid Build Coastguard Worker if (getenv("AFL_QUIET") == NULL) 442*08b48e0bSAndroid Build Coastguard Worker printf("Running cmplog-switches-pass by [email protected]\n"); 443*08b48e0bSAndroid Build Coastguard Worker else 444*08b48e0bSAndroid Build Coastguard Worker be_quiet = 1; 445*08b48e0bSAndroid Build Coastguard Worker hookInstrs(M); 446*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ 447*08b48e0bSAndroid Build Coastguard Worker auto PA = PreservedAnalyses::all(); 448*08b48e0bSAndroid Build Coastguard Worker #endif 449*08b48e0bSAndroid Build Coastguard Worker verifyModule(M); 450*08b48e0bSAndroid Build Coastguard Worker 451*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ 452*08b48e0bSAndroid Build Coastguard Worker return PA; 453*08b48e0bSAndroid Build Coastguard Worker #else 454*08b48e0bSAndroid Build Coastguard Worker return true; 455*08b48e0bSAndroid Build Coastguard Worker #endif 456*08b48e0bSAndroid Build Coastguard Worker 457*08b48e0bSAndroid Build Coastguard Worker } 458*08b48e0bSAndroid Build Coastguard Worker 459*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR < 11 /* use old pass manager */ 460*08b48e0bSAndroid Build Coastguard Worker static void registerCmplogSwitchesPass(const PassManagerBuilder &, 461*08b48e0bSAndroid Build Coastguard Worker legacy::PassManagerBase &PM) { 462*08b48e0bSAndroid Build Coastguard Worker 463*08b48e0bSAndroid Build Coastguard Worker auto p = new CmplogSwitches(); 464*08b48e0bSAndroid Build Coastguard Worker PM.add(p); 465*08b48e0bSAndroid Build Coastguard Worker 466*08b48e0bSAndroid Build Coastguard Worker } 467*08b48e0bSAndroid Build Coastguard Worker 468*08b48e0bSAndroid Build Coastguard Worker static RegisterStandardPasses RegisterCmplogSwitchesPass( 469*08b48e0bSAndroid Build Coastguard Worker PassManagerBuilder::EP_OptimizerLast, registerCmplogSwitchesPass); 470*08b48e0bSAndroid Build Coastguard Worker 471*08b48e0bSAndroid Build Coastguard Worker static RegisterStandardPasses RegisterCmplogSwitchesPass0( 472*08b48e0bSAndroid Build Coastguard Worker PassManagerBuilder::EP_EnabledOnOptLevel0, registerCmplogSwitchesPass); 473*08b48e0bSAndroid Build Coastguard Worker 474*08b48e0bSAndroid Build Coastguard Worker #if LLVM_VERSION_MAJOR >= 11 475*08b48e0bSAndroid Build Coastguard Worker static RegisterStandardPasses RegisterCmplogSwitchesPassLTO( 476*08b48e0bSAndroid Build Coastguard Worker PassManagerBuilder::EP_FullLinkTimeOptimizationLast, 477*08b48e0bSAndroid Build Coastguard Worker registerCmplogSwitchesPass); 478*08b48e0bSAndroid Build Coastguard Worker #endif 479*08b48e0bSAndroid Build Coastguard Worker #endif 480*08b48e0bSAndroid Build Coastguard Worker 481