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 new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-objcopy/ELF/remove-section-in-group.test @@ -0,0 +1,36 @@ +## This checks that the group section is shrunk when its member is removed. + +# RUN: yaml2obj %s -o - \ +# RUN: | llvm-objcopy -R .foo - - \ +# RUN: | obj2yaml - \ +# RUN: | FileCheck %s + +# CHECK: - Name: .group +# CHECK: Members: +# CHECK-NEXT: - SectionOrType: GRP_COMDAT +# CHECK-NEXT: - SectionOrType: .bar +# CHECK-NOT: - SectionOrType: + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name: .group + Type: SHT_GROUP + Info: foo_bar_grp + Members: + - SectionOrType: GRP_COMDAT + - SectionOrType: .foo + - SectionOrType: .bar + - Name: .foo + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_GROUP ] + - Name: .bar + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_GROUP ] +Symbols: + - Name: foo_bar_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 @@ -801,6 +801,9 @@ void accept(SectionVisitor &) const override; void accept(MutableSectionVisitor &Visitor) override; void finalize() override; + Error removeSectionReferences( + bool AllowBrokenLinks, + function_ref ToRemove) override; Error removeSymbols(function_ref ToRemove) override; void markSymbols() override; void replaceSectionReferences( 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 @@ -112,7 +112,9 @@ template void ELFSectionSizer::visit(GnuDebugLinkSection &Sec) {} -template void ELFSectionSizer::visit(GroupSection &Sec) {} +template void ELFSectionSizer::visit(GroupSection &Sec) { + Sec.Size = sizeof(Elf_Word) + Sec.GroupMembers.size() * sizeof(Elf_Word); +} template void ELFSectionSizer::visit(SectionIndexSection &Sec) {} @@ -968,6 +970,12 @@ this->Link = SymTab->Index; } +Error GroupSection::removeSectionReferences( + bool AllowBrokenLinks, function_ref ToRemove) { + llvm::erase_if(GroupMembers, ToRemove); + return Error::success(); +} + Error GroupSection::removeSymbols(function_ref ToRemove) { if (ToRemove(*Sym)) return createStringError(llvm::errc::invalid_argument,