1 #include <pass.h> 2 #include <stdlib.h> 3 4 using namespace llvm; 5 6 #define DBG(M) M 7 #define helloPassLog(M) DBG(errs() << "HelloPass: " << M << "\n") 8 #define MSG "Hello world!" 9 #define ERROR_FAILURE 1 10 11 namespace { 12 13 class HelloPass : public ModulePass { 14 15 public: 16 static char ID; 17 18 19 HelloPass() : ModulePass(ID) { } 20 21 22 virtual bool runOnModule(Module &M) { 23 24 Function* printfFunction = NULL; 25 Function* mainFunction = NULL; 26 27 mainFunction = M.getFunction("main"); 28 if (NULL == mainFunction) 29 { 30 helloPassLog("Info: main() not found. Skipping instrumentation."); 31 return false; 32 } 33 34 /* Prepare the string arguments for printf */ 35 std::string printFuncName = "printf" ; 36 const std::string msg = MSG; 37 const std::string fmt = "%s\n"; 38 Constant* strConstMsg = NULL; 39 Constant* strConstFmt = NULL; 40 std::vector<Value*> args(0); 41 Instruction *I = NULL; 42 43 PassUtil::getStringGlobalVariable(M, fmt, ".fmtStr", "", &strConstFmt, false); 44 PassUtil::getStringGlobalVariable(M, msg, ".helloworld", "", &strConstMsg, false); 45 46 if (NULL == strConstFmt || NULL == strConstMsg) 47 { 48 helloPassLog("Error: Prepared string contants point to NULL"); 49 exitOnError(ERROR_FAILURE); 50 } 51 52 args.push_back(strConstFmt); 53 args.push_back(strConstMsg); 54 55 /* Look for printf declaration */ 56 std::vector<TYPECONST Type*> functionTyArgs; 57 FunctionType* printfFuncType; 58 59 functionTyArgs.push_back(PointerType::get(IntegerType::get(M.getContext(), 8), 0)); 60 61 printfFuncType = PassUtil::getFunctionType(IntegerType::get(M.getContext(), 32), functionTyArgs, true); 62 if (NULL == printfFuncType) 63 { 64 helloPassLog("Error: Couldn't make function-type for printf."); 65 exitOnError(ERROR_FAILURE); 66 } 67 68 printfFunction = (Function *) M.getOrInsertFunction(printFuncName, printfFuncType); 69 if (NULL == printfFunction) 70 { 71 helloPassLog("Error: Couldnt find printf function declaration."); 72 exitOnError(ERROR_FAILURE); 73 } 74 75 /* Insert call instruction in main() to call printf */ 76 I = mainFunction->getBasicBlockList().begin()->begin(); 77 if (NULL != I) 78 { 79 if (args.empty()) 80 { 81 helloPassLog("Warning: args to printf is empty."); 82 } 83 84 helloPassLog("Info: Inserting printf call instruction"); 85 86 CallInst* callInst = PassUtil::createCallInstruction(printfFunction, args, "", I); 87 88 if (NULL == callInst ) 89 { 90 helloPassLog("Error: callInstr is null."); 91 exitOnError(ERROR_FAILURE); 92 } 93 94 helloPassLog("Info: Inserting call instruction successful."); 95 96 return true; 97 } 98 99 return false; 100 } 101 102 private: 103 void exitOnError(int errCode) 104 { 105 helloPassLog("Aborting instrumentation."); 106 exit(errCode); 107 } 108 109 }; 110 111 } 112 113 char HelloPass::ID = 0; 114 RegisterPass<HelloPass> HP("hello", "Hello Pass", false, false); 115