llvm.org GIT mirror llvm / d3ffac8
Revert r298158. Revert "[asan] Fix dead stripping of globals on Linux." OOM in gold linker. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@298288 91177308-0d34-0410-b5e6-96231b3b80d8 Evgeniy Stepanov 2 years ago
7 changed file(s) with 58 addition(s) and 163 deletion(s). Raw diff Collapse all Expand all
8080 void filterDeadComdatFunctions(
8181 Module &M, SmallVectorImpl &DeadComdatFunctions);
8282
83 /// \brief Produce a unique identifier for this module by taking the MD5 sum of
84 /// the names of the module's strong external symbols.
85 ///
86 /// This identifier is normally guaranteed to be unique, or the program would
87 /// fail to link due to multiply defined symbols.
88 ///
89 /// If the module has no strong external symbols (such a module may still have a
90 /// semantic effect if it performs global initialization), we cannot produce a
91 /// unique identifier for this module, so we return the empty string.
92 std::string getUniqueModuleId(Module *M);
93
9483 } // End llvm namespace
9584
9685 #endif // LLVM_TRANSFORMS_UTILS_MODULEUTILS_H
2727 #include "llvm/Support/ScopedPrinter.h"
2828 #include "llvm/Transforms/IPO/FunctionAttrs.h"
2929 #include "llvm/Transforms/Utils/Cloning.h"
30 #include "llvm/Transforms/Utils/ModuleUtils.h"
3130 using namespace llvm;
3231
3332 namespace {
33
34 // Produce a unique identifier for this module by taking the MD5 sum of the
35 // names of the module's strong external symbols. This identifier is
36 // normally guaranteed to be unique, or the program would fail to link due to
37 // multiply defined symbols.
38 //
39 // If the module has no strong external symbols (such a module may still have a
40 // semantic effect if it performs global initialization), we cannot produce a
41 // unique identifier for this module, so we return the empty string, which
42 // causes the entire module to be written as a regular LTO module.
43 std::string getModuleId(Module *M) {
44 MD5 Md5;
45 bool ExportsSymbols = false;
46 auto AddGlobal = [&](GlobalValue &GV) {
47 if (GV.isDeclaration() || GV.getName().startswith("llvm.") ||
48 !GV.hasExternalLinkage())
49 return;
50 ExportsSymbols = true;
51 Md5.update(GV.getName());
52 Md5.update(ArrayRef{0});
53 };
54
55 for (auto &F : *M)
56 AddGlobal(F);
57 for (auto &GV : M->globals())
58 AddGlobal(GV);
59 for (auto &GA : M->aliases())
60 AddGlobal(GA);
61 for (auto &IF : M->ifuncs())
62 AddGlobal(IF);
63
64 if (!ExportsSymbols)
65 return "";
66
67 MD5::MD5Result R;
68 Md5.final(R);
69
70 SmallString<32> Str;
71 MD5::stringifyResult(R, Str);
72 return ("$" + Str).str();
73 }
3474
3575 // Promote each local-linkage entity defined by ExportM and used by ImportM by
3676 // changing visibility and appending the given ModuleId.
212252 void splitAndWriteThinLTOBitcode(
213253 raw_ostream &OS, function_ref AARGetter,
214254 Module &M) {
215 std::string ModuleId = getUniqueModuleId(&M);
255 std::string ModuleId = getModuleId(&M);
216256 if (ModuleId.empty()) {
217257 // We couldn't generate a module ID for this module, just write it out as a
218258 // regular LTO module.
100100 "__asan_register_image_globals";
101101 static const char *const kAsanUnregisterImageGlobalsName =
102102 "__asan_unregister_image_globals";
103 static const char *const kAsanRegisterElfGlobalsName =
104 "__asan_register_elf_globals";
105 static const char *const kAsanUnregisterElfGlobalsName =
106 "__asan_unregister_elf_globals";
107103 static const char *const kAsanPoisonGlobalsName = "__asan_before_dynamic_init";
108104 static const char *const kAsanUnpoisonGlobalsName = "__asan_after_dynamic_init";
109105 static const char *const kAsanInitName = "__asan_init";
123119 "__asan_poison_stack_memory";
124120 static const char *const kAsanUnpoisonStackMemoryName =
125121 "__asan_unpoison_stack_memory";
126
127 // ASan version script has __asan_* wildcard. Triple underscore prevents a
128 // linker (gold) warning about attempting to export a local symbol.
129122 static const char *const kAsanGlobalsRegisteredFlagName =
130 "___asan_globals_registered";
123 "__asan_globals_registered";
131124
132125 static const char *const kAsanOptionDetectUseAfterReturn =
133126 "__asan_option_detect_stack_use_after_return";
618611 void InstrumentGlobalsCOFF(IRBuilder<> &IRB, Module &M,
619612 ArrayRef ExtendedGlobals,
620613 ArrayRef MetadataInitializers);
621 void InstrumentGlobalsELF(IRBuilder<> &IRB, Module &M,
622 ArrayRef ExtendedGlobals,
623 ArrayRef MetadataInitializers,
624 const std::string &UniqueModuleId);
625614 void InstrumentGlobalsMachO(IRBuilder<> &IRB, Module &M,
626615 ArrayRef ExtendedGlobals,
627616 ArrayRef MetadataInitializers);
632621
633622 GlobalVariable *CreateMetadataGlobal(Module &M, Constant *Initializer,
634623 StringRef OriginalName);
635 void SetComdatForGlobalMetadata(GlobalVariable *G, GlobalVariable *Metadata,
636 StringRef InternalSuffix);
624 void SetComdatForGlobalMetadata(GlobalVariable *G, GlobalVariable *Metadata);
637625 IRBuilder<> CreateAsanModuleDtor(Module &M);
638626
639627 bool ShouldInstrumentGlobal(GlobalVariable *G);
658646 Function *AsanUnregisterGlobals;
659647 Function *AsanRegisterImageGlobals;
660648 Function *AsanUnregisterImageGlobals;
661 Function *AsanRegisterElfGlobals;
662 Function *AsanUnregisterElfGlobals;
663649 };
664650
665651 // Stack poisoning does not play well with exception handling.
16091595 checkSanitizerInterfaceFunction(M.getOrInsertFunction(
16101596 kAsanUnregisterImageGlobalsName, IRB.getVoidTy(), IntptrTy, nullptr));
16111597 AsanUnregisterImageGlobals->setLinkage(Function::ExternalLinkage);
1612
1613 AsanRegisterElfGlobals = checkSanitizerInterfaceFunction(
1614 M.getOrInsertFunction(kAsanRegisterElfGlobalsName, IRB.getVoidTy(),
1615 IntptrTy, IntptrTy, IntptrTy, nullptr));
1616 AsanRegisterElfGlobals->setLinkage(Function::ExternalLinkage);
1617
1618 AsanUnregisterElfGlobals = checkSanitizerInterfaceFunction(
1619 M.getOrInsertFunction(kAsanUnregisterElfGlobalsName, IRB.getVoidTy(),
1620 IntptrTy, IntptrTy, IntptrTy, nullptr));
1621 AsanUnregisterElfGlobals->setLinkage(Function::ExternalLinkage);
16221598 }
16231599
16241600 // Put the metadata and the instrumented global in the same group. This ensures
16251601 // that the metadata is discarded if the instrumented global is discarded.
16261602 void AddressSanitizerModule::SetComdatForGlobalMetadata(
1627 GlobalVariable *G, GlobalVariable *Metadata, StringRef InternalSuffix) {
1603 GlobalVariable *G, GlobalVariable *Metadata) {
16281604 Module &M = *G->getParent();
16291605 Comdat *C = G->getComdat();
16301606 if (!C) {
16341610 assert(G->hasLocalLinkage());
16351611 G->setName(Twine(kAsanGenPrefix) + "_anon_global");
16361612 }
1637
1638 if (!InternalSuffix.empty() && G->hasLocalLinkage()) {
1639 std::string Name = G->getName();
1640 Name += InternalSuffix;
1641 C = M.getOrInsertComdat(Name);
1642 } else {
1643 C = M.getOrInsertComdat(G->getName());
1644 }
1645
1613 C = M.getOrInsertComdat(G->getName());
16461614 // Make this IMAGE_COMDAT_SELECT_NODUPLICATES on COFF.
16471615 if (TargetTriple.isOSBinFormatCOFF())
16481616 C->setSelectionKind(Comdat::NoDuplicates);
16971665 "global metadata will not be padded appropriately");
16981666 Metadata->setAlignment(SizeOfGlobalStruct);
16991667
1700 SetComdatForGlobalMetadata(G, Metadata, "");
1701 }
1702 }
1703
1704 void AddressSanitizerModule::InstrumentGlobalsELF(
1705 IRBuilder<> &IRB, Module &M, ArrayRef ExtendedGlobals,
1706 ArrayRef MetadataInitializers,
1707 const std::string &UniqueModuleId) {
1708 assert(ExtendedGlobals.size() == MetadataInitializers.size());
1709
1710 SmallVector MetadataGlobals(ExtendedGlobals.size());
1711 for (size_t i = 0; i < ExtendedGlobals.size(); i++) {
1712 GlobalVariable *G = ExtendedGlobals[i];
1713 GlobalVariable *Metadata =
1714 CreateMetadataGlobal(M, MetadataInitializers[i], G->getName());
1715 MDNode *MD = MDNode::get(M.getContext(), ValueAsMetadata::get(G));
1716 Metadata->setMetadata(LLVMContext::MD_associated, MD);
1717 MetadataGlobals[i] = Metadata;
1718
1719 SetComdatForGlobalMetadata(G, Metadata, UniqueModuleId);
1720 }
1721
1722 // Update llvm.compiler.used, adding the new metadata globals. This is
1723 // needed so that during LTO these variables stay alive.
1724 if (!MetadataGlobals.empty())
1725 appendToCompilerUsed(M, MetadataGlobals);
1726
1727 // RegisteredFlag serves two purposes. First, we can pass it to dladdr()
1728 // to look up the loaded image that contains it. Second, we can store in it
1729 // whether registration has already occurred, to prevent duplicate
1730 // registration.
1731 //
1732 // Common linkage ensures that there is only one global per shared library.
1733 GlobalVariable *RegisteredFlag = new GlobalVariable(
1734 M, IntptrTy, false, GlobalVariable::CommonLinkage,
1735 ConstantInt::get(IntptrTy, 0), kAsanGlobalsRegisteredFlagName);
1736 RegisteredFlag->setVisibility(GlobalVariable::HiddenVisibility);
1737
1738 // Create start and stop symbols.
1739 GlobalVariable *StartELFMetadata = new GlobalVariable(
1740 M, IntptrTy, false, GlobalVariable::ExternalWeakLinkage, nullptr,
1741 "__start_" + getGlobalMetadataSection());
1742 StartELFMetadata->setVisibility(GlobalVariable::HiddenVisibility);
1743 GlobalVariable *StopELFMetadata = new GlobalVariable(
1744 M, IntptrTy, false, GlobalVariable::ExternalWeakLinkage, nullptr,
1745 "__stop_" + getGlobalMetadataSection());
1746 StopELFMetadata->setVisibility(GlobalVariable::HiddenVisibility);
1747
1748 // Create a call to register the globals with the runtime.
1749 IRB.CreateCall(AsanRegisterElfGlobals,
1750 {IRB.CreatePointerCast(RegisteredFlag, IntptrTy),
1751 IRB.CreatePointerCast(StartELFMetadata, IntptrTy),
1752 IRB.CreatePointerCast(StopELFMetadata, IntptrTy)});
1753
1754 // We also need to unregister globals at the end, e.g., when a shared library
1755 // gets closed.
1756 IRBuilder<> IRB_Dtor = CreateAsanModuleDtor(M);
1757 IRB_Dtor.CreateCall(AsanUnregisterElfGlobals,
1758 {IRB.CreatePointerCast(RegisteredFlag, IntptrTy),
1759 IRB.CreatePointerCast(StartELFMetadata, IntptrTy),
1760 IRB.CreatePointerCast(StopELFMetadata, IntptrTy)});
1668 SetComdatForGlobalMetadata(G, Metadata);
1669 }
17611670 }
17621671
17631672 void AddressSanitizerModule::InstrumentGlobalsMachO(
20021911 Initializers[i] = Initializer;
20031912 }
20041913
2005 std::string ELFUniqueModuleId =
2006 TargetTriple.isOSBinFormatELF() ? getUniqueModuleId(&M) : "";
2007
2008 if (!ELFUniqueModuleId.empty()) {
2009 InstrumentGlobalsELF(IRB, M, NewGlobals, Initializers, ELFUniqueModuleId);
2010 } else if (TargetTriple.isOSBinFormatCOFF()) {
1914 if (TargetTriple.isOSBinFormatCOFF()) {
20111915 InstrumentGlobalsCOFF(IRB, M, NewGlobals, Initializers);
20121916 } else if (ShouldUseMachOGlobalsSection()) {
20131917 InstrumentGlobalsMachO(IRB, M, NewGlobals, Initializers);
228228 ComdatEntriesCovered.end();
229229 });
230230 }
231
232 std::string llvm::getUniqueModuleId(Module *M) {
233 MD5 Md5;
234 bool ExportsSymbols = false;
235 auto AddGlobal = [&](GlobalValue &GV) {
236 if (GV.isDeclaration() || GV.getName().startswith("llvm.") ||
237 !GV.hasExternalLinkage())
238 return;
239 ExportsSymbols = true;
240 Md5.update(GV.getName());
241 Md5.update(ArrayRef{0});
242 };
243
244 for (auto &F : *M)
245 AddGlobal(F);
246 for (auto &GV : M->globals())
247 AddGlobal(GV);
248 for (auto &GA : M->aliases())
249 AddGlobal(GA);
250 for (auto &IF : M->ifuncs())
251 AddGlobal(IF);
252
253 if (!ExportsSymbols)
254 return "";
255
256 MD5::MD5Result R;
257 Md5.final(R);
258
259 SmallString<32> Str;
260 MD5::stringifyResult(R, Str);
261 return ("$" + Str).str();
262 }
1111 @llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @_GLOBAL__sub_I_asan_globals.cpp, i8* null }]
1212
1313 ; Check that globals were instrumented:
14
15 ; CHECK: @global = global { i32, [60 x i8] } zeroinitializer, comdat, align 32
16 ; CHECK: @.str = internal unnamed_addr constant { [14 x i8], [50 x i8] } { [14 x i8] c"Hello, world!\00", [50 x i8] zeroinitializer }, comdat($".str${{[01-9a-f]+}}"), align 32
14 ; CHECK: @global = global { i32, [60 x i8] } zeroinitializer, align 32
15 ; CHECK: @.str = internal unnamed_addr constant { [14 x i8], [50 x i8] } { [14 x i8] c"Hello, world!\00", [50 x i8] zeroinitializer }, align 32
1716
1817 ; Check emitted location descriptions:
1918 ; CHECK: [[VARNAME:@__asan_gen_.[0-9]+]] = private unnamed_addr constant [7 x i8] c"global\00", align 1
2019 ; CHECK: [[FILENAME:@__asan_gen_.[0-9]+]] = private unnamed_addr constant [22 x i8] c"/tmp/asan-globals.cpp\00", align 1
2120 ; CHECK: [[LOCDESCR:@__asan_gen_.[0-9]+]] = private unnamed_addr constant { [22 x i8]*, i32, i32 } { [22 x i8]* [[FILENAME]], i32 5, i32 5 }
22 ; CHECK: @__asan_global_global = {{.*}}i64 ptrtoint ({ i32, [60 x i8] }* @global to i64){{.*}} section "asan_globals"{{.*}}, !associated
23 ; CHECK: @__asan_global_.str = {{.*}}i64 ptrtoint ({ [14 x i8], [50 x i8] }* @.str to i64){{.*}} section "asan_globals"{{.*}}, !associated
24
25 ; The metadata has to be inserted to llvm.compiler.used to avoid being stripped
26 ; during LTO.
27 ; CHECK: @llvm.compiler.used {{.*}} @__asan_global_global {{.*}} section "llvm.metadata"
2821
2922 ; Check that location descriptors and global names were passed into __asan_register_globals:
30 ; CHECK: call void @__asan_register_elf_globals(i64 ptrtoint (i64* @___asan_globals_registered to i64), i64 ptrtoint (i64* @__start_asan_globals to i64), i64 ptrtoint (i64* @__stop_asan_globals to i64))
23 ; CHECK: i64 ptrtoint ([7 x i8]* [[VARNAME]] to i64)
24 ; CHECK: i64 ptrtoint ({ [22 x i8]*, i32, i32 }* [[LOCDESCR]] to i64)
3125
3226 ; Function Attrs: nounwind sanitize_address
3327 define internal void @__cxx_global_var_init() #0 section ".text.startup" {
2525 ; CHECK: @llvm.compiler.used {{.*}} @__asan_binder_global {{.*}} section "llvm.metadata"
2626
2727 ; Test that there is the flag global variable:
28 ; CHECK: @___asan_globals_registered = common hidden global i64 0
28 ; CHECK: @__asan_globals_registered = common hidden global i64 0
2929
3030 ; Test that __asan_register_image_globals is invoked from the constructor:
3131 ; CHECK-LABEL: define internal void @asan.module_ctor
3232 ; CHECK-NOT: ret
33 ; CHECK: call void @__asan_register_image_globals(i64 ptrtoint (i64* @___asan_globals_registered to i64))
33 ; CHECK: call void @__asan_register_image_globals(i64 ptrtoint (i64* @__asan_globals_registered to i64))
3434 ; CHECK: ret
3535
3636 ; Test that __asan_unregister_image_globals is invoked from the destructor:
3737 ; CHECK-LABEL: define internal void @asan.module_dtor
3838 ; CHECK-NOT: ret
39 ; CHECK: call void @__asan_unregister_image_globals(i64 ptrtoint (i64* @___asan_globals_registered to i64))
39 ; CHECK: call void @__asan_unregister_image_globals(i64 ptrtoint (i64* @__asan_globals_registered to i64))
4040 ; CHECK: ret
7272
7373 ; CHECK-LABEL: define internal void @asan.module_ctor
7474 ; CHECK-NOT: ret
75 ; CHECK: call void @__asan_register_elf_globals
75 ; CHECK: call void @__asan_register_globals
7676 ; CHECK: ret
7777
7878 ; CHECK-LABEL: define internal void @asan.module_dtor
7979 ; CHECK-NOT: ret
80 ; CHECK: call void @__asan_unregister_elf_globals
80 ; CHECK: call void @__asan_unregister_globals
8181 ; CHECK: ret