[llvm] Remove empty SHT_GROUP sections. (PR #97141)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Jun 28 23:34:19 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-binary-utilities
Author: Dmitriy Chestnykh (chestnykh)
<details>
<summary>Changes</summary>
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
---
Full diff: https://github.com/llvm/llvm-project/pull/97141.diff
3 Files Affected:
- (modified) llvm/lib/ObjCopy/ELF/ELFObject.cpp (+9-1)
- (modified) llvm/lib/ObjCopy/ELF/ELFObject.h (+2)
- (added) llvm/test/tools/llvm-objcopy/ELF/strip-debug-empty-group.test (+25)
``````````diff
diff --git a/llvm/lib/ObjCopy/ELF/ELFObject.cpp b/llvm/lib/ObjCopy/ELF/ELFObject.cpp
index 02591e6f987c2..44181ccd328bf 100644
--- a/llvm/lib/ObjCopy/ELF/ELFObject.cpp
+++ b/llvm/lib/ObjCopy/ELF/ELFObject.cpp
@@ -2206,8 +2206,16 @@ 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 all together.
Sections.erase(Iter, std::end(Sections));
+
+ // Finally iterate over all sections and erase empty SHT_GROUP sections.
+ for (auto Iter = Sections.begin(); Iter != Sections.end(); ++Iter) {
+ if (auto GroupSec = dyn_cast<GroupSection>(Iter->get())) {
+ if (GroupSec->getMembersCount() == 0)
+ Sections.erase(Iter);
+ }
+ }
return Error::success();
}
diff --git a/llvm/lib/ObjCopy/ELF/ELFObject.h b/llvm/lib/ObjCopy/ELF/ELFObject.h
index 2b1895a30b41e..9bbef268017ea 100644
--- a/llvm/lib/ObjCopy/ELF/ELFObject.h
+++ b/llvm/lib/ObjCopy/ELF/ELFObject.h
@@ -963,6 +963,8 @@ class GroupSection : public SectionBase {
const DenseMap<SectionBase *, SectionBase *> &FromTo) override;
void onRemove() override;
+ size_t getMembersCount() {return GroupMembers.size(); }
+
static bool classof(const SectionBase *S) {
return S->OriginalType == ELF::SHT_GROUP;
}
diff --git a/llvm/test/tools/llvm-objcopy/ELF/strip-debug-empty-group.test b/llvm/test/tools/llvm-objcopy/ELF/strip-debug-empty-group.test
new file mode 100644
index 0000000000000..26bbde0c603bb
--- /dev/null
+++ b/llvm/test/tools/llvm-objcopy/ELF/strip-debug-empty-group.test
@@ -0,0 +1,25 @@
+# RUN: yaml2obj %s -o %t
+# RUN: llvm-strip --strip-debug %t -o %t1
+# RUN: llvm-readelf --section-groups %t1 | FileCheck %s
+
+--- !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
+
+# CHECK: There are no section groups in this file.
``````````
</details>
https://github.com/llvm/llvm-project/pull/97141
More information about the llvm-commits
mailing list