xref: /minix3/minix/llvm/passes/hello/hello.cpp (revision 3e457fe321c6af238c180a2b4a0f010f8b4f8c31)
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