@@ -101,6 +101,10 @@ static const char *const kAsanRegisterImageGlobalsName =
101
101
" __asan_register_image_globals" ;
102
102
static const char *const kAsanUnregisterImageGlobalsName =
103
103
" __asan_unregister_image_globals" ;
104
+ static const char *const kAsanRegisterElfGlobalsName =
105
+ " __asan_register_elf_globals" ;
106
+ static const char *const kAsanUnregisterElfGlobalsName =
107
+ " __asan_unregister_elf_globals" ;
104
108
static const char *const kAsanPoisonGlobalsName = " __asan_before_dynamic_init" ;
105
109
static const char *const kAsanUnpoisonGlobalsName = " __asan_after_dynamic_init" ;
106
110
static const char *const kAsanInitName = " __asan_init" ;
@@ -120,8 +124,11 @@ static const char *const kAsanPoisonStackMemoryName =
120
124
" __asan_poison_stack_memory" ;
121
125
static const char *const kAsanUnpoisonStackMemoryName =
122
126
" __asan_unpoison_stack_memory" ;
127
+
128
+ // ASan version script has __asan_* wildcard. Triple underscore prevents a
129
+ // linker (gold) warning about attempting to export a local symbol.
123
130
static const char *const kAsanGlobalsRegisteredFlagName =
124
- " __asan_globals_registered " ;
131
+ " ___asan_globals_registered " ;
125
132
126
133
static const char *const kAsanOptionDetectUseAfterReturn =
127
134
" __asan_option_detect_stack_use_after_return" ;
@@ -618,6 +625,10 @@ class AddressSanitizerModule : public ModulePass {
618
625
void InstrumentGlobalsCOFF (IRBuilder<> &IRB, Module &M,
619
626
ArrayRef<GlobalVariable *> ExtendedGlobals,
620
627
ArrayRef<Constant *> MetadataInitializers);
628
+ void InstrumentGlobalsELF (IRBuilder<> &IRB, Module &M,
629
+ ArrayRef<GlobalVariable *> ExtendedGlobals,
630
+ ArrayRef<Constant *> MetadataInitializers,
631
+ const std::string &UniqueModuleId);
621
632
void InstrumentGlobalsMachO (IRBuilder<> &IRB, Module &M,
622
633
ArrayRef<GlobalVariable *> ExtendedGlobals,
623
634
ArrayRef<Constant *> MetadataInitializers);
@@ -628,7 +639,8 @@ class AddressSanitizerModule : public ModulePass {
628
639
629
640
GlobalVariable *CreateMetadataGlobal (Module &M, Constant *Initializer,
630
641
StringRef OriginalName);
631
- void SetComdatForGlobalMetadata (GlobalVariable *G, GlobalVariable *Metadata);
642
+ void SetComdatForGlobalMetadata (GlobalVariable *G, GlobalVariable *Metadata,
643
+ StringRef InternalSuffix);
632
644
IRBuilder<> CreateAsanModuleDtor (Module &M);
633
645
634
646
bool ShouldInstrumentGlobal (GlobalVariable *G);
@@ -654,6 +666,8 @@ class AddressSanitizerModule : public ModulePass {
654
666
Function *AsanUnregisterGlobals;
655
667
Function *AsanRegisterImageGlobals;
656
668
Function *AsanUnregisterImageGlobals;
669
+ Function *AsanRegisterElfGlobals;
670
+ Function *AsanUnregisterElfGlobals;
657
671
658
672
Function *AsanCtorFunction = nullptr ;
659
673
Function *AsanDtorFunction = nullptr ;
@@ -1609,12 +1623,22 @@ void AddressSanitizerModule::initializeCallbacks(Module &M) {
1609
1623
checkSanitizerInterfaceFunction (M.getOrInsertFunction (
1610
1624
kAsanUnregisterImageGlobalsName , IRB.getVoidTy (), IntptrTy));
1611
1625
AsanUnregisterImageGlobals->setLinkage (Function::ExternalLinkage);
1626
+
1627
+ AsanRegisterElfGlobals = checkSanitizerInterfaceFunction (
1628
+ M.getOrInsertFunction (kAsanRegisterElfGlobalsName , IRB.getVoidTy (),
1629
+ IntptrTy, IntptrTy, IntptrTy));
1630
+ AsanRegisterElfGlobals->setLinkage (Function::ExternalLinkage);
1631
+
1632
+ AsanUnregisterElfGlobals = checkSanitizerInterfaceFunction (
1633
+ M.getOrInsertFunction (kAsanUnregisterElfGlobalsName , IRB.getVoidTy (),
1634
+ IntptrTy, IntptrTy, IntptrTy));
1635
+ AsanUnregisterElfGlobals->setLinkage (Function::ExternalLinkage);
1612
1636
}
1613
1637
1614
1638
// Put the metadata and the instrumented global in the same group. This ensures
1615
1639
// that the metadata is discarded if the instrumented global is discarded.
1616
1640
void AddressSanitizerModule::SetComdatForGlobalMetadata (
1617
- GlobalVariable *G, GlobalVariable *Metadata) {
1641
+ GlobalVariable *G, GlobalVariable *Metadata, StringRef InternalSuffix ) {
1618
1642
Module &M = *G->getParent ();
1619
1643
Comdat *C = G->getComdat ();
1620
1644
if (!C) {
@@ -1624,7 +1648,15 @@ void AddressSanitizerModule::SetComdatForGlobalMetadata(
1624
1648
assert (G->hasLocalLinkage ());
1625
1649
G->setName (Twine (kAsanGenPrefix ) + " _anon_global" );
1626
1650
}
1627
- C = M.getOrInsertComdat (G->getName ());
1651
+
1652
+ if (!InternalSuffix.empty () && G->hasLocalLinkage ()) {
1653
+ std::string Name = G->getName ();
1654
+ Name += InternalSuffix;
1655
+ C = M.getOrInsertComdat (Name);
1656
+ } else {
1657
+ C = M.getOrInsertComdat (G->getName ());
1658
+ }
1659
+
1628
1660
// Make this IMAGE_COMDAT_SELECT_NODUPLICATES on COFF.
1629
1661
if (TargetTriple.isOSBinFormatCOFF ())
1630
1662
C->setSelectionKind (Comdat::NoDuplicates);
@@ -1679,10 +1711,69 @@ void AddressSanitizerModule::InstrumentGlobalsCOFF(
1679
1711
" global metadata will not be padded appropriately" );
1680
1712
Metadata->setAlignment (SizeOfGlobalStruct);
1681
1713
1682
- SetComdatForGlobalMetadata (G, Metadata);
1714
+ SetComdatForGlobalMetadata (G, Metadata, " " );
1683
1715
}
1684
1716
}
1685
1717
1718
+ void AddressSanitizerModule::InstrumentGlobalsELF (
1719
+ IRBuilder<> &IRB, Module &M, ArrayRef<GlobalVariable *> ExtendedGlobals,
1720
+ ArrayRef<Constant *> MetadataInitializers,
1721
+ const std::string &UniqueModuleId) {
1722
+ assert (ExtendedGlobals.size () == MetadataInitializers.size ());
1723
+
1724
+ SmallVector<GlobalValue *, 16 > MetadataGlobals (ExtendedGlobals.size ());
1725
+ for (size_t i = 0 ; i < ExtendedGlobals.size (); i++) {
1726
+ GlobalVariable *G = ExtendedGlobals[i];
1727
+ GlobalVariable *Metadata =
1728
+ CreateMetadataGlobal (M, MetadataInitializers[i], G->getName ());
1729
+ MDNode *MD = MDNode::get (M.getContext (), ValueAsMetadata::get (G));
1730
+ Metadata->setMetadata (LLVMContext::MD_associated, MD);
1731
+ MetadataGlobals[i] = Metadata;
1732
+
1733
+ SetComdatForGlobalMetadata (G, Metadata, UniqueModuleId);
1734
+ }
1735
+
1736
+ // Update llvm.compiler.used, adding the new metadata globals. This is
1737
+ // needed so that during LTO these variables stay alive.
1738
+ if (!MetadataGlobals.empty ())
1739
+ appendToCompilerUsed (M, MetadataGlobals);
1740
+
1741
+ // RegisteredFlag serves two purposes. First, we can pass it to dladdr()
1742
+ // to look up the loaded image that contains it. Second, we can store in it
1743
+ // whether registration has already occurred, to prevent duplicate
1744
+ // registration.
1745
+ //
1746
+ // Common linkage ensures that there is only one global per shared library.
1747
+ GlobalVariable *RegisteredFlag = new GlobalVariable (
1748
+ M, IntptrTy, false , GlobalVariable::CommonLinkage,
1749
+ ConstantInt::get (IntptrTy, 0 ), kAsanGlobalsRegisteredFlagName );
1750
+ RegisteredFlag->setVisibility (GlobalVariable::HiddenVisibility);
1751
+
1752
+ // Create start and stop symbols.
1753
+ GlobalVariable *StartELFMetadata = new GlobalVariable (
1754
+ M, IntptrTy, false , GlobalVariable::ExternalWeakLinkage, nullptr ,
1755
+ " __start_" + getGlobalMetadataSection ());
1756
+ StartELFMetadata->setVisibility (GlobalVariable::HiddenVisibility);
1757
+ GlobalVariable *StopELFMetadata = new GlobalVariable (
1758
+ M, IntptrTy, false , GlobalVariable::ExternalWeakLinkage, nullptr ,
1759
+ " __stop_" + getGlobalMetadataSection ());
1760
+ StopELFMetadata->setVisibility (GlobalVariable::HiddenVisibility);
1761
+
1762
+ // Create a call to register the globals with the runtime.
1763
+ IRB.CreateCall (AsanRegisterElfGlobals,
1764
+ {IRB.CreatePointerCast (RegisteredFlag, IntptrTy),
1765
+ IRB.CreatePointerCast (StartELFMetadata, IntptrTy),
1766
+ IRB.CreatePointerCast (StopELFMetadata, IntptrTy)});
1767
+
1768
+ // We also need to unregister globals at the end, e.g., when a shared library
1769
+ // gets closed.
1770
+ IRBuilder<> IRB_Dtor = CreateAsanModuleDtor (M);
1771
+ IRB_Dtor.CreateCall (AsanUnregisterElfGlobals,
1772
+ {IRB.CreatePointerCast (RegisteredFlag, IntptrTy),
1773
+ IRB.CreatePointerCast (StartELFMetadata, IntptrTy),
1774
+ IRB.CreatePointerCast (StopELFMetadata, IntptrTy)});
1775
+ }
1776
+
1686
1777
void AddressSanitizerModule::InstrumentGlobalsMachO (
1687
1778
IRBuilder<> &IRB, Module &M, ArrayRef<GlobalVariable *> ExtendedGlobals,
1688
1779
ArrayRef<Constant *> MetadataInitializers) {
@@ -1931,7 +2022,14 @@ bool AddressSanitizerModule::InstrumentGlobals(IRBuilder<> &IRB, Module &M, bool
1931
2022
Initializers[i] = Initializer;
1932
2023
}
1933
2024
1934
- if (UseGlobalsGC && TargetTriple.isOSBinFormatCOFF ()) {
2025
+ std::string ELFUniqueModuleId =
2026
+ (UseGlobalsGC && TargetTriple.isOSBinFormatELF ()) ? getUniqueModuleId (&M)
2027
+ : " " ;
2028
+
2029
+ if (!ELFUniqueModuleId.empty ()) {
2030
+ InstrumentGlobalsELF (IRB, M, NewGlobals, Initializers, ELFUniqueModuleId);
2031
+ *CtorComdat = true ;
2032
+ } else if (UseGlobalsGC && TargetTriple.isOSBinFormatCOFF ()) {
1935
2033
InstrumentGlobalsCOFF (IRB, M, NewGlobals, Initializers);
1936
2034
} else if (UseGlobalsGC && ShouldUseMachOGlobalsSection ()) {
1937
2035
InstrumentGlobalsMachO (IRB, M, NewGlobals, Initializers);
0 commit comments