#include <iostream> #include <string> #include <vector> #include <map> using namespace std; #include "llvm/Constants.h" #include "llvm/Pass.h" #include "llvm/Function.h" #include "llvm/Instruction.h" #include "llvm/Instructions.h" #include "llvm/Module.h" #include "llvm/Support/InstIterator.h" #include "llvm/Support/raw_ostream.h" #include "llvm/ADT/Statistic.h" #include "llvm/DerivedTypes.h" #include "llvm/Value.h" #include "llvm/ValueSymbolTable.h" #include "llvm/Support/IRBuilder.h" #include "llvm/Type.h" #include <llvm/LLVMContext.h> #include <llvm/Support/MemoryBuffer.h> #include <llvm/Bitcode/ReaderWriter.h> #include "llvm/Support/system_error.h" #include <llvm/ADT/ArrayRef.h> #include "llvm/Support/TypeBuilder.h" using namespace llvm; #include <assert.h> struct Hello: public ModulePass{ public: static char ID; Hello() : ModulePass(ID) { my_section = new StringRef("my_section"); } virtual bool runOnModule(Module &M) { /* Run "FunctionPass" */ bool retval = false; for(Module::iterator f = M.begin(); f != M.end(); ++f) retval |= runOnFunction(*f, M); //M.dump(); return retval; } private: StringRef *my_section; map<Value *, GlobalVariable *> my_shadowMap; map<Function *, pair<Value *, Value *> > my_ptrAssigns; Function *my_createAssignHook(Module &M, Type *ptrType) { /* Create arguments for new function */ vector<Type *> v_params; v_params.push_back(ptrType); /* Shadow */ v_params.push_back(ptrType); /* New Value */ v_params.push_back(ptrType); /* Pointer */ //v_params.push_back(Type::getInt32PtrTy(M.getContext())); /* Function */ ArrayRef<Type *> a_params(v_params); /* Create new function */ FunctionType *my_funcType = FunctionType::get(Type::getVoidTy(M.getContext()), a_params, false); Function *newFunc = Function::Create(my_funcType, GlobalValue::PrivateLinkage, "", &M); newFunc->setSection(*my_section); /* Start Code */ BasicBlock *block = BasicBlock::Create(M.getContext(), "", newFunc); Value *val = newFunc->arg_begin(); Value *ptr = ++(newFunc->arg_begin()); new StoreInst(val, ptr, block); /* End Code */ ReturnInst::Create(M.getContext(), block); return newFunc; } bool runOnFunction(Function &F, Module &M) { bool retval = false; for(inst_iterator i = inst_begin(F); i != inst_end(F); ++i) { StoreInst *store = dyn_cast<StoreInst>(&*i); if(store != NULL) { if(store->getValueOperand()->getType()->isPointerTy()) { PointerType *pointerType = cast<PointerType>(store->getValueOperand()->getType()); if(pointerType->getTypeAtIndex(0u)->isFunctionTy() == true) { /* Store Assignment */ pair<Value *, Value *> assign = make_pair(store->getPointerOperand(), store->getValueOperand()); my_ptrAssigns.insert(make_pair(&F, assign)); //TODO: mem leak? /* Create shadow copy of variable, if needed */ GlobalVariable *shadow; map<Value *, GlobalVariable *>::iterator it = my_shadowMap.find(store->getPointerOperand()); if(it == my_shadowMap.end()) { shadow = new GlobalVariable(M, pointerType, false, GlobalValue::PrivateLinkage, Constant::getNullValue(pointerType), ""); shadow->setSection(*my_section); pair<map<Value *, GlobalVariable *>::iterator, bool> result; my_shadowMap.insert(make_pair(store->getPointerOperand(), shadow)); } else { shadow = it->second; } /* Make arguments */ vector<Value *> v_args; v_args.push_back(shadow); v_args.push_back(store->getValueOperand()); v_args.push_back(store->getPointerOperand()); //v_args.push_back(&F); ArrayRef<Value *> a_args(v_args); /* Insert Hook */ ++i; Function *hook = my_createAssignHook(M, store->getValueOperand()->getType()); M.dump(); CallInst::Create(hook, a_args, "", &*i); //M.dump(); --i; retval = true; } } } } //M.dump(); return retval; } }; char Hello::ID = 0; static RegisterPass<Hello> X("hello", "Hello World Pass");