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