@@ -815,11 +815,11 @@ class ModuleAddressSanitizer {
815
815
private:
816
816
void initializeCallbacks (Module &M);
817
817
818
- bool InstrumentGlobals (IRBuilder<> &IRB, Module &M, bool *CtorComdat);
818
+ void instrumentGlobals (IRBuilder<> &IRB, Module &M, bool *CtorComdat);
819
819
void InstrumentGlobalsCOFF (IRBuilder<> &IRB, Module &M,
820
820
ArrayRef<GlobalVariable *> ExtendedGlobals,
821
821
ArrayRef<Constant *> MetadataInitializers);
822
- void InstrumentGlobalsELF (IRBuilder<> &IRB, Module &M,
822
+ void instrumentGlobalsELF (IRBuilder<> &IRB, Module &M,
823
823
ArrayRef<GlobalVariable *> ExtendedGlobals,
824
824
ArrayRef<Constant *> MetadataInitializers,
825
825
const std::string &UniqueModuleId);
@@ -2175,7 +2175,7 @@ void ModuleAddressSanitizer::InstrumentGlobalsCOFF(
2175
2175
appendToCompilerUsed (M, MetadataGlobals);
2176
2176
}
2177
2177
2178
- void ModuleAddressSanitizer::InstrumentGlobalsELF (
2178
+ void ModuleAddressSanitizer::instrumentGlobalsELF (
2179
2179
IRBuilder<> &IRB, Module &M, ArrayRef<GlobalVariable *> ExtendedGlobals,
2180
2180
ArrayRef<Constant *> MetadataInitializers,
2181
2181
const std::string &UniqueModuleId) {
@@ -2185,7 +2185,7 @@ void ModuleAddressSanitizer::InstrumentGlobalsELF(
2185
2185
// false negative odr violations at link time. If odr indicators are used, we
2186
2186
// keep the comdat sections, as link time odr violations will be dectected on
2187
2187
// the odr indicator symbols.
2188
- bool UseComdatForGlobalsGC = UseOdrIndicator;
2188
+ bool UseComdatForGlobalsGC = UseOdrIndicator && !UniqueModuleId. empty () ;
2189
2189
2190
2190
SmallVector<GlobalValue *, 16 > MetadataGlobals (ExtendedGlobals.size ());
2191
2191
for (size_t i = 0 ; i < ExtendedGlobals.size (); i++) {
@@ -2235,7 +2235,7 @@ void ModuleAddressSanitizer::InstrumentGlobalsELF(
2235
2235
2236
2236
// We also need to unregister globals at the end, e.g., when a shared library
2237
2237
// gets closed.
2238
- if (DestructorKind != AsanDtorKind::None) {
2238
+ if (DestructorKind != AsanDtorKind::None && !MetadataGlobals. empty () ) {
2239
2239
IRBuilder<> IrbDtor (CreateAsanModuleDtor (M));
2240
2240
IrbDtor.CreateCall (AsanUnregisterElfGlobals,
2241
2241
{IRB.CreatePointerCast (RegisteredFlag, IntptrTy),
@@ -2341,10 +2341,8 @@ void ModuleAddressSanitizer::InstrumentGlobalsWithMetadataArray(
2341
2341
// redzones and inserts this function into llvm.global_ctors.
2342
2342
// Sets *CtorComdat to true if the global registration code emitted into the
2343
2343
// asan constructor is comdat-compatible.
2344
- bool ModuleAddressSanitizer::InstrumentGlobals (IRBuilder<> &IRB, Module &M,
2344
+ void ModuleAddressSanitizer::instrumentGlobals (IRBuilder<> &IRB, Module &M,
2345
2345
bool *CtorComdat) {
2346
- *CtorComdat = false ;
2347
-
2348
2346
// Build set of globals that are aliased by some GA, where
2349
2347
// getExcludedAliasedGlobal(GA) returns the relevant GlobalVariable.
2350
2348
SmallPtrSet<const GlobalVariable *, 16 > AliasedGlobalExclusions;
@@ -2362,11 +2360,6 @@ bool ModuleAddressSanitizer::InstrumentGlobals(IRBuilder<> &IRB, Module &M,
2362
2360
}
2363
2361
2364
2362
size_t n = GlobalsToChange.size ();
2365
- if (n == 0 ) {
2366
- *CtorComdat = true ;
2367
- return false ;
2368
- }
2369
-
2370
2363
auto &DL = M.getDataLayout ();
2371
2364
2372
2365
// A global is described by a structure
@@ -2389,8 +2382,11 @@ bool ModuleAddressSanitizer::InstrumentGlobals(IRBuilder<> &IRB, Module &M,
2389
2382
2390
2383
// We shouldn't merge same module names, as this string serves as unique
2391
2384
// 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 ;
2394
2390
2395
2391
for (size_t i = 0 ; i < n; i++) {
2396
2392
GlobalVariable *G = GlobalsToChange[i];
@@ -2515,27 +2511,34 @@ bool ModuleAddressSanitizer::InstrumentGlobals(IRBuilder<> &IRB, Module &M,
2515
2511
}
2516
2512
appendToCompilerUsed (M, ArrayRef<GlobalValue *>(GlobalsToAddToUsedList));
2517
2513
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.
2524
2519
*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 ();
2529
2526
} 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
+ }
2531
2535
}
2532
2536
2533
2537
// Create calls for poisoning before initializers run and unpoisoning after.
2534
2538
if (HasDynamicallyInitializedGlobals)
2535
2539
createInitializerPoisonCalls (M, ModuleName);
2536
2540
2537
2541
LLVM_DEBUG (dbgs () << M);
2538
- return true ;
2539
2542
}
2540
2543
2541
2544
uint64_t
@@ -2599,10 +2602,10 @@ bool ModuleAddressSanitizer::instrumentModule(Module &M) {
2599
2602
assert (AsanCtorFunction || ConstructorKind == AsanCtorKind::None);
2600
2603
if (AsanCtorFunction) {
2601
2604
IRBuilder<> IRB (AsanCtorFunction->getEntryBlock ().getTerminator ());
2602
- InstrumentGlobals (IRB, M, &CtorComdat);
2605
+ instrumentGlobals (IRB, M, &CtorComdat);
2603
2606
} else {
2604
2607
IRBuilder<> IRB (*C);
2605
- InstrumentGlobals (IRB, M, &CtorComdat);
2608
+ instrumentGlobals (IRB, M, &CtorComdat);
2606
2609
}
2607
2610
}
2608
2611
0 commit comments