mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 03:02:36 +01:00
[llvm-objcopy][ELF] Fix removing SHT_GROUP sections.
When a SHT_GROUP section is removed, but other sections of the group are kept, the SHF_GROUP flag of these sections should be dropped, otherwise the resulting ELF file will be malformed. Differential Revision: https://reviews.llvm.org/D80511
This commit is contained in:
parent
6837e69bdf
commit
786d96db56
33
test/tools/llvm-objcopy/ELF/remove-section-group.test
Normal file
33
test/tools/llvm-objcopy/ELF/remove-section-group.test
Normal file
@ -0,0 +1,33 @@
|
||||
## This checks that when the header section of a group is removed, the tool
|
||||
## drops the flag SHF_GROUP for preserved members of that group.
|
||||
|
||||
# RUN: yaml2obj %s -o - \
|
||||
# RUN: | llvm-objcopy -R .group - - \
|
||||
# RUN: | llvm-readobj --sections - \
|
||||
# RUN: | FileCheck %s
|
||||
|
||||
# CHECK: Name: .foo
|
||||
# CHECK-NEXT: Type: SHT_PROGBITS
|
||||
# CHECK-NEXT: Flags [
|
||||
# CHECK-NEXT: SHF_ALLOC
|
||||
# CHECK-NEXT: ]
|
||||
|
||||
--- !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: .foo
|
||||
- Name: .foo
|
||||
Type: SHT_PROGBITS
|
||||
Flags: [ SHF_ALLOC, SHF_GROUP ]
|
||||
Symbols:
|
||||
- Name: foo_grp
|
||||
Section: .group
|
@ -65,6 +65,7 @@ void SectionBase::finalize() {}
|
||||
void SectionBase::markSymbols() {}
|
||||
void SectionBase::replaceSectionReferences(
|
||||
const DenseMap<SectionBase *, SectionBase *> &) {}
|
||||
void SectionBase::onRemove() {}
|
||||
|
||||
template <class ELFT> void ELFWriter<ELFT>::writeShdr(const SectionBase &Sec) {
|
||||
uint8_t *B = Buf.getBufferStart() + Sec.HeaderOffset;
|
||||
@ -988,6 +989,13 @@ void GroupSection::replaceSectionReferences(
|
||||
Sec = To;
|
||||
}
|
||||
|
||||
void GroupSection::onRemove() {
|
||||
// As the header section of the group is removed, drop the Group flag in its
|
||||
// former members.
|
||||
for (SectionBase *Sec : GroupMembers)
|
||||
Sec->Flags &= ~SHF_GROUP;
|
||||
}
|
||||
|
||||
void Section::initialize(SectionTableRef SecTable) {
|
||||
if (Link == ELF::SHN_UNDEF)
|
||||
return;
|
||||
@ -1838,6 +1846,7 @@ Error Object::removeSections(bool AllowBrokenLinks,
|
||||
for (auto &RemoveSec : make_range(Iter, std::end(Sections))) {
|
||||
for (auto &Segment : Segments)
|
||||
Segment->removeSection(RemoveSec.get());
|
||||
RemoveSec->onRemove();
|
||||
RemoveSections.insert(RemoveSec.get());
|
||||
}
|
||||
|
||||
|
@ -424,6 +424,8 @@ public:
|
||||
virtual void markSymbols();
|
||||
virtual void
|
||||
replaceSectionReferences(const DenseMap<SectionBase *, SectionBase *> &);
|
||||
// Notify the section that it is subject to removal.
|
||||
virtual void onRemove();
|
||||
};
|
||||
|
||||
class Segment {
|
||||
@ -803,6 +805,7 @@ public:
|
||||
void markSymbols() override;
|
||||
void replaceSectionReferences(
|
||||
const DenseMap<SectionBase *, SectionBase *> &FromTo) override;
|
||||
void onRemove() override;
|
||||
|
||||
static bool classof(const SectionBase *S) {
|
||||
return S->OriginalType == ELF::SHT_GROUP;
|
||||
|
Loading…
Reference in New Issue
Block a user