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