--- /dev/null
+#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);
--- /dev/null
+#ifndef _PASS_HELLO_H
+#define _PASS_HELLO_H
+
+#if LLVM_VERSION >= 33
+#define ATTRIBUTE_SET_TY AttributeSet
+#include <llvm/IR/Function.h>
+#include <llvm/IR/Module.h>
+#include <llvm/IR/Instructions.h>
+#include <llvm/IR/Type.h>
+#include <llvm/IR/Constants.h>
+#include <llvm/IR/Intrinsics.h>
+#include <llvm/IR/DerivedTypes.h>
+#include <llvm/IR/LLVMContext.h>
+#include <llvm/IR/IntrinsicInst.h>
+#include <llvm/IR/DataLayout.h>
+#include <llvm/IR/IRBuilder.h>
+#include <llvm/Support/raw_ostream.h>
+#else /* LLVM_VERSION < 33 */
+#define ATTRIBUTE_SET_TY AttrListPtr
+#include <llvm/Function.h>
+#include <llvm/Module.h>
+#include <llvm/Instructions.h>
+#include <llvm/Type.h>
+#include <llvm/Constants.h>
+#include <llvm/Intrinsics.h>
+#include <llvm/DerivedTypes.h>
+#include <llvm/LLVMContext.h>
+#include <llvm/IntrinsicInst.h>
+#endif /* LLVM_VERSION >= 33 */
+
+#if LLVM_VERSION >= 32
+#define DATA_LAYOUT_TY DataLayout
+#define ATTRIBUTE_SET_RET_IDX ATTRIBUTE_SET_TY::ReturnIndex
+#define ATTRIBUTE_SET_FN_IDX ATTRIBUTE_SET_TY::FunctionIndex
+#include <llvm/DebugInfo.h>
+#if LLVM_VERSION == 32
+#include <llvm/DataLayout.h>
+#include <llvm/IRBuilder.h>
+#endif
+#else /* LLVM_VERSION < 32 */
+#define DATA_LAYOUT_TY TargetData
+#define ATTRIBUTE_SET_RET_IDX 0
+#define ATTRIBUTE_SET_FN_IDX (~0U)
+#include <llvm/Target/TargetData.h>
+#include <llvm/Analysis/DebugInfo.h>
+#include <llvm/Support/IRBuilder.h>
+#endif /* LLVM_VERSION >= 32 */
+
+#if LLVM_VERSION >= 31
+/* XXX Check. */
+#define CONSTANT_ARRAY_INITIALIZER_TY ConstantDataArray
+
+#else /* LLVM_VERSION < 31 */
+#define CONSTANT_ARRAY_INITIALIZER_TY ConstantArray
+#endif /* LLVM_VERSION >= 31 */
+
+#if LLVM_VERSION >= 30
+#define BASE_PARSER parser
+
+#define TYPECONST
+#else /* LLVM_VERSION < 30 */
+#define BASE_PARSER basic_parser
+
+#define TYPECONST const
+#endif /* LLVM_VERSION >= 30 */
+
+#if LLVM_VERSION >= 29
+#define VALUE_TO_VALUE_MAP_TY ValueToValueMapTy
+#else /* LLVM_VERSION < 29 */
+#define VALUE_TO_VALUE_MAP_TY ValueMap<const Value*, Value*>
+#endif /* LLVM_VERSION >= 29 */
+
+#define ZERO_CONSTANT_INT(M) ConstantInt::get((M).getContext(), APInt(32, 0, 10))
+#define VOID_PTR_TY(M) PointerType::get(IntegerType::get((M).getContext(), 8), 0)
+#define VOID_PTR_PTR_TY(M) PointerType::get(PointerType::get(IntegerType::get((M).getContext(), 8), 0), 0)
+
+#define DEBUG_LLVM_DEBUG_API 0
+
+typedef enum PassUtilLinkageTypeE {
+ PASS_UTIL_LINKAGE_NONE = 0,
+ PASS_UTIL_LINKAGE_WEAK,
+ PASS_UTIL_LINKAGE_COMMON,
+ PASS_UTIL_LINKAGE_EXTERNAL,
+ PASS_UTIL_LINKAGE_EXTERNAL_WEAK,
+ PASS_UTIL_LINKAGE_WEAK_POINTER,
+ PASS_UTIL_LINKAGE_PRIVATE,
+ __NUM_PASS_UTIL_LINKAGE_TYPES
+ /* Values here should only be appended at the end, external components (e.g., scripts) may be relying on them.*/
+} PassUtilLinkageType;
+
+#define PASS_UTIL_LINKAGE_TYPE_STRINGS \
+ "NONE", \
+ "WEAK", \
+ "COMMON", \
+ "EXTERNAL", \
+ "EXTERNAL_WEAK", \
+ "WEAK_POINTER", \
+ "PRIVATE"
+
+typedef enum PassUtilPropE {
+ PASS_UTIL_PROP_NONE,
+ PASS_UTIL_PROP_NOINLINE,
+ PASS_UTIL_PROP_USED,
+ PASS_UTIL_PROP_PRESERVE,
+ __NUM_PASS_UTIL_PROPS
+} PassUtilProp;
+
+#define PASS_UTIL_FLAG(F) (1 << F)
+
+#define PASS_COMMON_INIT_ONCE() \
+ Module *PassUtil::M = NULL; \
+
+using namespace llvm;
+
+namespace llvm {
+
+class PassUtil {
+ public:
+ static Constant* getGetElementPtrConstant(Constant *constant, std::vector<Value*> &indexes);
+ static CallInst* createCallInstruction(Value *F, std::vector<Value*> &args, const Twine &NameStr="", Instruction *InsertBefore=0);
+ static CallInst* createCallInstruction(Value *F, std::vector<Value*> &args, const Twine &NameStr="", BasicBlock *InsertAtEnd=0);
+ static FunctionType* getFunctionType(TYPECONST Type* Result, std::vector<TYPECONST Type*> &argsTy, bool isVarArg=false);
+ static Constant* getStringConstantArray(Module &M, const std::string &string);
+ static GlobalVariable* getStringGlobalVariable(Module &M, const std::string &string, const std::string &varName, const std::string &varSection = "", Constant **getElementPtrExpr=NULL, bool cacheable=false);
+ private:
+ static Module *M;
+};
+
+inline Constant* PassUtil::getGetElementPtrConstant(Constant *constant, std::vector<Value*> &indexes) {
+#if LLVM_VERSION >= 30
+ ArrayRef<Value*> ref(indexes);
+ return ConstantExpr::getGetElementPtr(constant, ref);
+#else
+ return ConstantExpr::getGetElementPtr(constant, &indexes[0], indexes.size());
+#endif
+}
+
+inline CallInst* PassUtil::createCallInstruction(Value *F, std::vector<Value*> &args, const Twine &NameStr, Instruction *InsertBefore) {
+#if LLVM_VERSION >= 30
+ ArrayRef<Value*> ref(args);
+ return CallInst::Create(F, ref, NameStr, InsertBefore);
+#else
+ return CallInst::Create(F, args.begin(), args.end(), NameStr, InsertBefore);
+#endif
+}
+
+inline CallInst* PassUtil::createCallInstruction(Value *F, std::vector<Value*> &args, const Twine &NameStr, BasicBlock *InsertAtEnd) {
+#if LLVM_VERSION >= 30
+ ArrayRef<Value*> ref(args);
+ return CallInst::Create(F, ref, NameStr, InsertAtEnd);
+#else
+ return CallInst::Create(F, args.begin(), args.end(), NameStr, InsertAtEnd);
+#endif
+}
+
+inline FunctionType* PassUtil::getFunctionType(TYPECONST Type* Result, std::vector<TYPECONST Type*> &argsTy, bool isVarArg)
+{
+#if LLVM_VERSION >= 30
+ ArrayRef<TYPECONST Type*> ref(argsTy);
+ return FunctionType::get(Result, ref, isVarArg);
+#else
+ return FunctionType::get(Result, argsTy, isVarArg);
+#endif
+}
+
+
+inline Constant* PassUtil::getStringConstantArray(Module &M, const std::string &string)
+{
+ std::vector<Constant*> elements;
+ elements.reserve(string.size() + 1);
+ for (unsigned i = 0; i < string.size(); ++i)
+ elements.push_back(ConstantInt::get(Type::getInt8Ty(M.getContext()), string[i]));
+
+ // Add a null terminator to the string...
+ elements.push_back(ConstantInt::get(Type::getInt8Ty(M.getContext()), 0));
+
+ ArrayType *ATy = ArrayType::get(Type::getInt8Ty(M.getContext()), elements.size());
+ return ConstantArray::get(ATy, elements);
+}
+
+inline GlobalVariable* PassUtil::getStringGlobalVariable(Module &M, const std::string &string, const std::string &varName, const std::string &varSection, Constant **getElementPtrExpr, bool cacheable)
+{
+ static std::map<std::string, GlobalVariable*> stringCache;
+ std::map<std::string, GlobalVariable*>::iterator stringCacheIt;
+ std::string stringCacheKey;
+ GlobalVariable *strGV = NULL;
+
+ if (cacheable) {
+ stringCacheKey = string + "~!~!" + varName + "~!~!" + varSection;
+ stringCacheIt = stringCache.find(stringCacheKey);
+ if (stringCacheIt != stringCache.end()) {
+ strGV = stringCacheIt->second;
+ cacheable = false;
+ }
+ }
+
+ if (!strGV) {
+ //create a constant internal string reference
+ Constant *stringValue = PassUtil::getStringConstantArray(M, string);
+
+ //create the global variable, cache it, and record it in the module
+ strGV = new GlobalVariable(M, stringValue->getType(), true,
+ GlobalValue::InternalLinkage, stringValue, varName);
+ if (varSection.compare("")) {
+ strGV->setSection(varSection);
+ }
+ }
+ if (getElementPtrExpr) {
+ std::vector<Value*> strConstantIndices;
+ strConstantIndices.push_back(ZERO_CONSTANT_INT(M));
+ strConstantIndices.push_back(ZERO_CONSTANT_INT(M));
+ *getElementPtrExpr = PassUtil::getGetElementPtrConstant(strGV, strConstantIndices);
+ }
+
+ if (cacheable) {
+ stringCache.insert(std::pair<std::string, GlobalVariable*>(stringCacheKey, strGV));
+ }
+
+ return strGV;
+}
+
+}
+
+#endif /* _PASS_HELLO_H */