[PATCH] D37567: [llvm-readobj] - Teach tool to report error if some section is in multiple COMDAT groups at once.
Rafael Avila de Espindola via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 7 09:30:11 PDT 2017
Can the testcase be created with yaml2obj?
Can we have a common code path for printing the error in both cases?
Should the error go to stderr?
Should we exit with 1 when there is an error?
Cheers,
Rafael
George Rimar via Phabricator <reviews at reviews.llvm.org> writes:
> grimar created this revision.
>
> This is relative to PR34506,
> current LLD head produces broken output. It places the same section into 2 COMDAT groups.
> gnu readelf tool reports an error in this case.
>
> Patch teaches llvm-readobj to do the same.
>
>
> https://reviews.llvm.org/D37567
>
> Files:
> test/tools/llvm-readobj/Inputs/broken-group.obj.elf-x86_64
> test/tools/llvm-readobj/broken-group.test
> tools/llvm-readobj/ELFDumper.cpp
>
> Index: tools/llvm-readobj/ELFDumper.cpp
> ===================================================================
> --- tools/llvm-readobj/ELFDumper.cpp
> +++ tools/llvm-readobj/ELFDumper.cpp
> @@ -18,6 +18,7 @@
> #include "StackMapPrinter.h"
> #include "llvm-readobj.h"
> #include "llvm/ADT/ArrayRef.h"
> +#include "llvm/ADT/DenseMap.h"
> #include "llvm/ADT/Optional.h"
> #include "llvm/ADT/PointerIntPair.h"
> #include "llvm/ADT/SmallString.h"
> @@ -2444,6 +2445,7 @@
> template <class ELFT> void GNUStyle<ELFT>::printGroupSections(const ELFO *Obj) {
> uint32_t SectionIndex = 0;
> bool HasGroups = false;
> + DenseMap<uint32_t, uint32_t> SectionToGroup;
> for (const Elf_Shdr &Sec : unwrapOrError(Obj->sections())) {
> if (Sec.sh_type == ELF::SHT_GROUP) {
> HasGroups = true;
> @@ -2459,7 +2461,15 @@
> << StrTable.data() + Signature->st_name << "] contains "
> << (Data.size() - 1) << " sections:\n"
> << " [Index] Name\n";
> - for (auto &Ndx : Data.slice(1)) {
> + for (Elf_Word Ndx : Data.slice(1)) {
> + auto It = SectionToGroup.insert({Ndx, SectionIndex});
> + if (!It.second) {
> + OS << "Error: section [" << format_decimal(Ndx, 5)
> + << "] in group section [" << format_decimal(SectionIndex, 5)
> + << "] already in group section ["
> + << format_decimal(It.first->second, 5) << "]";
> + continue;
> + }
> auto Sec = unwrapOrError(Obj->getSection(Ndx));
> const StringRef Name = unwrapOrError(Obj->getSectionName(Sec));
> OS << " [" << format_decimal(Ndx, 5) << "] " << Name
> @@ -3491,6 +3501,7 @@
> DictScope Lists(W, "Groups");
> uint32_t SectionIndex = 0;
> bool HasGroups = false;
> + DenseMap<uint32_t, std::pair<StringRef, uint32_t>> SectionToGroup;
> for (const Elf_Shdr &Sec : unwrapOrError(Obj->sections())) {
> if (Sec.sh_type == ELF::SHT_GROUP) {
> HasGroups = true;
> @@ -3501,18 +3512,28 @@
> auto Data = unwrapOrError(
> Obj->template getSectionContentsAsArray<Elf_Word>(&Sec));
> DictScope D(W, "Group");
> - StringRef Name = unwrapOrError(Obj->getSectionName(&Sec));
> - W.printNumber("Name", Name, Sec.sh_name);
> + StringRef GroupName = unwrapOrError(Obj->getSectionName(&Sec));
> + W.printNumber("Name", GroupName, Sec.sh_name);
> W.printNumber("Index", SectionIndex);
> W.printHex("Type", getGroupType(Data[0]), Data[0]);
> W.startLine() << "Signature: " << StrTable.data() + Sym->st_name << "\n";
> {
> ListScope L(W, "Section(s) in group");
> size_t Member = 1;
> while (Member < Data.size()) {
> auto Sec = unwrapOrError(Obj->getSection(Data[Member]));
> - const StringRef Name = unwrapOrError(Obj->getSectionName(Sec));
> - W.startLine() << Name << " (" << Data[Member++] << ")\n";
> + Elf_Word Ndx = Data[Member++];
> + const StringRef SecName = unwrapOrError(Obj->getSectionName(Sec));
> + auto It = SectionToGroup.insert({Ndx, {GroupName, SectionIndex}});
> + if (!It.second) {
> + StringRef GroupName = It.first->second.first;
> + uint32_t GroupIndex = It.first->second.second;
> + W.startLine() << "Error: " << SecName << " (" << Ndx
> + << ") already in a group " + GroupName + " ("
> + << GroupIndex << ")\n";
> + continue;
> + }
> + W.startLine() << SecName << " (" << Ndx << ")\n";
> }
> }
> }
> Index: test/tools/llvm-readobj/broken-group.test
> ===================================================================
> --- test/tools/llvm-readobj/broken-group.test
> +++ test/tools/llvm-readobj/broken-group.test
> @@ -0,0 +1,41 @@
> +broken-group.obj.elf-x86_64 contans 2 COMDAT groups and each one contains
> +the same section foo. This is a result of bug in linker.
> +Testcase shows that llvm-readobj reports error in that case.
> +Linker used: LLD 6.0.0 (trunk 310596) (compatible with GNU linkers)
> +Code:
> +.section .foo,"axG", at progbits,bar,comdat
> +.section .foo,"axG", at progbits,zed,comdat
> +Invocation:
> +ld.lld -r test.o -o out.lld
> +
> +RUN: llvm-readobj --elf-section-groups -elf-output-style=GNU \
> +RUN: %p/Inputs/broken-group.obj.elf-x86_64 | FileCheck %s -check-prefix=GNU
> +GNU: COMDAT group section [ 2] `.group' [bar] contains 1 sections:
> +GNU-NEXT: [Index] Name
> +GNU-NEXT: [ 3] .foo
> +GNU: COMDAT group section [ 4] `.group' [zed] contains 1 sections:
> +GNU-NEXT: [Index] Name
> +GNU-NEXT: Error: section [ 3] in group section [ 4] already in group section [ 2]
> +
> +RUN: llvm-readobj --elf-section-groups \
> +RUN: %p/Inputs/broken-group.obj.elf-x86_64 | FileCheck %s -check-prefix=LLVM
> +LLVM: Groups {
> +LLVM-NEXT: Group {
> +LLVM-NEXT: Name: .group
> +LLVM-NEXT: Index: 2
> +LLVM-NEXT: Type: COMDAT
> +LLVM-NEXT: Signature: bar
> +LLVM-NEXT: Section(s) in group [
> +LLVM-NEXT: .foo (3)
> +LLVM-NEXT: ]
> +LLVM-NEXT: }
> +LLVM-NEXT: Group {
> +LLVM-NEXT: Name: .group
> +LLVM-NEXT: Index: 4
> +LLVM-NEXT: Type: COMDAT
> +LLVM-NEXT: Signature: zed
> +LLVM-NEXT: Section(s) in group [
> +LLVM-NEXT: Error: .foo (3) already in a group .group (2)
> +LLVM-NEXT: ]
> +LLVM-NEXT: }
> +LLVM-NEXT: }
More information about the llvm-commits
mailing list