[llvm] [llvm-objcopy] Remove references for empty section groups (PR #98106)
Pranav Kant via llvm-commits
llvm-commits at lists.llvm.org
Tue Jul 9 10:48:26 PDT 2024
https://github.com/pranavk updated https://github.com/llvm/llvm-project/pull/98106
>From 91c329d6daf5c7b247111bd1911fe9d63211e695 Mon Sep 17 00:00:00 2001
From: Pranav Kant <prka at google.com>
Date: Tue, 9 Jul 2024 02:41:06 +0000
Subject: [PATCH] [llvm-objcopy] Remove references for empty section groups
Otherwise, llvm-objcopy fails with use-after-free when built under
sanitizers. Simple repro can be running the test ELF/remove-section-in-group.test
under asan. This is due to symbol table references to empty section groups.
---
llvm/lib/ObjCopy/ELF/ELFObject.cpp | 5 ++
llvm/lib/ObjCopy/ELF/ELFObject.h | 7 +++
.../ELF/remove-section-in-group.test | 50 ++++++++++++++++++-
3 files changed, 61 insertions(+), 1 deletion(-)
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