mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-03-07 11:59:09 +00:00
[asan] Delay creation of asan ctor.
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. This is a rebase of r298731 which was reverted due to a false alarm. llvm-svn: 299695
This commit is contained in:
parent
e6e54f54df
commit
2fb6fb7026
@ -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
|
||||
|
@ -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).
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -2011,7 +2015,6 @@ 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());
|
||||
@ -2019,13 +2022,6 @@ bool AddressSanitizer::doInitialization(Module &M) {
|
||||
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;
|
||||
}
|
||||
@ -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;
|
||||
@ -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;
|
||||
|
@ -138,6 +138,17 @@ 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,
|
||||
@ -145,16 +156,13 @@ std::pair<Function *, Function *> llvm::createSanitizerCtorAndInitFunctions(
|
||||
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 =
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user