@@ -815,11 +815,11 @@ class ModuleAddressSanitizer {
815815private:
816816 void initializeCallbacks (Module &M);
817817
818- bool InstrumentGlobals (IRBuilder<> &IRB, Module &M, bool *CtorComdat);
818+ void instrumentGlobals (IRBuilder<> &IRB, Module &M, bool *CtorComdat);
819819 void InstrumentGlobalsCOFF (IRBuilder<> &IRB, Module &M,
820820 ArrayRef<GlobalVariable *> ExtendedGlobals,
821821 ArrayRef<Constant *> MetadataInitializers);
822- void InstrumentGlobalsELF (IRBuilder<> &IRB, Module &M,
822+ void instrumentGlobalsELF (IRBuilder<> &IRB, Module &M,
823823 ArrayRef<GlobalVariable *> ExtendedGlobals,
824824 ArrayRef<Constant *> MetadataInitializers,
825825 const std::string &UniqueModuleId);
@@ -2175,7 +2175,7 @@ void ModuleAddressSanitizer::InstrumentGlobalsCOFF(
21752175 appendToCompilerUsed (M, MetadataGlobals);
21762176}
21772177
2178- void ModuleAddressSanitizer::InstrumentGlobalsELF (
2178+ void ModuleAddressSanitizer::instrumentGlobalsELF (
21792179 IRBuilder<> &IRB, Module &M, ArrayRef<GlobalVariable *> ExtendedGlobals,
21802180 ArrayRef<Constant *> MetadataInitializers,
21812181 const std::string &UniqueModuleId) {
@@ -2185,7 +2185,7 @@ void ModuleAddressSanitizer::InstrumentGlobalsELF(
21852185 // false negative odr violations at link time. If odr indicators are used, we
21862186 // keep the comdat sections, as link time odr violations will be dectected on
21872187 // the odr indicator symbols.
2188- bool UseComdatForGlobalsGC = UseOdrIndicator;
2188+ bool UseComdatForGlobalsGC = UseOdrIndicator && !UniqueModuleId. empty () ;
21892189
21902190 SmallVector<GlobalValue *, 16 > MetadataGlobals (ExtendedGlobals.size ());
21912191 for (size_t i = 0 ; i < ExtendedGlobals.size (); i++) {
@@ -2235,7 +2235,7 @@ void ModuleAddressSanitizer::InstrumentGlobalsELF(
22352235
22362236 // We also need to unregister globals at the end, e.g., when a shared library
22372237 // gets closed.
2238- if (DestructorKind != AsanDtorKind::None) {
2238+ if (DestructorKind != AsanDtorKind::None && !MetadataGlobals. empty () ) {
22392239 IRBuilder<> IrbDtor (CreateAsanModuleDtor (M));
22402240 IrbDtor.CreateCall (AsanUnregisterElfGlobals,
22412241 {IRB.CreatePointerCast (RegisteredFlag, IntptrTy),
@@ -2341,10 +2341,8 @@ void ModuleAddressSanitizer::InstrumentGlobalsWithMetadataArray(
23412341// redzones and inserts this function into llvm.global_ctors.
23422342// Sets *CtorComdat to true if the global registration code emitted into the
23432343// asan constructor is comdat-compatible.
2344- bool ModuleAddressSanitizer::InstrumentGlobals (IRBuilder<> &IRB, Module &M,
2344+ void ModuleAddressSanitizer::instrumentGlobals (IRBuilder<> &IRB, Module &M,
23452345 bool *CtorComdat) {
2346- *CtorComdat = false ;
2347-
23482346 // Build set of globals that are aliased by some GA, where
23492347 // getExcludedAliasedGlobal(GA) returns the relevant GlobalVariable.
23502348 SmallPtrSet<const GlobalVariable *, 16 > AliasedGlobalExclusions;
@@ -2362,11 +2360,6 @@ bool ModuleAddressSanitizer::InstrumentGlobals(IRBuilder<> &IRB, Module &M,
23622360 }
23632361
23642362 size_t n = GlobalsToChange.size ();
2365- if (n == 0 ) {
2366- *CtorComdat = true ;
2367- return false ;
2368- }
2369-
23702363 auto &DL = M.getDataLayout ();
23712364
23722365 // A global is described by a structure
@@ -2389,8 +2382,11 @@ bool ModuleAddressSanitizer::InstrumentGlobals(IRBuilder<> &IRB, Module &M,
23892382
23902383 // We shouldn't merge same module names, as this string serves as unique
23912384 // module ID in runtime.
2392- GlobalVariable *ModuleName = createPrivateGlobalForString (
2393- M, M.getModuleIdentifier (), /* AllowMerging*/ false , kAsanGenPrefix );
2385+ GlobalVariable *ModuleName =
2386+ n != 0
2387+ ? createPrivateGlobalForString (M, M.getModuleIdentifier (),
2388+ /* AllowMerging*/ false , kAsanGenPrefix )
2389+ : nullptr ;
23942390
23952391 for (size_t i = 0 ; i < n; i++) {
23962392 GlobalVariable *G = GlobalsToChange[i];
@@ -2515,27 +2511,34 @@ bool ModuleAddressSanitizer::InstrumentGlobals(IRBuilder<> &IRB, Module &M,
25152511 }
25162512 appendToCompilerUsed (M, ArrayRef<GlobalValue *>(GlobalsToAddToUsedList));
25172513
2518- std::string ELFUniqueModuleId =
2519- (UseGlobalsGC && TargetTriple.isOSBinFormatELF ()) ? getUniqueModuleId (&M)
2520- : " " ;
2521-
2522- if (!ELFUniqueModuleId.empty ()) {
2523- InstrumentGlobalsELF (IRB, M, NewGlobals, Initializers, ELFUniqueModuleId);
2514+ if (UseGlobalsGC && TargetTriple.isOSBinFormatELF ()) {
2515+ // Use COMDAT and register globals even if n == 0 to ensure that (a) the
2516+ // linkage unit will only have one module constructor, and (b) the register
2517+ // function will be called. The module destructor is not created when n ==
2518+ // 0.
25242519 *CtorComdat = true ;
2525- } else if (UseGlobalsGC && TargetTriple.isOSBinFormatCOFF ()) {
2526- InstrumentGlobalsCOFF (IRB, M, NewGlobals, Initializers);
2527- } else if (UseGlobalsGC && ShouldUseMachOGlobalsSection ()) {
2528- InstrumentGlobalsMachO (IRB, M, NewGlobals, Initializers);
2520+ instrumentGlobalsELF (IRB, M, NewGlobals, Initializers,
2521+ getUniqueModuleId (&M));
2522+ } else if (n == 0 ) {
2523+ // When UseGlobalsGC is false, COMDAT can still be used if n == 0, because
2524+ // all compile units will have identical module constructor/destructor.
2525+ *CtorComdat = TargetTriple.isOSBinFormatELF ();
25292526 } else {
2530- InstrumentGlobalsWithMetadataArray (IRB, M, NewGlobals, Initializers);
2527+ *CtorComdat = false ;
2528+ if (UseGlobalsGC && TargetTriple.isOSBinFormatCOFF ()) {
2529+ InstrumentGlobalsCOFF (IRB, M, NewGlobals, Initializers);
2530+ } else if (UseGlobalsGC && ShouldUseMachOGlobalsSection ()) {
2531+ InstrumentGlobalsMachO (IRB, M, NewGlobals, Initializers);
2532+ } else {
2533+ InstrumentGlobalsWithMetadataArray (IRB, M, NewGlobals, Initializers);
2534+ }
25312535 }
25322536
25332537 // Create calls for poisoning before initializers run and unpoisoning after.
25342538 if (HasDynamicallyInitializedGlobals)
25352539 createInitializerPoisonCalls (M, ModuleName);
25362540
25372541 LLVM_DEBUG (dbgs () << M);
2538- return true ;
25392542}
25402543
25412544uint64_t
@@ -2599,10 +2602,10 @@ bool ModuleAddressSanitizer::instrumentModule(Module &M) {
25992602 assert (AsanCtorFunction || ConstructorKind == AsanCtorKind::None);
26002603 if (AsanCtorFunction) {
26012604 IRBuilder<> IRB (AsanCtorFunction->getEntryBlock ().getTerminator ());
2602- InstrumentGlobals (IRB, M, &CtorComdat);
2605+ instrumentGlobals (IRB, M, &CtorComdat);
26032606 } else {
26042607 IRBuilder<> IRB (*C);
2605- InstrumentGlobals (IRB, M, &CtorComdat);
2608+ instrumentGlobals (IRB, M, &CtorComdat);
26062609 }
26072610 }
26082611
0 commit comments