diff --git a/llvm/test/tools/llvm-readobj/ELF/groups.test b/llvm/test/tools/llvm-readobj/ELF/groups.test --- a/llvm/test/tools/llvm-readobj/ELF/groups.test +++ b/llvm/test/tools/llvm-readobj/ELF/groups.test @@ -4,6 +4,7 @@ # RUN: yaml2obj %s -o %t.o # RUN: llvm-readobj -g %t.o | FileCheck %s # RUN: llvm-readobj --elf-section-groups %t.o | FileCheck %s +# RUN: llvm-readobj --elf-section-groups %t.o --elf-output-style=JSON --pretty-print | FileCheck %s --check-prefix=JSON # RUN: llvm-readelf -g %t.o | FileCheck --check-prefix=GNU %s # CHECK: Groups { @@ -41,6 +42,57 @@ # GNU-NEXT: [ 5] .text.bar # GNU-NEXT: [ 6] .rela.text.bar +# JSON: "Groups": { +# JSON-NEXT: "Group": { +# JSON-NEXT: "Name": { +# JSON-NEXT: "Name": ".group", +# JSON-NEXT: "Value": 16 +# JSON-NEXT: }, +# JSON-NEXT: "Index": 1, +# JSON-NEXT: "Link": 7, +# JSON-NEXT: "Info": 1, +# JSON-NEXT: "Type": { +# JSON-NEXT: "Name": "COMDAT", +# JSON-NEXT: "Value": 1 +# JSON-NEXT: }, +# JSON-NEXT: "Signature": "foo", +# JSON-NEXT: "GroupSections": [ +# JSON-NEXT: { +# JSON-NEXT: "Name": ".text.foo", +# JSON-NEXT: "Index": 3 +# JSON-NEXT: }, +# JSON-NEXT: { +# JSON-NEXT: "Name": ".rela.text.foo", +# JSON-NEXT: "Index": 4 +# JSON-NEXT: } +# JSON-NEXT: ] +# JSON-NEXT: }, +# JSON-NEXT: "Group": { +# JSON-NEXT: "Name": { +# JSON-NEXT: "Name": ".group1", +# JSON-NEXT: "Value": 64 +# JSON-NEXT: }, +# JSON-NEXT: "Index": 2, +# JSON-NEXT: "Link": 7, +# JSON-NEXT: "Info": 2, +# JSON-NEXT: "Type": { +# JSON-NEXT: "Name": "COMDAT", +# JSON-NEXT: "Value": 1 +# JSON-NEXT: }, +# JSON-NEXT: "Signature": "bar", +# JSON-NEXT: "GroupSections": [ +# JSON-NEXT: { +# JSON-NEXT: "Name": ".text.bar", +# JSON-NEXT: "Index": 5 +# JSON-NEXT: }, +# JSON-NEXT: { +# JSON-NEXT: "Name": ".rela.text.bar", +# JSON-NEXT: "Index": 6 +# JSON-NEXT: } +# JSON-NEXT: ] +# JSON-NEXT: } +# JSON-NEXT: } + --- !ELF FileHeader: Class: ELFCLASS64 diff --git a/llvm/test/tools/llvm-readobj/ELF/relocations.test b/llvm/test/tools/llvm-readobj/ELF/relocations.test --- a/llvm/test/tools/llvm-readobj/ELF/relocations.test +++ b/llvm/test/tools/llvm-readobj/ELF/relocations.test @@ -116,130 +116,140 @@ # RUN: llvm-readobj -r --expand-relocs %t64 --elf-output-style=JSON --pretty-print \ # RUN: | FileCheck %s --check-prefix=JSON-EXPAND-64 -# JSON-EXPAND-64: "Relocations": [Section (2) .rel.text { -# JSON-EXPAND-64: "Relocation": { -# JSON-EXPAND-64-NEXT: "Offset": 0, -# JSON-EXPAND-64-NEXT: "Type": { -# JSON-EXPAND-64-NEXT: "Name": "R_X86_64_NONE", -# JSON-EXPAND-64-NEXT: "Value": 0 +# JSON-EXPAND-64: "Relocations": [ +# JSON-EXPAND-64-NEXT: { +# JSON-EXPAND-64-NEXT: "SectionIndex": 2 +# JSON-EXPAND-64-NEXT: "Relocs": [ +# JSON-EXPAND-64-NEXT: { +# JSON-EXPAND-64-NEXT: "Relocation": { +# JSON-EXPAND-64-NEXT: "Offset": 0, +# JSON-EXPAND-64-NEXT: "Type": { +# JSON-EXPAND-64-NEXT: "Name": "R_X86_64_NONE", +# JSON-EXPAND-64-NEXT: "Value": 0 +# JSON-EXPAND-64-NEXT: }, +# JSON-EXPAND-64-NEXT: "Symbol": { +# JSON-EXPAND-64-NEXT: "Name": "rel_0", +# JSON-EXPAND-64-NEXT: "Value": 1 +# JSON-EXPAND-64-NEXT: } +# JSON-EXPAND-64-NEXT: } # JSON-EXPAND-64-NEXT: }, -# JSON-EXPAND-64-NEXT: "Symbol": { -# JSON-EXPAND-64-NEXT: "Name": "rel_0", -# JSON-EXPAND-64-NEXT: "Value": 1 -# JSON-EXPAND-64-NEXT: } -# JSON-EXPAND-64-NEXT: } -# JSON-EXPAND-64-NEXT: }, -# JSON-EXPAND-64-NEXT: { -# JSON-EXPAND-64-NEXT: "Relocation": { -# JSON-EXPAND-64-NEXT: "Offset": 1, -# JSON-EXPAND-64-NEXT: "Type": { -# JSON-EXPAND-64-NEXT: "Name": "R_X86_64_PC32", -# JSON-EXPAND-64-NEXT: "Value": 2 -# JSON-EXPAND-64-NEXT: }, -# JSON-EXPAND-64-NEXT: "Symbol": { -# JSON-EXPAND-64-NEXT: "Name": "rel_neg", -# JSON-EXPAND-64-NEXT: "Value": 2 -# JSON-EXPAND-64-NEXT: } -# JSON-EXPAND-64-NEXT: } -# JSON-EXPAND-64-NEXT: }, -# JSON-EXPAND-64-NEXT: { -# JSON-EXPAND-64-NEXT: "Relocation": { -# JSON-EXPAND-64-NEXT: "Offset": 5, -# JSON-EXPAND-64-NEXT: "Type": { -# JSON-EXPAND-64-NEXT: "Name": "R_X86_64_PLT32", -# JSON-EXPAND-64-NEXT: "Value": 4 +# JSON-EXPAND-64-NEXT: { +# JSON-EXPAND-64-NEXT: "Relocation": { +# JSON-EXPAND-64-NEXT: "Offset": 1, +# JSON-EXPAND-64-NEXT: "Type": { +# JSON-EXPAND-64-NEXT: "Name": "R_X86_64_PC32", +# JSON-EXPAND-64-NEXT: "Value": 2 +# JSON-EXPAND-64-NEXT: }, +# JSON-EXPAND-64-NEXT: "Symbol": { +# JSON-EXPAND-64-NEXT: "Name": "rel_neg", +# JSON-EXPAND-64-NEXT: "Value": 2 +# JSON-EXPAND-64-NEXT: } +# JSON-EXPAND-64-NEXT: } # JSON-EXPAND-64-NEXT: }, -# JSON-EXPAND-64-NEXT: "Symbol": { -# JSON-EXPAND-64-NEXT: "Name": "rel_pos", -# JSON-EXPAND-64-NEXT: "Value": 3 -# JSON-EXPAND-64-NEXT: } -# JSON-EXPAND-64-NEXT: } -# JSON-EXPAND-64-NEXT: }, -# JSON-EXPAND-64-NEXT: { -# JSON-EXPAND-64-NEXT: "Relocation": { -# JSON-EXPAND-64-NEXT: "Offset": 9, -# JSON-EXPAND-64-NEXT: "Type": { -# JSON-EXPAND-64-NEXT: "Name": "R_X86_64_64", -# JSON-EXPAND-64-NEXT: "Value": 1 +# JSON-EXPAND-64-NEXT: { +# JSON-EXPAND-64-NEXT: "Relocation": { +# JSON-EXPAND-64-NEXT: "Offset": 5, +# JSON-EXPAND-64-NEXT: "Type": { +# JSON-EXPAND-64-NEXT: "Name": "R_X86_64_PLT32", +# JSON-EXPAND-64-NEXT: "Value": 4 +# JSON-EXPAND-64-NEXT: }, +# JSON-EXPAND-64-NEXT: "Symbol": { +# JSON-EXPAND-64-NEXT: "Name": "rel_pos", +# JSON-EXPAND-64-NEXT: "Value": 3 +# JSON-EXPAND-64-NEXT: } +# JSON-EXPAND-64-NEXT: } # JSON-EXPAND-64-NEXT: }, -# JSON-EXPAND-64-NEXT: "Symbol": { -# JSON-EXPAND-64-NEXT: "Name": "rel_64", -# JSON-EXPAND-64-NEXT: "Value": 4 +# JSON-EXPAND-64-NEXT: { +# JSON-EXPAND-64-NEXT: "Relocation": { +# JSON-EXPAND-64-NEXT: "Offset": 9, +# JSON-EXPAND-64-NEXT: "Type": { +# JSON-EXPAND-64-NEXT: "Name": "R_X86_64_64", +# JSON-EXPAND-64-NEXT: "Value": 1 +# JSON-EXPAND-64-NEXT: }, +# JSON-EXPAND-64-NEXT: "Symbol": { +# JSON-EXPAND-64-NEXT: "Name": "rel_64", +# JSON-EXPAND-64-NEXT: "Value": 4 +# JSON-EXPAND-64-NEXT: } +# JSON-EXPAND-64-NEXT: } # JSON-EXPAND-64-NEXT: } -# JSON-EXPAND-64-NEXT: } -# JSON-EXPAND-64-NEXT: }} -# JSON-EXPAND-64-NEXT: Section (3) .rela.text { -# JSON-EXPAND-64-NEXT: , -# JSON-EXPAND-64-NEXT: { -# JSON-EXPAND-64-NEXT: "Relocation": { -# JSON-EXPAND-64-NEXT: "Offset": 0, -# JSON-EXPAND-64-NEXT: "Type": { -# JSON-EXPAND-64-NEXT: "Name": "R_X86_64_NONE", -# JSON-EXPAND-64-NEXT: "Value": 0 -# JSON-EXPAND-64-NEXT: }, -# JSON-EXPAND-64-NEXT: "Symbol": { -# JSON-EXPAND-64-NEXT: "Name": "rela_0", -# JSON-EXPAND-64-NEXT: "Value": 5 -# JSON-EXPAND-64-NEXT: }, -# JSON-EXPAND-64-NEXT: "Addend": 0 -# JSON-EXPAND-64-NEXT: } -# JSON-EXPAND-64-NEXT: }, -# JSON-EXPAND-64-NEXT: { -# JSON-EXPAND-64-NEXT: "Relocation": { -# JSON-EXPAND-64-NEXT: "Offset": 1, -# JSON-EXPAND-64-NEXT: "Type": { -# JSON-EXPAND-64-NEXT: "Name": "R_X86_64_PC32", -# JSON-EXPAND-64-NEXT: "Value": 2 +# JSON-EXPAND-64-NEXT: ] +# JSON-EXPAND-64-NEXT: }, +# JSON-EXPAND-64-NEXT: { +# JSON-EXPAND-64-NEXT: "SectionIndex": 3, +# JSON-EXPAND-64-NEXT: "Relocs": [ +# JSON-EXPAND-64-NEXT: { +# JSON-EXPAND-64-NEXT: "Relocation": { +# JSON-EXPAND-64-NEXT: "Offset": 0, +# JSON-EXPAND-64-NEXT: "Type": { +# JSON-EXPAND-64-NEXT: "Name": "R_X86_64_NONE", +# JSON-EXPAND-64-NEXT: "Value": 0 +# JSON-EXPAND-64-NEXT: }, +# JSON-EXPAND-64-NEXT: "Symbol": { +# JSON-EXPAND-64-NEXT: "Name": "rela_0", +# JSON-EXPAND-64-NEXT: "Value": 5 +# JSON-EXPAND-64-NEXT: }, +# JSON-EXPAND-64-NEXT: "Addend": 0 +# JSON-EXPAND-64-NEXT: } # JSON-EXPAND-64-NEXT: }, -# JSON-EXPAND-64-NEXT: "Symbol": { -# JSON-EXPAND-64-NEXT: "Name": "rela_neg", -# JSON-EXPAND-64-NEXT: "Value": 6 +# JSON-EXPAND-64-NEXT: { +# JSON-EXPAND-64-NEXT: "Relocation": { +# JSON-EXPAND-64-NEXT: "Offset": 1, +# JSON-EXPAND-64-NEXT: "Type": { +# JSON-EXPAND-64-NEXT: "Name": "R_X86_64_PC32", +# JSON-EXPAND-64-NEXT: "Value": 2 +# JSON-EXPAND-64-NEXT: }, +# JSON-EXPAND-64-NEXT: "Symbol": { +# JSON-EXPAND-64-NEXT: "Name": "rela_neg", +# JSON-EXPAND-64-NEXT: "Value": 6 +# JSON-EXPAND-64-NEXT: }, +# JSON-EXPAND-64-NEXT: "Addend": 18446744073709551615 +# JSON-EXPAND-64-NEXT: } # JSON-EXPAND-64-NEXT: }, -# JSON-EXPAND-64-NEXT: "Addend": 18446744073709551615 -# JSON-EXPAND-64-NEXT: } -# JSON-EXPAND-64-NEXT: }, -# JSON-EXPAND-64-NEXT: { -# JSON-EXPAND-64-NEXT: "Relocation": { -# JSON-EXPAND-64-NEXT: "Offset": 5, -# JSON-EXPAND-64-NEXT: "Type": { -# JSON-EXPAND-64-NEXT: "Name": "R_X86_64_PLT32", -# JSON-EXPAND-64-NEXT: "Value": 4 +# JSON-EXPAND-64-NEXT: { +# JSON-EXPAND-64-NEXT: "Relocation": { +# JSON-EXPAND-64-NEXT: "Offset": 5, +# JSON-EXPAND-64-NEXT: "Type": { +# JSON-EXPAND-64-NEXT: "Name": "R_X86_64_PLT32", +# JSON-EXPAND-64-NEXT: "Value": 4 +# JSON-EXPAND-64-NEXT: }, +# JSON-EXPAND-64-NEXT: "Symbol": { +# JSON-EXPAND-64-NEXT: "Name": "rela_pos", +# JSON-EXPAND-64-NEXT: "Value": 7 +# JSON-EXPAND-64-NEXT: }, +# JSON-EXPAND-64-NEXT: "Addend": 2 +# JSON-EXPAND-64-NEXT: } # JSON-EXPAND-64-NEXT: }, -# JSON-EXPAND-64-NEXT: "Symbol": { -# JSON-EXPAND-64-NEXT: "Name": "rela_pos", -# JSON-EXPAND-64-NEXT: "Value": 7 +# JSON-EXPAND-64-NEXT: { +# JSON-EXPAND-64-NEXT: "Relocation": { +# JSON-EXPAND-64-NEXT: "Offset": 18446744073709551615, +# JSON-EXPAND-64-NEXT: "Type": { +# JSON-EXPAND-64-NEXT: "Name": "R_X86_64_64", +# JSON-EXPAND-64-NEXT: "Value": 1 +# JSON-EXPAND-64-NEXT: }, +# JSON-EXPAND-64-NEXT: "Symbol": { +# JSON-EXPAND-64-NEXT: "Name": "rela_minneg", +# JSON-EXPAND-64-NEXT: "Value": 8 +# JSON-EXPAND-64-NEXT: }, +# JSON-EXPAND-64-NEXT: "Addend": 9223372036854775808 +# JSON-EXPAND-64-NEXT: } # JSON-EXPAND-64-NEXT: }, -# JSON-EXPAND-64-NEXT: "Addend": 2 -# JSON-EXPAND-64-NEXT: } -# JSON-EXPAND-64-NEXT: }, -# JSON-EXPAND-64-NEXT: { -# JSON-EXPAND-64-NEXT: "Relocation": { -# JSON-EXPAND-64-NEXT: "Offset": 18446744073709551615, -# JSON-EXPAND-64-NEXT: "Type": { -# JSON-EXPAND-64-NEXT: "Name": "R_X86_64_64", -# JSON-EXPAND-64-NEXT: "Value": 1 -# JSON-EXPAND-64-NEXT: }, -# JSON-EXPAND-64-NEXT: "Symbol": { -# JSON-EXPAND-64-NEXT: "Name": "rela_minneg", -# JSON-EXPAND-64-NEXT: "Value": 8 -# JSON-EXPAND-64-NEXT: }, -# JSON-EXPAND-64-NEXT: "Addend": 9223372036854775808 -# JSON-EXPAND-64-NEXT: } -# JSON-EXPAND-64-NEXT: }, -# JSON-EXPAND-64-NEXT: { -# JSON-EXPAND-64-NEXT: "Relocation": { -# JSON-EXPAND-64-NEXT: "Offset": 9, -# JSON-EXPAND-64-NEXT: "Type": { -# JSON-EXPAND-64-NEXT: "Name": "R_X86_64_32S", -# JSON-EXPAND-64-NEXT: "Value": 11 -# JSON-EXPAND-64-NEXT: }, -# JSON-EXPAND-64-NEXT: "Symbol": { -# JSON-EXPAND-64-NEXT: "Name": "rela_maxpos", -# JSON-EXPAND-64-NEXT: "Value": 9 -# JSON-EXPAND-64-NEXT: }, -# JSON-EXPAND-64-NEXT: "Addend": 9223372036854775807 -# JSON-EXPAND-64-NEXT: } -# JSON-EXPAND-64-NEXT: }} +# JSON-EXPAND-64-NEXT: { +# JSON-EXPAND-64-NEXT: "Relocation": { +# JSON-EXPAND-64-NEXT: "Offset": 9, +# JSON-EXPAND-64-NEXT: "Type": { +# JSON-EXPAND-64-NEXT: "Name": "R_X86_64_32S", +# JSON-EXPAND-64-NEXT: "Value": 11 +# JSON-EXPAND-64-NEXT: }, +# JSON-EXPAND-64-NEXT: "Symbol": { +# JSON-EXPAND-64-NEXT: "Name": "rela_maxpos", +# JSON-EXPAND-64-NEXT: "Value": 9 +# JSON-EXPAND-64-NEXT: }, +# JSON-EXPAND-64-NEXT: "Addend": 9223372036854775807 +# JSON-EXPAND-64-NEXT: } +# JSON-EXPAND-64-NEXT: } +# JSON-EXPAND-64-NEXT: ] +# JSON-EXPAND-64-NEXT: } +# JSON-EXPAND-64-NEXT: ] --- !ELF FileHeader: diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -725,6 +725,12 @@ virtual void printDefaultRelRelaReloc(const Relocation &R, const StringRef SymbolName, const StringRef RelocName); + virtual void printRelocationSectionInfo(const Elf_Shdr &Sec, const StringRef Name, + const unsigned SecNdx); + virtual void printEmptyGroupMessage() const; + virtual void printSectionGroupMembers(const StringRef Name, + uint64_t Idx) const; + virtual std::string getGroupSectionHeaderName() const; ScopedPrinter &W; }; @@ -747,6 +753,14 @@ const StringRef SymbolName, const StringRef RelocName) override; + void printRelocationSectionInfo(const Elf_Shdr &Sec, const StringRef Name, + const unsigned SecNdx) override; + void printEmptyGroupMessage() const override; + + void printSectionGroupMembers(const StringRef Name, + uint64_t Idx) const override; + std::string getGroupSectionHeaderName() const override; + private: std::unique_ptr FileScope; }; @@ -6738,9 +6752,9 @@ W.printNumber("Link", G.Link); W.printNumber("Info", G.Info); W.printHex("Type", getGroupType(G.Type), G.Type); - W.startLine() << "Signature: " << G.Signature << "\n"; + W.printString("Signature", G.Signature); - ListScope L(W, "Section(s) in group"); + ListScope L(W, getGroupSectionHeaderName()); for (const GroupMember &GM : G.Members) { const GroupSection *MainGroup = Map[GM.Index]; if (MainGroup != &G) @@ -6750,12 +6764,23 @@ Twine(MainGroup->Index) + ", was also found in the group section with index " + Twine(G.Index)); - W.startLine() << GM.Name << " (" << GM.Index << ")\n"; + printSectionGroupMembers(GM.Name, GM.Index); } } if (V.empty()) - W.startLine() << "There are no group sections in the file.\n"; + printEmptyGroupMessage(); +} + +template +void LLVMELFDumper::printSectionGroupMembers(const StringRef Name, + uint64_t Idx) const { + W.startLine() << Name << " (" << Idx << ")\n"; +} + +template +std::string LLVMELFDumper::getGroupSectionHeaderName() const { + return "Section(s) in group"; } template void LLVMELFDumper::printRelocations() { @@ -6767,11 +6792,7 @@ StringRef Name = this->getPrintableSectionName(Sec); unsigned SecNdx = &Sec - &cantFail(this->Obj.sections()).front(); - W.startLine() << "Section (" << SecNdx << ") " << Name << " {\n"; - W.indent(); - this->printRelocationsHelper(Sec); - W.unindent(); - W.startLine() << "}\n"; + printRelocationSectionInfo(Sec, Name, SecNdx); } } @@ -6804,6 +6825,18 @@ OS << "\n"; } +template +void LLVMELFDumper::printRelocationSectionInfo(const Elf_Shdr &Sec, + const StringRef Name, + const unsigned SecNdx) { + DictScope D(W,(Twine("Section (") + Twine(SecNdx) +") " + Name).str()); + this->printRelocationsHelper(Sec); +} + +template void LLVMELFDumper::printEmptyGroupMessage() const { + W.startLine() << "There are no group sections in the file.\n"; +} + template void LLVMELFDumper::printRelRelaReloc(const Relocation &R, const RelSymbol &RelSym) { @@ -7719,3 +7752,30 @@ const StringRef RelocName) { this->printExpandedRelRelaReloc(R, SymbolName, RelocName); } + +template +void JSONELFDumper::printRelocationSectionInfo(const Elf_Shdr &Sec, + const StringRef Name, + const unsigned SecNdx) { + DictScope Group(this->W); + this->W.printNumber("SectionIndex", SecNdx); + ListScope D(this->W, "Relocs"); + this->printRelocationsHelper(Sec); +} + +template void JSONELFDumper::printEmptyGroupMessage() const { + // JSON output does not need to print anything for empty groups +} + +template +void JSONELFDumper::printSectionGroupMembers(const StringRef Name, + uint64_t Idx) const { + DictScope Grp(this->W); + this->W.printString("Name", Name); + this->W.printNumber("Index", Idx); +} + +template +std::string JSONELFDumper::getGroupSectionHeaderName() const { + return "GroupSections"; +}