[llvm] e142a55 - [llvm-objcopy] Remove references for empty section groups (#98106)

via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 9 14:48:13 PDT 2024


Author: Pranav Kant
Date: 2024-07-09T14:48:09-07:00
New Revision: e142a5568627d8f90b13aaca3e427cb0bed71464

URL: https://github.com/llvm/llvm-project/commit/e142a5568627d8f90b13aaca3e427cb0bed71464
DIFF: https://github.com/llvm/llvm-project/commit/e142a5568627d8f90b13aaca3e427cb0bed71464.diff

LOG: [llvm-objcopy] Remove references for empty section groups (#98106)

Otherwise, llvm-objcopy fails with use-after-free when built under
sanitizers. Simple repro: run the test
`ELF/remove-section-in-group.test` under asan. This is due to symbol
table references to empty section groups that must be removed.

Added: 
    

Modified: 
    llvm/lib/ObjCopy/ELF/ELFObject.cpp
    llvm/lib/ObjCopy/ELF/ELFObject.h
    llvm/test/tools/llvm-objcopy/ELF/remove-section-in-group.test

Removed: 
    


################################################################################
diff  --git a/llvm/lib/ObjCopy/ELF/ELFObject.cpp b/llvm/lib/ObjCopy/ELF/ELFObject.cpp
index 5e6d19b9bfa54..fd55f974115a2 100644
--- a/llvm/lib/ObjCopy/ELF/ELFObject.cpp
+++ b/llvm/lib/ObjCopy/ELF/ELFObject.cpp
@@ -2203,6 +2203,11 @@ Error Object::removeSections(
           if (auto ToRelSec = RelSec->getSection())
             return !ToRemove(*ToRelSec);
         }
+        // Remove empty group sections.
+        if (Sec->Type == ELF::SHT_GROUP) {
+          auto GroupSec = cast<GroupSection>(Sec.get());
+          return !llvm::all_of(GroupSec->members(), ToRemove);
+        }
         return true;
       });
   if (SymbolTable != nullptr && ToRemove(*SymbolTable))

diff  --git a/llvm/lib/ObjCopy/ELF/ELFObject.h b/llvm/lib/ObjCopy/ELF/ELFObject.h
index e3c0e7abda16b..6ccf85387131e 100644
--- a/llvm/lib/ObjCopy/ELF/ELFObject.h
+++ b/llvm/lib/ObjCopy/ELF/ELFObject.h
@@ -941,6 +941,9 @@ class GroupSection : public SectionBase {
   SmallVector<SectionBase *, 3> GroupMembers;
 
 public:
+  template <class T>
+  using ConstRange = iterator_range<
+      pointee_iterator<typename llvm::SmallVector<T *, 3>::const_iterator>>;
   // TODO: Contents is present in several classes of the hierarchy.
   // This needs to be refactored to avoid duplication.
   ArrayRef<uint8_t> Contents;
@@ -964,6 +967,10 @@ class GroupSection : public SectionBase {
       const DenseMap<SectionBase *, SectionBase *> &FromTo) override;
   void onRemove() override;
 
+  ConstRange<SectionBase> members() const {
+    return make_pointee_range(GroupMembers);
+  }
+
   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..20a836cae8bfe 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.
\ No newline at end of file


        


More information about the llvm-commits mailing list