From: Ismail Pazarbasi Date: Wed, 6 May 2015 18:48:22 +0000 (+0000) Subject: Implement `createSanitizerCtor`, common helper function for all sanitizers X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=4e21d7aff9187de570062ae6e58f42205466b93b;p=oota-llvm.git Implement `createSanitizerCtor`, common helper function for all sanitizers Summary: This helper function creates a ctor function, which calls sanitizer's init function with given arguments. This constructor is then expected to be added to module's ctors. The patch helps unifying how sanitizer constructor functions are created, and how init functions are called across all sanitizers. Reviewers: kcc, samsonov Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D8777 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@236627 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/Transforms/Utils/ModuleUtils.h b/include/llvm/Transforms/Utils/ModuleUtils.h index 907563ebe0b..622265bae14 100644 --- a/include/llvm/Transforms/Utils/ModuleUtils.h +++ b/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 Function; 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 @@ GlobalVariable *collectUsedGlobalVariables(Module &M, // 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 diff --git a/lib/Transforms/Utils/ModuleUtils.cpp b/lib/Transforms/Utils/ModuleUtils.cpp index 014574d859d..d69a81ec474 100644 --- a/lib/Transforms/Utils/ModuleUtils.cpp +++ b/lib/Transforms/Utils/ModuleUtils.cpp @@ -104,3 +104,24 @@ Function *llvm::checkSanitizerInterfaceFunction(Constant *FuncOrBitcast) { 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); +} +