[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 14 09:47:59 PDT 2017
Can you check if readelf prints this to stderr or stdout and if its exit
status is 0 or 1?
Thanks,
Rafael
George Rimar via Phabricator <reviews at reviews.llvm.org> writes:
> grimar updated this revision to Diff 115184.
> grimar added a comment.
>
> - Rebased after r313236.
>
>
> https://reviews.llvm.org/D37567
>
> Files:
> 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"
> @@ -2489,18 +2490,38 @@
> }
> return Ret;
> }
> +
> +DenseMap<uint64_t, const GroupSection *>
> +mapSectionsToGroups(ArrayRef<GroupSection> Groups) {
> + DenseMap<uint64_t, const GroupSection *> Ret;
> + for (const GroupSection &G : Groups)
> + for (const GroupMember &GM : G.Members)
> + Ret.insert({GM.Index, &G});
> + return Ret;
> +}
> +
> } // namespace
>
> template <class ELFT> void GNUStyle<ELFT>::printGroupSections(const ELFO *Obj) {
> std::vector<GroupSection> V = getGroups<ELFT>(Obj);
> + DenseMap<uint64_t, const GroupSection *> Map = mapSectionsToGroups(V);
> for (const GroupSection &G : V) {
> OS << "\n"
> << getGroupType(G.Type) << " group section ["
> << format_decimal(G.Index, 5) << "] `" << G.Name << "' [" << G.Signature
> << "] contains " << G.Members.size() << " sections:\n"
> << " [Index] Name\n";
> - for (const GroupMember &GM : G.Members)
> + for (const GroupMember &GM : G.Members) {
> + const GroupSection *MainGroup = Map[GM.Index];
> + if (MainGroup != &G) {
> + OS << "Error: section [" << format_decimal(GM.Index, 5)
> + << "] in group section [" << format_decimal(G.Index, 5)
> + << "] already in group section ["
> + << format_decimal(MainGroup->Index, 5) << "]";
> + continue;
> + }
> OS << " [" << format_decimal(GM.Index, 5) << "] " << GM.Name << "\n";
> + }
> }
>
> if (V.empty())
> @@ -3525,16 +3546,25 @@
> void LLVMStyle<ELFT>::printGroupSections(const ELFO *Obj) {
> DictScope Lists(W, "Groups");
> std::vector<GroupSection> V = getGroups<ELFT>(Obj);
> + DenseMap<uint64_t, const GroupSection *> Map = mapSectionsToGroups(V);
> for (const GroupSection &G : V) {
> DictScope D(W, "Group");
> W.printNumber("Name", G.Name, G.ShName);
> W.printNumber("Index", G.Index);
> W.printHex("Type", getGroupType(G.Type), G.Type);
> W.startLine() << "Signature: " << G.Signature << "\n";
>
> ListScope L(W, "Section(s) in group");
> - for (const GroupMember &GM : G.Members)
> + for (const GroupMember &GM : G.Members) {
> + const GroupSection *MainGroup = Map[GM.Index];
> + if (MainGroup != &G) {
> + W.startLine() << "Error: " << GM.Name << " (" << GM.Index
> + << ") already in a group " + MainGroup->Name + " ("
> + << MainGroup->Index << ")\n";
> + continue;
> + }
> W.startLine() << GM.Name << " (" << GM.Index << ")\n";
> + }
> }
>
> if (V.empty())
> 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,73 @@
> +# RUN: yaml2obj %s -o %t.o
> +
> +# RUN: llvm-readobj --elf-section-groups -elf-output-style=GNU %t.o \
> +# RUN: | 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] `.group1' [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 %t.o \
> +# RUN: | 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: .group1
> +# 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: }
> +
> +!ELF
> +FileHeader:
> + Class: ELFCLASS64
> + Data: ELFDATA2LSB
> + Type: ET_REL
> + Machine: EM_X86_64
> +Sections:
> + - Name: .text
> + Type: SHT_PROGBITS
> + Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
> + AddressAlign: 0x0000000000000004
> + Content: ''
> + - Name: .group
> + Type: SHT_GROUP
> + Link: .symtab
> + AddressAlign: 0x0000000000000004
> + Info: bar
> + Members:
> + - SectionOrType: GRP_COMDAT
> + - SectionOrType: .foo
> + - Name: .foo
> + Type: SHT_PROGBITS
> + Flags: [ SHF_ALLOC, SHF_EXECINSTR, SHF_GROUP ]
> + AddressAlign: 0x0000000000000001
> + Content: ''
> + - Name: .group1
> + Type: SHT_GROUP
> + Link: .symtab
> + AddressAlign: 0x0000000000000004
> + Info: zed
> + Members:
> + - SectionOrType: GRP_COMDAT
> + - SectionOrType: .foo
> +Symbols:
> + Local:
> + - Name: bar
> + Section: .group
> + - Name: zed
> + Section: .group1
More information about the llvm-commits
mailing list