diff --git a/llvm/test/tools/llvm-objcopy/ELF/remove-section-group.test b/llvm/test/tools/llvm-objcopy/ELF/remove-section-group.test new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-objcopy/ELF/remove-section-group.test @@ -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 diff --git a/llvm/tools/llvm-objcopy/ELF/Object.h b/llvm/tools/llvm-objcopy/ELF/Object.h --- a/llvm/tools/llvm-objcopy/ELF/Object.h +++ b/llvm/tools/llvm-objcopy/ELF/Object.h @@ -424,6 +424,8 @@ virtual void markSymbols(); virtual void replaceSectionReferences(const DenseMap &); + // Notify the section that it is subject to removal. + virtual void onRemove(); }; class Segment { @@ -803,6 +805,7 @@ void markSymbols() override; void replaceSectionReferences( const DenseMap &FromTo) override; + void onRemove() override; static bool classof(const SectionBase *S) { return S->OriginalType == ELF::SHT_GROUP; diff --git a/llvm/tools/llvm-objcopy/ELF/Object.cpp b/llvm/tools/llvm-objcopy/ELF/Object.cpp --- a/llvm/tools/llvm-objcopy/ELF/Object.cpp +++ b/llvm/tools/llvm-objcopy/ELF/Object.cpp @@ -65,6 +65,7 @@ void SectionBase::markSymbols() {} void SectionBase::replaceSectionReferences( const DenseMap &) {} +void SectionBase::onRemove() {} template void ELFWriter::writeShdr(const SectionBase &Sec) { uint8_t *B = Buf.getBufferStart() + Sec.HeaderOffset; @@ -988,6 +989,13 @@ 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 @@ for (auto &RemoveSec : make_range(Iter, std::end(Sections))) { for (auto &Segment : Segments) Segment->removeSection(RemoveSec.get()); + RemoveSec->onRemove(); RemoveSections.insert(RemoveSec.get()); }