Skip to content

Commit 7ccc7f7

Browse files
author
git apple-llvm automerger
committed
Merge commit '888437e1b600' from llvm.org/release/17.x into stable/20230725
2 parents aac9d90 + 35d6b2e commit 7ccc7f7

File tree

4 files changed

+97
-36
lines changed

4 files changed

+97
-36
lines changed

llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp

Lines changed: 32 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -815,11 +815,11 @@ class ModuleAddressSanitizer {
815815
private:
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

25412544
uint64_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

llvm/test/Instrumentation/AddressSanitizer/basic.ll

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,8 +210,10 @@ define void @test_swifterror_3() sanitize_address {
210210

211211
;; ctor/dtor have the nounwind attribute. See uwtable.ll, they additionally have
212212
;; the uwtable attribute with the module flag "uwtable".
213-
; CHECK: define internal void @asan.module_ctor() #[[#ATTR:]] {{(comdat )?}}{
213+
; CHECK: define internal void @asan.module_ctor() #[[#ATTR:]] comdat {
214214
; CHECK: call void @__asan_init()
215+
;; __asan_register_elf_globals is called even if this module does not contain instrumented global variables.
216+
; CHECK: call void @__asan_register_elf_globals(i64 ptrtoint (ptr @___asan_globals_registered to i64), i64 ptrtoint (ptr @__start_asan_globals to i64), i64 ptrtoint (ptr @__stop_asan_globals to i64))
215217

216218
; CHECK: attributes #[[#ATTR]] = { nounwind }
217219

llvm/test/Instrumentation/AddressSanitizer/global_metadata_array.ll

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
1-
; RUN: opt < %s -passes=asan -asan-globals-live-support=0 -mtriple=x86_64-unknown-linux-gnu -S | FileCheck --check-prefix=CHECK %s
2-
; RUN: opt < %s -passes=asan -asan-globals-live-support=0 -mtriple=x86_64-apple-macosx10.11.0 -S | FileCheck --check-prefix=CHECK %s
3-
; RUN: opt < %s -passes=asan -asan-globals-live-support=0 -mtriple=x86_64-pc-windows-msvc19.0.24215 -S | FileCheck --check-prefix=CHECK %s
4-
; RUN: opt < %s -passes=asan -asan-globals-live-support=0 -asan-mapping-scale=5 -mtriple=x86_64-unknown-linux-gnu -S | FileCheck --check-prefixes=CHECK,CHECK-S5 %s
1+
; RUN: rm -rf %t && split-file %s %t && cd %t
2+
; RUN: opt < a.ll -passes=asan -asan-globals-live-support=0 -mtriple=x86_64-unknown-linux-gnu -S | FileCheck --check-prefix=CHECK %s
3+
; RUN: opt < a.ll -passes=asan -asan-globals-live-support=0 -mtriple=x86_64-apple-macosx10.11.0 -S | FileCheck --check-prefix=CHECK %s
4+
; RUN: opt < a.ll -passes=asan -asan-globals-live-support=0 -mtriple=x86_64-pc-windows-msvc19.0.24215 -S | FileCheck --check-prefix=CHECK %s
5+
; RUN: opt < a.ll -passes=asan -asan-globals-live-support=0 -asan-mapping-scale=5 -mtriple=x86_64-unknown-linux-gnu -S | FileCheck --check-prefixes=CHECK,CHECK-S5 %s
56

7+
; RUN: opt < empty.ll -passes=asan -asan-globals-live-support=0 -mtriple=x86_64-unknown-linux-gnu -S | FileCheck --check-prefix=ELF-NOGC %s
8+
9+
;--- a.ll
610
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
711

812
; Globals:
@@ -59,3 +63,10 @@ attributes #1 = { nounwind sanitize_address "less-precise-fpmad"="false" "frame-
5963
!7 = !{!"/tmp/asan-globals.cpp", i32 7, i32 5}
6064
!8 = !{!"/tmp/asan-globals.cpp", i32 12, i32 14}
6165
!9 = !{!"/tmp/asan-globals.cpp", i32 14, i32 25}
66+
67+
;; In the presence of instrumented global variables, asan.module_ctor do not use comdat.
68+
; CHECK: define internal void @asan.module_ctor() #[[#ATTR:]] {
69+
70+
; ELF-NOGC: define internal void @asan.module_ctor() #[[#ATTR:]] comdat {
71+
72+
;--- empty.ll

llvm/test/Instrumentation/AddressSanitizer/global_with_comdat.ll

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,14 @@
55
; enabled as indicator symbols will cause link time odr violations.
66
; This is to fix PR 47925.
77
;
8-
; RUN: opt < %s -passes=asan -asan-globals-live-support=1 -S | FileCheck %s --check-prefixes=CHECK,NOCOMDAT
8+
; RUN: rm -rf %t && split-file %s %t && cd %t
9+
; RUN: opt < a.ll -passes=asan -asan-globals-live-support=1 -asan-use-odr-indicator=0 -S | FileCheck %s --check-prefixes=CHECK,NOCOMDAT
910
; Check that enabling odr indicators enables comdat for globals.
10-
; RUN: opt < %s -passes=asan -asan-globals-live-support=1 -asan-use-odr-indicator=1 -S | FileCheck %s --check-prefixes=CHECK,COMDAT
11+
; RUN: opt < a.ll -passes=asan -asan-globals-live-support=1 -S | FileCheck %s --check-prefixes=CHECK,COMDAT
12+
13+
; RUN: opt < no_module_id.ll -passes=asan -S | FileCheck %s --check-prefix=NOMODULEID
14+
15+
;--- a.ll
1116
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
1217
target triple = "x86_64-unknown-linux-gnu"
1318

@@ -87,3 +92,43 @@ attributes #1 = { nounwind sanitize_address "less-precise-fpmad"="false" "frame-
8792
!7 = !{!"/tmp/asan-globals.cpp", i32 7, i32 5}
8893
!8 = !{!"/tmp/asan-globals.cpp", i32 12, i32 14}
8994
!9 = !{!"/tmp/asan-globals.cpp", i32 14, i32 25}
95+
96+
;--- no_module_id.ll
97+
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
98+
target triple = "x86_64-unknown-linux-gnu"
99+
100+
; NOMODULEID: $asan.module_ctor = comdat any
101+
; NOMODULEID: $asan.module_dtor = comdat any
102+
103+
;; Don't place the instrumented globals in a comdat when the unique module ID is empty.
104+
; NOMODULEID: @.str = internal constant { [4 x i8], [28 x i8] } { [4 x i8] c"str\00", [28 x i8] zeroinitializer }, align 32
105+
; NOMODULEID: @_ZL3buf = internal global { [4 x i8], [28 x i8] } zeroinitializer, align 32
106+
; NOMODULEID: @__asan_global_.str = private global {{.*}}, section "asan_globals", !associated !0
107+
; NOMODULEID: @__asan_global__ZL3buf = private global {{.*}}, section "asan_globals", !associated !1
108+
; NOMODULEID: @llvm.compiler.used = appending global [4 x ptr] [ptr @.str, ptr @_ZL3buf, ptr @__asan_global_.str, ptr @__asan_global__ZL3buf]
109+
110+
; NOMODULEID: define internal void @asan.module_ctor() #[[#]] comdat {
111+
; NOMODULEID-NEXT: call void @__asan_init()
112+
; NOMODULEID-NEXT: call void @__asan_version_mismatch_check_v8()
113+
; NOMODULEID-NEXT: call void @__asan_register_elf_globals(i64 ptrtoint (ptr @___asan_globals_registered to i64), i64 ptrtoint (ptr @__start_asan_globals to i64), i64 ptrtoint (ptr @__stop_asan_globals to i64))
114+
; NOMODULEID-NEXT: ret void
115+
; NOMODULEID-NEXT: }
116+
117+
; NOMODULEID: !0 = !{ptr @.str}
118+
; NOMODULEID: !1 = !{ptr @_ZL3buf}
119+
120+
@.str = private unnamed_addr constant [4 x i8] c"str\00", align 1
121+
@_ZL3buf = internal unnamed_addr global [4 x i8] zeroinitializer, align 1
122+
@llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 65535, ptr @_GLOBAL__sub_I_a.cc, ptr null }]
123+
124+
declare void @ext(ptr noundef)
125+
126+
; Function Attrs: uwtable
127+
define internal void @_GLOBAL__sub_I_a.cc() #2 section ".text.startup" {
128+
entry:
129+
%0 = load i8, ptr @_ZL3buf, align 1
130+
%inc = add i8 %0, 1
131+
store i8 %inc, ptr @_ZL3buf, align 1
132+
tail call void @ext(ptr noundef nonnull @.str)
133+
ret void
134+
}

0 commit comments

Comments
 (0)