Index: include/llvm/Transforms/Utils/ModuleUtils.h =================================================================== --- include/llvm/Transforms/Utils/ModuleUtils.h +++ include/llvm/Transforms/Utils/ModuleUtils.h @@ -14,6 +14,8 @@ #ifndef LLVM_TRANSFORMS_UTILS_MODULEUTILS_H #define LLVM_TRANSFORMS_UTILS_MODULEUTILS_H +#include "llvm/ADT/ArrayRef.h" + namespace llvm { class Module; @@ -21,6 +23,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 +48,15 @@ // with the same name, their prototypes must match, otherwise // getOrInsertFunction returns a bitcast. Function *checkInterfaceFunction(Constant *FuncOrBitcast); + +/// \brief Creates sanitizer constructor function, and calls sanitizer's init +/// function from it. +Function *createSanitizerCtor(Module &M, StringRef CtorName, StringRef InitName, + ArrayRef InitType = ArrayRef(), + ArrayRef InitArgs = ArrayRef(), + Function **InitFunctionPtr = nullptr); +Function *createSanitizerCtor(Module &M, StringRef CtorName, StringRef InitName, + Function **InitFunctionPtr); } // End llvm namespace #endif // LLVM_TRANSFORMS_UTILS_MODULEUTILS_H Index: lib/Transforms/Utils/ModuleUtils.cpp =================================================================== --- lib/Transforms/Utils/ModuleUtils.cpp +++ lib/Transforms/Utils/ModuleUtils.cpp @@ -104,3 +104,32 @@ Stream << "Sanitizer interface function redefined: " << *FuncOrBitcast; report_fatal_error(Err); } + +Function *llvm::createSanitizerCtor(Module &M, llvm::StringRef CtorName, + llvm::StringRef InitName, + llvm::ArrayRef InitType, + llvm::ArrayRef InitArgs, + llvm::Function **InitFunctionPtr) { + assert(!InitName.empty() && "Expected init function name"); + 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 = checkInterfaceFunction(M.getOrInsertFunction( + InitName, FunctionType::get(IRB.getVoidTy(), InitType, false), + AttributeSet())); + InitFunction->setLinkage(Function::ExternalLinkage); + IRB.CreateCall(InitFunction, InitArgs); + if (InitFunctionPtr) + *InitFunctionPtr = InitFunction; + return Ctor; +} + +Function *llvm::createSanitizerCtor(Module &M, llvm::StringRef CtorName, + llvm::StringRef InitName, + llvm::Function **InitFunctionPtr) { + return llvm::createSanitizerCtor(M, CtorName, InitName, {}, {}, + InitFunctionPtr); +} +