Skip to content

Commit e142a55

Browse files
authored
[llvm-objcopy] Remove references for empty section groups (llvm#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.
1 parent 8e9d50c commit e142a55

File tree

3 files changed

+61
-1
lines changed

3 files changed

+61
-1
lines changed

llvm/lib/ObjCopy/ELF/ELFObject.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2203,6 +2203,11 @@ Error Object::removeSections(
22032203
if (auto ToRelSec = RelSec->getSection())
22042204
return !ToRemove(*ToRelSec);
22052205
}
2206+
// Remove empty group sections.
2207+
if (Sec->Type == ELF::SHT_GROUP) {
2208+
auto GroupSec = cast<GroupSection>(Sec.get());
2209+
return !llvm::all_of(GroupSec->members(), ToRemove);
2210+
}
22062211
return true;
22072212
});
22082213
if (SymbolTable != nullptr && ToRemove(*SymbolTable))

llvm/lib/ObjCopy/ELF/ELFObject.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -941,6 +941,9 @@ class GroupSection : public SectionBase {
941941
SmallVector<SectionBase *, 3> GroupMembers;
942942

943943
public:
944+
template <class T>
945+
using ConstRange = iterator_range<
946+
pointee_iterator<typename llvm::SmallVector<T *, 3>::const_iterator>>;
944947
// TODO: Contents is present in several classes of the hierarchy.
945948
// This needs to be refactored to avoid duplication.
946949
ArrayRef<uint8_t> Contents;
@@ -964,6 +967,10 @@ class GroupSection : public SectionBase {
964967
const DenseMap<SectionBase *, SectionBase *> &FromTo) override;
965968
void onRemove() override;
966969

970+
ConstRange<SectionBase> members() const {
971+
return make_pointee_range(GroupMembers);
972+
}
973+
967974
static bool classof(const SectionBase *S) {
968975
return S->OriginalType == ELF::SHT_GROUP;
969976
}

llvm/test/tools/llvm-objcopy/ELF/remove-section-in-group.test

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
## This checks that the group section is shrunk when its member is removed.
22

3-
# RUN: yaml2obj %s -o - \
3+
# RUN: yaml2obj --docnum=1 %s -o - \
44
# RUN: | llvm-objcopy -R .foo - - \
55
# RUN: | obj2yaml - \
66
# RUN: | FileCheck %s
@@ -35,3 +35,51 @@ Symbols:
3535
- Name: foo_bar_grp
3636
Section: .group
3737
Binding: STB_GLOBAL
38+
39+
# RUN: yaml2obj --docnum=2 %s -o %t
40+
# RUN: llvm-objcopy --remove-section=.debug_macro %t
41+
# RUN: llvm-readelf --section-groups %t | FileCheck %s --check-prefix=GROUP-REMOVED
42+
43+
--- !ELF
44+
FileHeader:
45+
Class: ELFCLASS64
46+
Data: ELFDATA2LSB
47+
Type: ET_REL
48+
Machine: EM_X86_64
49+
Sections:
50+
- Name: .group
51+
Type: SHT_GROUP
52+
Info: foo_grp
53+
Members:
54+
- SectionOrType: GRP_COMDAT
55+
- SectionOrType: .debug_macro
56+
- Name: .debug_macro
57+
Type: SHT_PROGBITS
58+
Flags: [ SHF_GROUP ]
59+
Symbols:
60+
- Name: foo_grp
61+
Section: .group
62+
63+
# GROUP-REMOVED: There are no section groups in this file.
64+
65+
# RUN: yaml2obj --docnum=3 %s -o %t
66+
# RUN: llvm-objcopy --remove-section=.group %t
67+
# RUN: llvm-readelf --section-groups %t | FileCheck %s --check-prefix=EMPTY-GROUP-REMOVED
68+
69+
--- !ELF
70+
FileHeader:
71+
Class: ELFCLASS64
72+
Data: ELFDATA2LSB
73+
Type: ET_REL
74+
Machine: EM_X86_64
75+
Sections:
76+
- Name: .group
77+
Type: SHT_GROUP
78+
Info: foo_grp
79+
Members:
80+
- SectionOrType: GRP_COMDAT
81+
Symbols:
82+
- Name: foo_grp
83+
Section: .group
84+
85+
# EMPTY-GROUP-REMOVED: There are no section groups in this file.

0 commit comments

Comments
 (0)