Skip to content

Commit

Permalink
[llvm-objcopy] Remove empty SHT_GROUP sections (#97141)
Browse files Browse the repository at this point in the history
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 #97139
  • Loading branch information
chestnykh authored Jul 8, 2024
1 parent f002558 commit 359c64f
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 2 deletions.
11 changes: 10 additions & 1 deletion llvm/lib/ObjCopy/ELF/ELFObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2239,8 +2239,17 @@ Error Object::removeSections(
// Transfer removed sections into the Object RemovedSections container for use
// later.
std::move(Iter, Sections.end(), std::back_inserter(RemovedSections));
// Now finally get rid of them all together.
// Now get rid of them altogether.
Sections.erase(Iter, std::end(Sections));

// Finally erase empty SHT_GROUP sections.
llvm::erase_if(Sections, [](const SecPtr &Sec) {
if (auto GroupSec = dyn_cast<GroupSection>(Sec.get()))
return GroupSec->getMembersCount() == 0;

return false;
});

return Error::success();
}

Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/ObjCopy/ELF/ELFObject.h
Original file line number Diff line number Diff line change
Expand Up @@ -964,6 +964,8 @@ class GroupSection : public SectionBase {
const DenseMap<SectionBase *, SectionBase *> &FromTo) override;
void onRemove() override;

size_t getMembersCount() const { return GroupMembers.size(); }

static bool classof(const SectionBase *S) {
return S->OriginalType == ELF::SHT_GROUP;
}
Expand Down
50 changes: 49 additions & 1 deletion llvm/test/tools/llvm-objcopy/ELF/remove-section-in-group.test
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
## This checks that the group section is shrunk when its member is removed.

# RUN: yaml2obj %s -o - \
# RUN: yaml2obj --docnum=1 %s -o - \
# RUN: | llvm-objcopy -R .foo - - \
# RUN: | obj2yaml - \
# RUN: | FileCheck %s
Expand Down Expand Up @@ -35,3 +35,51 @@ Symbols:
- Name: foo_bar_grp
Section: .group
Binding: STB_GLOBAL

# RUN: yaml2obj --docnum=2 %s -o %t
# RUN: llvm-objcopy --remove-section=.debug_macro %t
# RUN: llvm-readelf --section-groups %t | FileCheck %s --check-prefix=GROUP-REMOVED

--- !ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_REL
Machine: EM_X86_64
Sections:
- Name: .group
Type: SHT_GROUP
Info: foo_grp
Members:
- SectionOrType: GRP_COMDAT
- SectionOrType: .debug_macro
- Name: .debug_macro
Type: SHT_PROGBITS
Flags: [ SHF_GROUP ]
Symbols:
- Name: foo_grp
Section: .group

# GROUP-REMOVED: There are no section groups in this file.

# RUN: yaml2obj --docnum=3 %s -o %t
# RUN: llvm-objcopy --remove-section=.group %t
# RUN: llvm-readelf --section-groups %t | FileCheck %s --check-prefix=EMPTY-GROUP-REMOVED

--- !ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_REL
Machine: EM_X86_64
Sections:
- Name: .group
Type: SHT_GROUP
Info: foo_grp
Members:
- SectionOrType: GRP_COMDAT
Symbols:
- Name: foo_grp
Section: .group

# EMPTY-GROUP-REMOVED: There are no section groups in this file.

0 comments on commit 359c64f

Please sign in to comment.