minix3/llvm/passes/hello/hello.cpp

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);