115 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			115 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| #include "pass_hello.h"
 | |
| #include <stdlib.h>
 | |
| 
 | |
| using namespace llvm;
 | |
| 
 | |
| #define DBG(M) M
 | |
| #define helloPassLog(M) DBG(errs() << "HelloPass: " << M << "\n")
 | |
| #define MSG   "Hello world!"
 | |
| #define ERROR_FAILURE   1
 | |
| 
 | |
| namespace {
 | |
| 
 | |
|   class HelloPass : public ModulePass {
 | |
| 
 | |
|   public:
 | |
|     static char ID;
 | |
| 
 | |
|     
 | |
|     HelloPass() : ModulePass(ID) { }
 | |
|     
 | |
| 
 | |
|     virtual bool runOnModule(Module &M) {
 | |
| 
 | |
|     Function* printfFunction = NULL;
 | |
|     Function* mainFunction = NULL;      
 | |
| 
 | |
|     mainFunction = M.getFunction("main");
 | |
|     if (NULL == mainFunction)
 | |
|     {
 | |
|       helloPassLog("Info: main() not found. Skipping instrumentation.");
 | |
|       return false;
 | |
|     }
 | |
| 
 | |
|     /* Prepare the string arguments for printf */
 | |
|     std::string printFuncName = "printf" ;
 | |
|     const std::string msg = MSG;
 | |
|     const std::string fmt = "%s\n";
 | |
|     Constant* strConstMsg = NULL;
 | |
|     Constant* strConstFmt = NULL;
 | |
|     std::vector<Value*> args(0);
 | |
|     Instruction *I = NULL;
 | |
| 
 | |
|     PassUtil::getStringGlobalVariable(M, fmt, ".fmtStr", "", &strConstFmt, false);
 | |
|     PassUtil::getStringGlobalVariable(M, msg, ".helloworld", "", &strConstMsg, false);
 | |
| 
 | |
|     if (NULL == strConstFmt || NULL == strConstMsg)
 | |
|     {
 | |
|   	  helloPassLog("Error: Prepared string contants point to NULL");
 | |
|   	  exitOnError(ERROR_FAILURE);
 | |
|     }
 | |
| 
 | |
|     args.push_back(strConstFmt);
 | |
|     args.push_back(strConstMsg);
 | |
|     
 | |
|     /* Look for printf declaration */
 | |
|     std::vector<TYPECONST Type*> functionTyArgs;
 | |
|     FunctionType* printfFuncType;
 | |
| 
 | |
|     functionTyArgs.push_back(PointerType::get(IntegerType::get(M.getContext(), 8), 0));
 | |
|     
 | |
|     printfFuncType = PassUtil::getFunctionType(IntegerType::get(M.getContext(), 32), functionTyArgs, true);
 | |
|     if (NULL == printfFuncType)
 | |
|     {
 | |
|       helloPassLog("Error: Couldn't make function-type for printf.");
 | |
|       exitOnError(ERROR_FAILURE);
 | |
|     }
 | |
| 
 | |
| 	  printfFunction = (Function *) M.getOrInsertFunction(printFuncName, printfFuncType);
 | |
| 	  if (NULL == printfFunction)
 | |
| 	  {
 | |
|       helloPassLog("Error: Couldnt find printf function declaration.");
 | |
|       exitOnError(ERROR_FAILURE);
 | |
|     }
 | |
|     
 | |
|     /* Insert call instruction in main() to call printf */
 | |
| 	  I = mainFunction->getBasicBlockList().begin()->begin();
 | |
| 	  if (NULL != I)
 | |
| 	  {
 | |
| 		  if (args.empty())
 | |
| 		  {
 | |
| 			  helloPassLog("Warning: args to printf is empty.");
 | |
| 		  }
 | |
| 
 | |
| 		  helloPassLog("Info: Inserting printf call instruction");
 | |
| 
 | |
| 		  CallInst* callInst = PassUtil::createCallInstruction(printfFunction, args, "", I);
 | |
| 
 | |
| 		  if (NULL == callInst )
 | |
| 		  {
 | |
| 			  helloPassLog("Error: callInstr is null.");
 | |
| 			  exitOnError(ERROR_FAILURE);
 | |
| 		  }
 | |
| 
 | |
| 		  helloPassLog("Info: Inserting call instruction successful.");
 | |
| 
 | |
| 		  return true;
 | |
| 	  }
 | |
| 	  
 | |
|       return false;
 | |
|     }
 | |
| 
 | |
|     private:
 | |
|     void exitOnError(int errCode)
 | |
|     {
 | |
|       helloPassLog("Aborting instrumentation.");
 | |
|     	exit(errCode);
 | |
|     }
 | |
| 
 | |
|   };
 | |
| 
 | |
| }
 | |
| 
 | |
| char HelloPass::ID = 0;
 | |
| RegisterPass<HelloPass> HP("hello", "Hello Pass", false, false);
 | 
