llvm.org GIT mirror llvm / fcc3459
[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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@299695 91177308-0d34-0410-b5e6-96231b3b80d8 Evgeniy Stepanov 2 years ago
4 changed file(s) with 31 addition(s) and 23 deletion(s). Raw diff Collapse all Expand all
4545 // getOrInsertFunction returns a bitcast.
4646 Function *checkSanitizerInterfaceFunction(Constant *FuncOrBitcast);
4747
48 Function *declareSanitizerInitFunction(Module &M, StringRef InitName,
49 ArrayRef InitArgTypes);
50
4851 /// \brief Creates sanitizer constructor function, and calls sanitizer's init
4952 /// function from it.
5053 /// \return Returns pair of pointers to constructor, and init functions
575575 Type *IntptrTy;
576576 ShadowMapping Mapping;
577577 DominatorTree *DT;
578 Function *AsanCtorFunction = nullptr;
579 Function *AsanInitFunction = nullptr;
580578 Function *AsanHandleNoReturnFunc;
581579 Function *AsanPtrCmpFunction, *AsanPtrSubFunction;
582580 // This array is indexed by AccessIsWrite, Experiment and log2(AccessSize).
19351933 Mapping = getShadowMapping(TargetTriple, LongSize, CompileKernel);
19361934 initializeCallbacks(M);
19371935
1936 if (CompileKernel)
1937 return false;
1938
1939 Function *AsanCtorFunction;
1940 std::tie(AsanCtorFunction, std::ignore) = createSanitizerCtorAndInitFunctions(
1941 M, kAsanModuleCtorName, kAsanInitName, /*InitArgTypes=*/{},
1942 /*InitArgs=*/{}, kAsanVersionCheckName);
1943 appendToGlobalCtors(M, AsanCtorFunction, kAsanCtorAndDtorPriority);
1944
19381945 bool Changed = false;
1939
19401946 // TODO(glider): temporarily disabled globals instrumentation for KASan.
1941 if (ClGlobals && !CompileKernel) {
1942 Function *CtorFunc = M.getFunction(kAsanModuleCtorName);
1943 assert(CtorFunc);
1944 IRBuilder<> IRB(CtorFunc->getEntryBlock().getTerminator());
1947 if (ClGlobals) {
1948 IRBuilder<> IRB(AsanCtorFunction->getEntryBlock().getTerminator());
19451949 Changed |= InstrumentGlobals(IRB, M);
19461950 }
19471951
20102014 // virtual
20112015 bool AddressSanitizer::doInitialization(Module &M) {
20122016 // Initialize the private fields. No one has accessed them before.
2013
20142017 GlobalsMD.init(M);
20152018
20162019 C = &(M.getContext());
20182021 IntptrTy = Type::getIntNTy(*C, LongSize);
20192022 TargetTriple = Triple(M.getTargetTriple());
20202023
2021 if (!CompileKernel) {
2022 std::tie(AsanCtorFunction, AsanInitFunction) =
2023 createSanitizerCtorAndInitFunctions(
2024 M, kAsanModuleCtorName, kAsanInitName,
2025 /*InitArgTypes=*/{}, /*InitArgs=*/{}, kAsanVersionCheckName);
2026 appendToGlobalCtors(M, AsanCtorFunction, kAsanCtorAndDtorPriority);
2027 }
20282024 Mapping = getShadowMapping(TargetTriple, LongSize, CompileKernel);
20292025 return true;
20302026 }
20432039 // We cannot just ignore these methods, because they may call other
20442040 // instrumented functions.
20452041 if (F.getName().find(" load]") != std::string::npos) {
2042 Function *AsanInitFunction =
2043 declareSanitizerInitFunction(*F.getParent(), kAsanInitName, {});
20462044 IRBuilder<> IRB(&F.front(), F.front().begin());
20472045 IRB.CreateCall(AsanInitFunction, {});
20482046 return true;
20902088 }
20912089
20922090 bool AddressSanitizer::runOnFunction(Function &F) {
2093 if (&F == AsanCtorFunction) return false;
20942091 if (F.getLinkage() == GlobalValue::AvailableExternallyLinkage) return false;
20952092 if (!ClDebugFunc.empty() && ClDebugFunc == F.getName()) return false;
20962093 if (F.getName().startswith("__asan_")) return false;
137137 report_fatal_error(Err);
138138 }
139139
140 Function *llvm::declareSanitizerInitFunction(Module &M, StringRef InitName,
141 ArrayRef InitArgTypes) {
142 assert(!InitName.empty() && "Expected init function name");
143 Function *F = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
144 InitName,
145 FunctionType::get(Type::getVoidTy(M.getContext()), InitArgTypes, false),
146 AttributeList()));
147 F->setLinkage(Function::ExternalLinkage);
148 return F;
149 }
150
140151 std::pair llvm::createSanitizerCtorAndInitFunctions(
141152 Module &M, StringRef CtorName, StringRef InitName,
142153 ArrayRef InitArgTypes, ArrayRef InitArgs,
144155 assert(!InitName.empty() && "Expected init function name");
145156 assert(InitArgs.size() == InitArgTypes.size() &&
146157 "Sanitizer's init function expects different number of arguments");
158 Function *InitFunction =
159 declareSanitizerInitFunction(M, InitName, InitArgTypes);
147160 Function *Ctor = Function::Create(
148161 FunctionType::get(Type::getVoidTy(M.getContext()), false),
149162 GlobalValue::InternalLinkage, CtorName, &M);
150163 BasicBlock *CtorBB = BasicBlock::Create(M.getContext(), "", Ctor);
151164 IRBuilder<> IRB(ReturnInst::Create(M.getContext(), CtorBB));
152 Function *InitFunction =
153 checkSanitizerInterfaceFunction(M.getOrInsertFunction(
154 InitName, FunctionType::get(IRB.getVoidTy(), InitArgTypes, false),
155 AttributeList()));
156 InitFunction->setLinkage(Function::ExternalLinkage);
157165 IRB.CreateCall(InitFunction, InitArgs);
158166 if (!VersionCheckName.empty()) {
159167 Function *VersionCheckFunction =
1515 ; OPT1: IncrementMe
1616 ; OPT1: __asan_report_
1717 ; OPT1-NOT: __asan_report_
18 ; OPT1: asan.module_ctor
18 ; OPT1: ret void
1919
2020 ; Without optimizations we should see two calls to __asan_report_*
2121 ; OPT0: IncrementMe
2222 ; OPT0: __asan_report_
2323 ; OPT0: __asan_report_
24 ; OPT0: asan.module_ctor
24 ; OPT0: ret void