Implement `createSanitizerCtor`, common helper function for all sanitizers
authorIsmail Pazarbasi <ismail.pazarbasi@gmail.com>
Wed, 6 May 2015 18:48:22 +0000 (18:48 +0000)
committerIsmail Pazarbasi <ismail.pazarbasi@gmail.com>
Wed, 6 May 2015 18:48:22 +0000 (18:48 +0000)
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

include/llvm/Transforms/Utils/ModuleUtils.h
lib/Transforms/Utils/ModuleUtils.cpp

index 907563ebe0b2a3f9ce14efc8efa8acbe222dda13..622265bae143b499d5250ba4cf2f0dab6bc6c52b 100644 (file)
@@ -14,6 +14,9 @@
 #ifndef LLVM_TRANSFORMS_UTILS_MODULEUTILS_H
 #define LLVM_TRANSFORMS_UTILS_MODULEUTILS_H
 
+#include "llvm/ADT/ArrayRef.h"
+#include <utility> // 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 PtrType> 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<Function *, Function *> createSanitizerCtorAndInitFunctions(
+    Module &M, StringRef CtorName, StringRef InitName,
+    ArrayRef<Type *> InitArgTypes, ArrayRef<Value *> InitArgs);
 } // End llvm namespace
 
 #endif //  LLVM_TRANSFORMS_UTILS_MODULEUTILS_H
index 014574d859d9fd30b7ea024bf32d0ed7ecf456ce..d69a81ec47415c651a2dfcdb0683f6afd7711828 100644 (file)
@@ -104,3 +104,24 @@ Function *llvm::checkSanitizerInterfaceFunction(Constant *FuncOrBitcast) {
   Stream << "Sanitizer interface function redefined: " << *FuncOrBitcast;
   report_fatal_error(Err);
 }
+
+std::pair<Function *, Function *> llvm::createSanitizerCtorAndInitFunctions(
+    Module &M, StringRef CtorName, StringRef InitName,
+    ArrayRef<Type *> InitArgTypes, ArrayRef<Value *> 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);
+}
+