Skip to content

Commit 792c206

Browse files
committed
[llvm-objcopy] Drop GRP_COMDAT if the group signature is localized
See [GRP_COMDAT group with STB_LOCAL signature](https://groups.google.com/g/generic-abi/c/2X6mR-s2zoc) objcopy PR: https://sourceware.org/bugzilla/show_bug.cgi?id=27931 GRP_COMDAT deduplication is purely based on the signature symbol name in ld.lld/GNU ld/gold. The local/global status is not part of the equation. If the signature symbol is localized by --localize-hidden or --keep-global-symbol, the intention is likely to make the group fully localized. Drop GRP_COMDAT to suppress deduplication. Reviewed By: jhenderson Differential Revision: https://reviews.llvm.org/D106782
1 parent c0da287 commit 792c206

File tree

5 files changed

+61
-2
lines changed

5 files changed

+61
-2
lines changed

llvm/test/tools/llvm-objcopy/ELF/group-reorder.test

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,4 +61,5 @@ Symbols:
6161
Section: .bar
6262
- Name: bar
6363
Type: STT_FUNC
64+
Binding: STB_GLOBAL
6465
Section: .foo

llvm/test/tools/llvm-objcopy/ELF/group.test

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,3 +78,52 @@ Symbols:
7878
## sh_info fields.
7979
# RUN: llvm-objcopy --allow-broken-links -R .symtab %t3 %t4
8080
# RUN: cmp %t3 %t4
81+
82+
## The signature symbol becomes local. Assume the intention is to localize the group.
83+
## Drop GRP_COMDAT so that the linker will suppress deduplication.
84+
# RUN: llvm-objcopy --keep-global-symbol=bar %t %t5
85+
# RUN: llvm-readelf -s --section-groups %t5 | FileCheck %s --check-prefix=LOCAL-SIG
86+
87+
# LOCAL-SIG: LOCAL DEFAULT [[#]] foo
88+
# LOCAL-SIG: (unknown) group section [ 1] `.group' [foo] contains 1 sections:
89+
90+
## The signature symbol remains non-local. Keep GRP_COMDAT.
91+
# RUN: llvm-readelf -s --section-groups %t1 | FileCheck %s --check-prefix=WEAK-SIG
92+
93+
# WEAK-SIG: WEAK DEFAULT [[#]] foo
94+
# WEAK-SIG: COMDAT group section [ 1] `.group' [foo] contains 1 sections:
95+
96+
# RUN: llvm-objcopy --globalize-symbol=foo %t %t6
97+
# RUN: llvm-readelf -s --section-groups %t6 | FileCheck %s --check-prefix=GLOBAL-SIG
98+
99+
# GLOBAL-SIG: GLOBAL DEFAULT [[#]] foo
100+
# GLOBAL-SIG: COMDAT group section [ 1] `.group' [foo] contains 1 sections:
101+
102+
## If the signature is initially local and no operation has been performed to
103+
## specifically localize it, it isn't clear whether we should drop GRP_COMDAT.
104+
## The current convention is that compilers should not produce such input, so
105+
## our choice does not matter.
106+
# RUN: yaml2obj --docnum=2 %s -o %t.localsig
107+
# RUN: llvm-objcopy %t.localsig %t.localsig.out
108+
# RUN: llvm-readelf -s --section-groups %t.localsig.out | FileCheck %s --check-prefix=LOCAL-SIG
109+
110+
--- !ELF
111+
FileHeader:
112+
Class: ELFCLASS64
113+
Data: ELFDATA2LSB
114+
Type: ET_REL
115+
Machine: EM_X86_64
116+
Sections:
117+
- Name: .group
118+
Type: SHT_GROUP
119+
Info: foo
120+
Members:
121+
- SectionOrType: GRP_COMDAT
122+
- SectionOrType: .text.foo
123+
- Name: .text.foo
124+
Type: SHT_PROGBITS
125+
Flags: [ SHF_GROUP ]
126+
Symbols:
127+
- Name: foo
128+
Type: STT_FUNC
129+
Section: .text.foo

llvm/test/tools/llvm-objcopy/ELF/remove-section-in-group.test

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,4 @@ Sections:
3434
Symbols:
3535
- Name: foo_bar_grp
3636
Section: .group
37+
Binding: STB_GLOBAL

llvm/test/tools/llvm-objcopy/ELF/strip-dwo-groups.test

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,11 @@ Sections:
7575
Symbols:
7676
- Name: debug_before
7777
Section: .debug_before.dwo
78+
- Name: debug_after
79+
Section: .debug_after.dwo
7880
- Name: group2
7981
Section: .text.group2
82+
Binding: STB_WEAK
8083
- Name: group1
8184
Section: .text.group1
82-
- Name: debug_after
83-
Section: .debug_after.dwo
85+
Binding: STB_WEAK

llvm/tools/llvm-objcopy/ELF/Object.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1069,6 +1069,12 @@ Error Section::removeSectionReferences(
10691069
void GroupSection::finalize() {
10701070
this->Info = Sym ? Sym->Index : 0;
10711071
this->Link = SymTab ? SymTab->Index : 0;
1072+
// Linker deduplication for GRP_COMDAT is based on Sym->Name. The local/global
1073+
// status is not part of the equation. If Sym is localized, the intention is
1074+
// likely to make the group fully localized. Drop GRP_COMDAT to suppress
1075+
// deduplication. See https://groups.google.com/g/generic-abi/c/2X6mR-s2zoc
1076+
if ((FlagWord & GRP_COMDAT) && Sym && Sym->Binding == STB_LOCAL)
1077+
this->FlagWord &= ~GRP_COMDAT;
10721078
}
10731079

10741080
Error GroupSection::removeSectionReferences(

0 commit comments

Comments
 (0)