[esan] Add calls from the ctor/dtor to the runtime library
Summary:
Adds createEsanInitToolGV for creating a tool-specific variable passed
to the runtime library.
Adds dtor "esan.module_dtor" and inserts calls from the dtor to
"__esan_exit" in the runtime library.
Updates the EfficiencySanitizer test.
Patch by Qin Zhao.
Reviewers: aizatsky
Subscribers: bruening, kcc, vitalybuka, eugenis, llvm-commits
Differential Revision: http://reviews.llvm.org/D20488
llvm-svn: 270627
diff --git a/llvm/lib/Transforms/Instrumentation/EfficiencySanitizer.cpp b/llvm/lib/Transforms/Instrumentation/EfficiencySanitizer.cpp
index 8feadd2..6c47960 100644
--- a/llvm/lib/Transforms/Instrumentation/EfficiencySanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/EfficiencySanitizer.cpp
@@ -59,8 +59,11 @@
STATISTIC(NumAccessesWithIrregularSize,
"Number of accesses with a size outside our targeted callout sizes");
+static const uint64_t EsanCtorAndDtorPriority = 0;
static const char *const EsanModuleCtorName = "esan.module_ctor";
+static const char *const EsanModuleDtorName = "esan.module_dtor";
static const char *const EsanInitName = "__esan_init";
+static const char *const EsanExitName = "__esan_exit";
namespace {
@@ -90,6 +93,8 @@
private:
bool initOnModule(Module &M);
void initializeCallbacks(Module &M);
+ GlobalVariable *createEsanInitToolGV(Module &M);
+ void createDestructor(Module &M, GlobalVariable *GV);
bool runOnFunction(Function &F, Module &M);
bool instrumentLoadOrStore(Instruction *I, const DataLayout &DL);
bool instrumentMemIntrinsic(MemIntrinsic *MI);
@@ -115,6 +120,7 @@
Function *EsanUnalignedLoadN, *EsanUnalignedStoreN;
Function *MemmoveFn, *MemcpyFn, *MemsetFn;
Function *EsanCtorFunction;
+ Function *EsanDtorFunction;
};
} // namespace
@@ -173,19 +179,50 @@
IRB.getInt32Ty(), IntptrTy, nullptr));
}
+// Create the tool-specific global variable passed to EsanInit and EsanExit.
+GlobalVariable *EfficiencySanitizer::createEsanInitToolGV(Module &M) {
+ GlobalVariable *GV = nullptr;
+ // FIXME: create the tool specific global variable.
+ if (GV == nullptr) {
+ GV = new GlobalVariable(M, IntptrTy, true, GlobalVariable::InternalLinkage,
+ Constant::getNullValue(IntptrTy));
+ }
+ return GV;
+}
+
+void EfficiencySanitizer::createDestructor(Module &M, GlobalVariable *GV) {
+ EsanDtorFunction = Function::Create(FunctionType::get(Type::getVoidTy(*Ctx),
+ false),
+ GlobalValue::InternalLinkage,
+ EsanModuleDtorName, &M);
+ ReturnInst::Create(*Ctx, BasicBlock::Create(*Ctx, "", EsanDtorFunction));
+ IRBuilder<> IRB_Dtor(EsanDtorFunction->getEntryBlock().getTerminator());
+ Function *EsanExit = checkSanitizerInterfaceFunction(
+ M.getOrInsertFunction(EsanExitName, IRB_Dtor.getVoidTy(),
+ IntptrTy, nullptr));
+ EsanExit->setLinkage(Function::ExternalLinkage);
+ IRB_Dtor.CreateCall(EsanExit,
+ {IRB_Dtor.CreatePointerCast(GV, IntptrTy)});
+ appendToGlobalDtors(M, EsanDtorFunction, EsanCtorAndDtorPriority);
+}
+
bool EfficiencySanitizer::initOnModule(Module &M) {
Ctx = &M.getContext();
const DataLayout &DL = M.getDataLayout();
IRBuilder<> IRB(M.getContext());
IntegerType *OrdTy = IRB.getInt32Ty();
IntptrTy = DL.getIntPtrType(M.getContext());
+ // Create the variable passed to EsanInit and EsanExit.
+ GlobalVariable *GV = createEsanInitToolGV(M);
+ // Constructor
std::tie(EsanCtorFunction, std::ignore) = createSanitizerCtorAndInitFunctions(
- M, EsanModuleCtorName, EsanInitName, /*InitArgTypes=*/{OrdTy},
+ M, EsanModuleCtorName, EsanInitName, /*InitArgTypes=*/{OrdTy, IntptrTy},
/*InitArgs=*/{
- ConstantInt::get(OrdTy, static_cast<int>(Options.ToolType))});
+ ConstantInt::get(OrdTy, static_cast<int>(Options.ToolType)),
+ ConstantExpr::getPointerCast(GV, IntptrTy)});
+ appendToGlobalCtors(M, EsanCtorFunction, EsanCtorAndDtorPriority);
- appendToGlobalCtors(M, EsanCtorFunction, 0);
-
+ createDestructor(M, GV);
return true;
}
@@ -216,7 +253,7 @@
SmallVector<Instruction *, 8> LoadsAndStores;
SmallVector<Instruction *, 8> MemIntrinCalls;
bool Res = false;
- const DataLayout &DL = F.getParent()->getDataLayout();
+ const DataLayout &DL = M.getDataLayout();
for (auto &BB : F) {
for (auto &Inst : BB) {