Index: llvm/trunk/include/llvm/Transforms/Utils/ModuleUtils.h =================================================================== --- llvm/trunk/include/llvm/Transforms/Utils/ModuleUtils.h +++ llvm/trunk/include/llvm/Transforms/Utils/ModuleUtils.h @@ -14,6 +14,9 @@ #ifndef LLVM_TRANSFORMS_UTILS_MODULEUTILS_H #define LLVM_TRANSFORMS_UTILS_MODULEUTILS_H +#include "llvm/ADT/ArrayRef.h" +#include // for std::pair + namespace llvm { class Module; @@ -21,6 +24,9 @@ class GlobalValue; class GlobalVariable; class Constant; +class StringRef; +class Value; +class Type; template class SmallPtrSetImpl; /// Append F to the list of global ctors of module M with the given Priority. @@ -43,6 +49,14 @@ // with the same name, their prototypes must match, otherwise // getOrInsertFunction returns a bitcast. Function *checkSanitizerInterfaceFunction(Constant *FuncOrBitcast); + +/// \brief Creates sanitizer constructor function, and calls sanitizer's init +/// function from it. +/// \return Returns pair of pointers to constructor, and init functions +/// respectively. +std::pair createSanitizerCtorAndInitFunctions( + Module &M, StringRef CtorName, StringRef InitName, + ArrayRef InitArgTypes, ArrayRef InitArgs); } // End llvm namespace #endif // LLVM_TRANSFORMS_UTILS_MODULEUTILS_H Index: llvm/trunk/lib/Transforms/Utils/ModuleUtils.cpp =================================================================== --- llvm/trunk/lib/Transforms/Utils/ModuleUtils.cpp +++ llvm/trunk/lib/Transforms/Utils/ModuleUtils.cpp @@ -104,3 +104,24 @@ Stream << "Sanitizer interface function redefined: " << *FuncOrBitcast; report_fatal_error(Err); } + +std::pair llvm::createSanitizerCtorAndInitFunctions( + Module &M, StringRef CtorName, StringRef InitName, + ArrayRef InitArgTypes, ArrayRef InitArgs) { + assert(!InitName.empty() && "Expected init function name"); + assert(InitArgTypes.size() == InitArgTypes.size() && + "Sanitizer's init function expects different number of arguments"); + Function *Ctor = Function::Create( + FunctionType::get(Type::getVoidTy(M.getContext()), false), + GlobalValue::InternalLinkage, CtorName, &M); + BasicBlock *CtorBB = BasicBlock::Create(M.getContext(), "", Ctor); + IRBuilder<> IRB(ReturnInst::Create(M.getContext(), CtorBB)); + Function *InitFunction = + checkSanitizerInterfaceFunction(M.getOrInsertFunction( + InitName, FunctionType::get(IRB.getVoidTy(), InitArgTypes, false), + AttributeSet())); + InitFunction->setLinkage(Function::ExternalLinkage); + IRB.CreateCall(InitFunction, InitArgs); + return std::make_pair(Ctor, InitFunction); +} +