Skip to content

Commit

Permalink
[asan] Delay creation of asan ctor.
Browse files Browse the repository at this point in the history
Create the constructor in the module pass.
This in needed for the GC-friendly globals change, where the constructor can be
put in a comdat  in some cases, but we don't know about that in the function
pass.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@298731 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
eugenis committed Mar 24, 2017
1 parent d4f6485 commit 3685331
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 23 deletions.
3 changes: 3 additions & 0 deletions include/llvm/Transforms/Utils/ModuleUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ void appendToGlobalDtors(Module &M, Function *F, int Priority,
// getOrInsertFunction returns a bitcast.
Function *checkSanitizerInterfaceFunction(Constant *FuncOrBitcast);

Function *declareSanitizerInitFunction(Module &M, StringRef InitName,
ArrayRef<Type *> InitArgTypes);

/// \brief Creates sanitizer constructor function, and calls sanitizer's init
/// function from it.
/// \return Returns pair of pointers to constructor, and init functions
Expand Down
29 changes: 13 additions & 16 deletions lib/Transforms/Instrumentation/AddressSanitizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -576,8 +576,6 @@ struct AddressSanitizer : public FunctionPass {
Type *IntptrTy;
ShadowMapping Mapping;
DominatorTree *DT;
Function *AsanCtorFunction = nullptr;
Function *AsanInitFunction = nullptr;
Function *AsanHandleNoReturnFunc;
Function *AsanPtrCmpFunction, *AsanPtrSubFunction;
// This array is indexed by AccessIsWrite, Experiment and log2(AccessSize).
Expand Down Expand Up @@ -1936,13 +1934,19 @@ bool AddressSanitizerModule::runOnModule(Module &M) {
Mapping = getShadowMapping(TargetTriple, LongSize, CompileKernel);
initializeCallbacks(M);

bool Changed = false;
if (CompileKernel)
return false;

Function *AsanCtorFunction;
std::tie(AsanCtorFunction, std::ignore) = createSanitizerCtorAndInitFunctions(
M, kAsanModuleCtorName, kAsanInitName, /*InitArgTypes=*/{},
/*InitArgs=*/{}, kAsanVersionCheckName);
appendToGlobalCtors(M, AsanCtorFunction, kAsanCtorAndDtorPriority);

bool Changed = false;
// TODO(glider): temporarily disabled globals instrumentation for KASan.
if (ClGlobals && !CompileKernel) {
Function *CtorFunc = M.getFunction(kAsanModuleCtorName);
assert(CtorFunc);
IRBuilder<> IRB(CtorFunc->getEntryBlock().getTerminator());
if (ClGlobals) {
IRBuilder<> IRB(AsanCtorFunction->getEntryBlock().getTerminator());
Changed |= InstrumentGlobals(IRB, M);
}

Expand Down Expand Up @@ -2011,21 +2015,13 @@ void AddressSanitizer::initializeCallbacks(Module &M) {
// virtual
bool AddressSanitizer::doInitialization(Module &M) {
// Initialize the private fields. No one has accessed them before.

GlobalsMD.init(M);

C = &(M.getContext());
LongSize = M.getDataLayout().getPointerSizeInBits();
IntptrTy = Type::getIntNTy(*C, LongSize);
TargetTriple = Triple(M.getTargetTriple());

if (!CompileKernel) {
std::tie(AsanCtorFunction, AsanInitFunction) =
createSanitizerCtorAndInitFunctions(
M, kAsanModuleCtorName, kAsanInitName,
/*InitArgTypes=*/{}, /*InitArgs=*/{}, kAsanVersionCheckName);
appendToGlobalCtors(M, AsanCtorFunction, kAsanCtorAndDtorPriority);
}
Mapping = getShadowMapping(TargetTriple, LongSize, CompileKernel);
return true;
}
Expand All @@ -2044,6 +2040,8 @@ bool AddressSanitizer::maybeInsertAsanInitAtFunctionEntry(Function &F) {
// We cannot just ignore these methods, because they may call other
// instrumented functions.
if (F.getName().find(" load]") != std::string::npos) {
Function *AsanInitFunction =
declareSanitizerInitFunction(*F.getParent(), kAsanInitName, {});
IRBuilder<> IRB(&F.front(), F.front().begin());
IRB.CreateCall(AsanInitFunction, {});
return true;
Expand Down Expand Up @@ -2091,7 +2089,6 @@ void AddressSanitizer::markEscapedLocalAllocas(Function &F) {
}

bool AddressSanitizer::runOnFunction(Function &F) {
if (&F == AsanCtorFunction) return false;
if (F.getLinkage() == GlobalValue::AvailableExternallyLinkage) return false;
if (!ClDebugFunc.empty() && ClDebugFunc == F.getName()) return false;
if (F.getName().startswith("__asan_")) return false;
Expand Down
18 changes: 13 additions & 5 deletions lib/Transforms/Utils/ModuleUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,23 +138,31 @@ Function *llvm::checkSanitizerInterfaceFunction(Constant *FuncOrBitcast) {
report_fatal_error(Err);
}

Function *llvm::declareSanitizerInitFunction(Module &M, StringRef InitName,
ArrayRef<Type *> InitArgTypes) {
assert(!InitName.empty() && "Expected init function name");
Function *F = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
InitName,
FunctionType::get(Type::getVoidTy(M.getContext()), InitArgTypes, false),
AttributeList()));
F->setLinkage(Function::ExternalLinkage);
return F;
}

std::pair<Function *, Function *> llvm::createSanitizerCtorAndInitFunctions(
Module &M, StringRef CtorName, StringRef InitName,
ArrayRef<Type *> InitArgTypes, ArrayRef<Value *> InitArgs,
StringRef VersionCheckName) {
assert(!InitName.empty() && "Expected init function name");
assert(InitArgs.size() == InitArgTypes.size() &&
"Sanitizer's init function expects different number of arguments");
Function *InitFunction =
declareSanitizerInitFunction(M, InitName, InitArgTypes);
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),
AttributeList()));
InitFunction->setLinkage(Function::ExternalLinkage);
IRB.CreateCall(InitFunction, InitArgs);
if (!VersionCheckName.empty()) {
Function *VersionCheckFunction =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ entry:
; OPT1: IncrementMe
; OPT1: __asan_report_
; OPT1-NOT: __asan_report_
; OPT1: asan.module_ctor
; OPT1: ret void

; Without optimizations we should see two calls to __asan_report_*
; OPT0: IncrementMe
; OPT0: __asan_report_
; OPT0: __asan_report_
; OPT0: asan.module_ctor
; OPT0: ret void

0 comments on commit 3685331

Please sign in to comment.