Skip to content

Commit fbd81eb

Browse files
committed
[llvm-strip] Remove empty SHT_GROUP sections.
Currently llvm-strip in --strip-debug mode doesn't remove such sections. This behavior can lead to incompatibilities with GNU binutils (for examples ld.bfd 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 #97139
1 parent 8bb00cb commit fbd81eb

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
@@ -2206,8 +2206,17 @@ Error Object::removeSections(
22062206
// Transfer removed sections into the Object RemovedSections container for use
22072207
// later.
22082208
std::move(Iter, Sections.end(), std::back_inserter(RemovedSections));
2209-
// Now finally get rid of them all together.
2209+
// Now get rid of them altogether.
22102210
Sections.erase(Iter, std::end(Sections));
2211+
2212+
// Finally erase empty SHT_GROUP sections.
2213+
llvm::erase_if(Sections, [](const SecPtr &Sec) {
2214+
if (auto GroupSec = dyn_cast<GroupSection>(Sec.get()))
2215+
return GroupSec->getMembersCount() == 0;
2216+
2217+
return false;
2218+
});
2219+
22112220
return Error::success();
22122221
}
22132222

llvm/lib/ObjCopy/ELF/ELFObject.h

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

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

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)