Skip to content

Commit 359c64f

Browse files
authored
[llvm-objcopy] Remove empty SHT_GROUP sections (llvm#97141)
Currently `llvm-objcopy/llvm-strip` in `--strip-debug` mode doesn't remove such sections. This behavior can lead to incompatibilities with GNU binutils (for examples ld.bfd before https://sourceware.org/PR20520 cannot process the object file contains empty .group section). The ELF object that contains group section with `.debug_*` sections inside can be obtained by `gcc -g3`. Fix llvm#97139
1 parent f002558 commit 359c64f

File tree

3 files changed

+61
-2
lines changed

3 files changed

+61
-2
lines changed

llvm/lib/ObjCopy/ELF/ELFObject.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2239,8 +2239,17 @@ Error Object::removeSections(
22392239
// Transfer removed sections into the Object RemovedSections container for use
22402240
// later.
22412241
std::move(Iter, Sections.end(), std::back_inserter(RemovedSections));
2242-
// Now finally get rid of them all together.
2242+
// Now get rid of them altogether.
22432243
Sections.erase(Iter, std::end(Sections));
2244+
2245+
// Finally erase empty SHT_GROUP sections.
2246+
llvm::erase_if(Sections, [](const SecPtr &Sec) {
2247+
if (auto GroupSec = dyn_cast<GroupSection>(Sec.get()))
2248+
return GroupSec->getMembersCount() == 0;
2249+
2250+
return false;
2251+
});
2252+
22442253
return Error::success();
22452254
}
22462255

llvm/lib/ObjCopy/ELF/ELFObject.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -964,6 +964,8 @@ class GroupSection : public SectionBase {
964964
const DenseMap<SectionBase *, SectionBase *> &FromTo) override;
965965
void onRemove() override;
966966

967+
size_t getMembersCount() const { return GroupMembers.size(); }
968+
967969
static bool classof(const SectionBase *S) {
968970
return S->OriginalType == ELF::SHT_GROUP;
969971
}

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

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
## This checks that the group section is shrunk when its member is removed.
22

3-
# RUN: yaml2obj %s -o - \
3+
# RUN: yaml2obj --docnum=1 %s -o - \
44
# RUN: | llvm-objcopy -R .foo - - \
55
# RUN: | obj2yaml - \
66
# RUN: | FileCheck %s
@@ -35,3 +35,51 @@ Symbols:
3535
- Name: foo_bar_grp
3636
Section: .group
3737
Binding: STB_GLOBAL
38+
39+
# RUN: yaml2obj --docnum=2 %s -o %t
40+
# RUN: llvm-objcopy --remove-section=.debug_macro %t
41+
# RUN: llvm-readelf --section-groups %t | FileCheck %s --check-prefix=GROUP-REMOVED
42+
43+
--- !ELF
44+
FileHeader:
45+
Class: ELFCLASS64
46+
Data: ELFDATA2LSB
47+
Type: ET_REL
48+
Machine: EM_X86_64
49+
Sections:
50+
- Name: .group
51+
Type: SHT_GROUP
52+
Info: foo_grp
53+
Members:
54+
- SectionOrType: GRP_COMDAT
55+
- SectionOrType: .debug_macro
56+
- Name: .debug_macro
57+
Type: SHT_PROGBITS
58+
Flags: [ SHF_GROUP ]
59+
Symbols:
60+
- Name: foo_grp
61+
Section: .group
62+
63+
# GROUP-REMOVED: There are no section groups in this file.
64+
65+
# RUN: yaml2obj --docnum=3 %s -o %t
66+
# RUN: llvm-objcopy --remove-section=.group %t
67+
# RUN: llvm-readelf --section-groups %t | FileCheck %s --check-prefix=EMPTY-GROUP-REMOVED
68+
69+
--- !ELF
70+
FileHeader:
71+
Class: ELFCLASS64
72+
Data: ELFDATA2LSB
73+
Type: ET_REL
74+
Machine: EM_X86_64
75+
Sections:
76+
- Name: .group
77+
Type: SHT_GROUP
78+
Info: foo_grp
79+
Members:
80+
- SectionOrType: GRP_COMDAT
81+
Symbols:
82+
- Name: foo_grp
83+
Section: .group
84+
85+
# EMPTY-GROUP-REMOVED: There are no section groups in this file.

0 commit comments

Comments
 (0)