diff options
author | Igor Kudrin <ikudrin@accesssoftek.com> | 2020-05-29 19:27:28 +0700 |
---|---|---|
committer | Igor Kudrin <ikudrin@accesssoftek.com> | 2020-05-29 20:24:53 +0700 |
commit | a9313282cd5413ed498dceb763ebba12ea5bdecd (patch) | |
tree | 834c56de6e190a2839a3fc1bf0172c811d7b16c5 /llvm/tools/llvm-objcopy/ELF/Object.cpp | |
parent | 99a3b20452b16aa92e18e4f5d2c8c6f025aafbae (diff) | |
download | llvm-a9313282cd5413ed498dceb763ebba12ea5bdecd.zip llvm-a9313282cd5413ed498dceb763ebba12ea5bdecd.tar.gz llvm-a9313282cd5413ed498dceb763ebba12ea5bdecd.tar.bz2 |
[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
Diffstat (limited to 'llvm/tools/llvm-objcopy/ELF/Object.cpp')
-rw-r--r-- | llvm/tools/llvm-objcopy/ELF/Object.cpp | 9 |
1 files changed, 9 insertions, 0 deletions
diff --git a/llvm/tools/llvm-objcopy/ELF/Object.cpp b/llvm/tools/llvm-objcopy/ELF/Object.cpp index 8c3ae25..2ceb479 100644 --- a/llvm/tools/llvm-objcopy/ELF/Object.cpp +++ b/llvm/tools/llvm-objcopy/ELF/Object.cpp @@ -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()); } |