[llvm] [llvm-strip] Remove empty SHT_GROUP sections. (PR #97141)

Dmitriy Chestnykh via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 4 02:41:51 PDT 2024


https://github.com/chestnykh updated https://github.com/llvm/llvm-project/pull/97141

>From f0108b1a98b007ac1040e7a238d0eb438362039f Mon Sep 17 00:00:00 2001
From: Dmitry Chestnykh <dm.chestnykh at gmail.com>
Date: Sun, 30 Jun 2024 13:21:34 +0300
Subject: [PATCH] [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
---
 llvm/lib/ObjCopy/ELF/ELFObject.cpp            |  9 +++-
 llvm/lib/ObjCopy/ELF/ELFObject.h              |  2 +
 .../ELF/remove-section-in-group.test          | 50 ++++++++++++++++++-
 3 files changed, 59 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/ObjCopy/ELF/ELFObject.cpp b/llvm/lib/ObjCopy/ELF/ELFObject.cpp
index 02591e6f987c2..3517dcb893a1b 100644
--- a/llvm/lib/ObjCopy/ELF/ELFObject.cpp
+++ b/llvm/lib/ObjCopy/ELF/ELFObject.cpp
@@ -2206,8 +2206,15 @@ 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 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..2adab618ce12f 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/remove-section-in-group.test b/llvm/test/tools/llvm-objcopy/ELF/remove-section-in-group.test
index 9e683b9f68c93..ccc1ede0589c1 100644
--- a/llvm/test/tools/llvm-objcopy/ELF/remove-section-in-group.test
+++ b/llvm/test/tools/llvm-objcopy/ELF/remove-section-in-group.test
@@ -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
@@ -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.



More information about the llvm-commits mailing list