diff --git a/llvm/test/tools/llvm-readobj/ELF/llvm-vs-json-format.test b/llvm/test/tools/llvm-readobj/ELF/llvm-vs-json-format.test --- a/llvm/test/tools/llvm-readobj/ELF/llvm-vs-json-format.test +++ b/llvm/test/tools/llvm-readobj/ELF/llvm-vs-json-format.test @@ -3,7 +3,7 @@ # When the Other field is 0, the LLVM format prints the output differently, # JSON formatting should always be consistent. -# RUN: yaml2obj %s -o %t.o +# RUN: yaml2obj %s --docnum=1 -o %t.o # RUN: llvm-readobj --symbols %t.o | FileCheck %s --check-prefix=LLVM # RUN: llvm-readobj --symbols --pretty-print --elf-output-style=JSON %t.o | FileCheck %s --check-prefix=JSON @@ -39,7 +39,6 @@ # JSON-NEXT: "Flags": [] # JSON-NEXT: }, - --- !ELF FileHeader: Class: ELFCLASS64 @@ -51,3 +50,365 @@ Other: [ STO_AARCH64_VARIANT_PCS ] - Name: bar Other: [ ] + +## Show that even without --expand-relocs the JSON output is always expanded +## while the LLVM output does not expand + +# RUN: yaml2obj %s --docnum=2 -o %t64 +# RUN: llvm-readobj -r %t64 \ +# RUN: | FileCheck %s --check-prefix=LLVM-64 --strict-whitespace --match-full-lines +# RUN: llvm-readobj --relocations %t64 --elf-output-style=JSON --pretty-print \ +# RUN: | FileCheck %s --check-prefix=JSON-64 + +# LLVM-64:Relocations [ +# LLVM-64-NEXT: Section (2) .rel.text { +# LLVM-64-NEXT: 0x0 R_X86_64_NONE rel_0 +# LLVM-64-NEXT: 0x1 R_X86_64_PC32 rel_neg +# LLVM-64-NEXT: 0x5 R_X86_64_PLT32 rel_pos +# LLVM-64-NEXT: 0x9 R_X86_64_64 rel_64 +# LLVM-64-NEXT: } +# LLVM-64-NEXT: Section (3) .rela.text { +# LLVM-64-NEXT: 0x0 R_X86_64_NONE rela_0 0x0 +# LLVM-64-NEXT: 0x1 R_X86_64_PC32 rela_neg 0xFFFFFFFFFFFFFFFF +# LLVM-64-NEXT: 0x5 R_X86_64_PLT32 rela_pos 0x2 +# LLVM-64-NEXT: 0xFFFFFFFFFFFFFFFF R_X86_64_64 rela_minneg 0x8000000000000000 +# LLVM-64-NEXT: 0x9 R_X86_64_32S rela_maxpos 0x7FFFFFFFFFFFFFFF +# LLVM-64-NEXT: } +# LLVM-64-NEXT:] + +# JSON-64: "Relocations": [Section (2) .rel.text { +# JSON-64: { +# JSON-64-NEXT: "Relocation": { +# JSON-64-NEXT: "Offset": 0, +# JSON-64-NEXT: "Type": { +# JSON-64-NEXT: "Value": "R_X86_64_NONE", +# JSON-64-NEXT: "RawValue": 0 +# JSON-64-NEXT: }, +# JSON-64-NEXT: "Symbol": { +# JSON-64-NEXT: "Value": "rel_0", +# JSON-64-NEXT: "RawValue": 1 +# JSON-64-NEXT: } +# JSON-64-NEXT: } +# JSON-64-NEXT: }, +# JSON-64-NEXT: { +# JSON-64-NEXT: "Relocation": { +# JSON-64-NEXT: "Offset": 1, +# JSON-64-NEXT: "Type": { +# JSON-64-NEXT: "Value": "R_X86_64_PC32", +# JSON-64-NEXT: "RawValue": 2 +# JSON-64-NEXT: }, +# JSON-64-NEXT: "Symbol": { +# JSON-64-NEXT: "Value": "rel_neg", +# JSON-64-NEXT: "RawValue": 2 +# JSON-64-NEXT: } +# JSON-64-NEXT: } +# JSON-64-NEXT: }, +# JSON-64-NEXT: { +# JSON-64-NEXT: "Relocation": { +# JSON-64-NEXT: "Offset": 5, +# JSON-64-NEXT: "Type": { +# JSON-64-NEXT: "Value": "R_X86_64_PLT32", +# JSON-64-NEXT: "RawValue": 4 +# JSON-64-NEXT: }, +# JSON-64-NEXT: "Symbol": { +# JSON-64-NEXT: "Value": "rel_pos", +# JSON-64-NEXT: "RawValue": 3 +# JSON-64-NEXT: } +# JSON-64-NEXT: } +# JSON-64-NEXT: }, +# JSON-64-NEXT: { +# JSON-64-NEXT: "Relocation": { +# JSON-64-NEXT: "Offset": 9, +# JSON-64-NEXT: "Type": { +# JSON-64-NEXT: "Value": "R_X86_64_64", +# JSON-64-NEXT: "RawValue": 1 +# JSON-64-NEXT: }, +# JSON-64-NEXT: "Symbol": { +# JSON-64-NEXT: "Value": "rel_64", +# JSON-64-NEXT: "RawValue": 4 +# JSON-64-NEXT: } +# JSON-64-NEXT: } +# JSON-64-NEXT: }} +# JSON-64-NEXT: Section (3) .rela.text { +# JSON-64-NEXT: , +# JSON-64-NEXT: { +# JSON-64-NEXT: "Relocation": { +# JSON-64-NEXT: "Offset": 0, +# JSON-64-NEXT: "Type": { +# JSON-64-NEXT: "Value": "R_X86_64_NONE", +# JSON-64-NEXT: "RawValue": 0 +# JSON-64-NEXT: }, +# JSON-64-NEXT: "Symbol": { +# JSON-64-NEXT: "Value": "rela_0", +# JSON-64-NEXT: "RawValue": 5 +# JSON-64-NEXT: }, +# JSON-64-NEXT: "Addend": 0 +# JSON-64-NEXT: } +# JSON-64-NEXT: }, +# JSON-64-NEXT: { +# JSON-64-NEXT: "Relocation": { +# JSON-64-NEXT: "Offset": 1, +# JSON-64-NEXT: "Type": { +# JSON-64-NEXT: "Value": "R_X86_64_PC32", +# JSON-64-NEXT: "RawValue": 2 +# JSON-64-NEXT: }, +# JSON-64-NEXT: "Symbol": { +# JSON-64-NEXT: "Value": "rela_neg", +# JSON-64-NEXT: "RawValue": 6 +# JSON-64-NEXT: }, +# JSON-64-NEXT: "Addend": 18446744073709551615 +# JSON-64-NEXT: } +# JSON-64-NEXT: }, +# JSON-64-NEXT: { +# JSON-64-NEXT: "Relocation": { +# JSON-64-NEXT: "Offset": 5, +# JSON-64-NEXT: "Type": { +# JSON-64-NEXT: "Value": "R_X86_64_PLT32", +# JSON-64-NEXT: "RawValue": 4 +# JSON-64-NEXT: }, +# JSON-64-NEXT: "Symbol": { +# JSON-64-NEXT: "Value": "rela_pos", +# JSON-64-NEXT: "RawValue": 7 +# JSON-64-NEXT: }, +# JSON-64-NEXT: "Addend": 2 +# JSON-64-NEXT: } +# JSON-64-NEXT: }, +# JSON-64-NEXT: { +# JSON-64-NEXT: "Relocation": { +# JSON-64-NEXT: "Offset": 18446744073709551615, +# JSON-64-NEXT: "Type": { +# JSON-64-NEXT: "Value": "R_X86_64_64", +# JSON-64-NEXT: "RawValue": 1 +# JSON-64-NEXT: }, +# JSON-64-NEXT: "Symbol": { +# JSON-64-NEXT: "Value": "rela_minneg", +# JSON-64-NEXT: "RawValue": 8 +# JSON-64-NEXT: }, +# JSON-64-NEXT: "Addend": 9223372036854775808 +# JSON-64-NEXT: } +# JSON-64-NEXT: }, +# JSON-64-NEXT: { +# JSON-64-NEXT: "Relocation": { +# JSON-64-NEXT: "Offset": 9, +# JSON-64-NEXT: "Type": { +# JSON-64-NEXT: "Value": "R_X86_64_32S", +# JSON-64-NEXT: "RawValue": 11 +# JSON-64-NEXT: }, +# JSON-64-NEXT: "Symbol": { +# JSON-64-NEXT: "Value": "rela_maxpos", +# JSON-64-NEXT: "RawValue": 9 +# JSON-64-NEXT: }, +# JSON-64-NEXT: "Addend": 9223372036854775807 +# JSON-64-NEXT: } +# JSON-64-NEXT: }} +# JSON-64: ] + +## Show that --expand-relocs expands the relocation dump for LLVM style but +## the JSON output is always expanded + +# RUN: llvm-readobj -r --expand-relocs %t64 \ +# RUN: | FileCheck %s --check-prefix=LLVM-EXPAND-64 --match-full-lines --strict-whitespace +# RUN: llvm-readobj -r --expand-relocs %t64 --elf-output-style=JSON --pretty-print \ +# RUN: | FileCheck %s --check-prefix=JSON-64 + +# LLVM-EXPAND-64:Relocations [ +# LLVM-EXPAND-64-NEXT: Section (2) .rel.text { +# LLVM-EXPAND-64-NEXT: Relocation { +# LLVM-EXPAND-64-NEXT: Offset: 0x0 +# LLVM-EXPAND-64-NEXT: Type: R_X86_64_NONE (0) +# LLVM-EXPAND-64-NEXT: Symbol: rel_0 (1) +# LLVM-EXPAND-64-NEXT: } +# LLVM-EXPAND-64-NEXT: Relocation { +# LLVM-EXPAND-64-NEXT: Offset: 0x1 +# LLVM-EXPAND-64-NEXT: Type: R_X86_64_PC32 (2) +# LLVM-EXPAND-64-NEXT: Symbol: rel_neg (2) +# LLVM-EXPAND-64-NEXT: } +# LLVM-EXPAND-64-NEXT: Relocation { +# LLVM-EXPAND-64-NEXT: Offset: 0x5 +# LLVM-EXPAND-64-NEXT: Type: R_X86_64_PLT32 (4) +# LLVM-EXPAND-64-NEXT: Symbol: rel_pos (3) +# LLVM-EXPAND-64-NEXT: } +# LLVM-EXPAND-64-NEXT: Relocation { +# LLVM-EXPAND-64-NEXT: Offset: 0x9 +# LLVM-EXPAND-64-NEXT: Type: R_X86_64_64 (1) +# LLVM-EXPAND-64-NEXT: Symbol: rel_64 (4) +# LLVM-EXPAND-64-NEXT: } +# LLVM-EXPAND-64-NEXT: } +# LLVM-EXPAND-64-NEXT: Section (3) .rela.text { +# LLVM-EXPAND-64-NEXT: Relocation { +# LLVM-EXPAND-64-NEXT: Offset: 0x0 +# LLVM-EXPAND-64-NEXT: Type: R_X86_64_NONE (0) +# LLVM-EXPAND-64-NEXT: Symbol: rela_0 (5) +# LLVM-EXPAND-64-NEXT: Addend: 0x0 +# LLVM-EXPAND-64-NEXT: } +# LLVM-EXPAND-64-NEXT: Relocation { +# LLVM-EXPAND-64-NEXT: Offset: 0x1 +# LLVM-EXPAND-64-NEXT: Type: R_X86_64_PC32 (2) +# LLVM-EXPAND-64-NEXT: Symbol: rela_neg (6) +# LLVM-EXPAND-64-NEXT: Addend: 0xFFFFFFFFFFFFFFFF +# LLVM-EXPAND-64-NEXT: } +# LLVM-EXPAND-64-NEXT: Relocation { +# LLVM-EXPAND-64-NEXT: Offset: 0x5 +# LLVM-EXPAND-64-NEXT: Type: R_X86_64_PLT32 (4) +# LLVM-EXPAND-64-NEXT: Symbol: rela_pos (7) +# LLVM-EXPAND-64-NEXT: Addend: 0x2 +# LLVM-EXPAND-64-NEXT: } +# LLVM-EXPAND-64-NEXT: Relocation { +# LLVM-EXPAND-64-NEXT: Offset: 0xFFFFFFFFFFFFFFFF +# LLVM-EXPAND-64-NEXT: Type: R_X86_64_64 (1) +# LLVM-EXPAND-64-NEXT: Symbol: rela_minneg (8) +# LLVM-EXPAND-64-NEXT: Addend: 0x8000000000000000 +# LLVM-EXPAND-64-NEXT: } +# LLVM-EXPAND-64-NEXT: Relocation { +# LLVM-EXPAND-64-NEXT: Offset: 0x9 +# LLVM-EXPAND-64-NEXT: Type: R_X86_64_32S (11) +# LLVM-EXPAND-64-NEXT: Symbol: rela_maxpos (9) +# LLVM-EXPAND-64-NEXT: Addend: 0x7FFFFFFFFFFFFFFF +# LLVM-EXPAND-64-NEXT: } +# LLVM-EXPAND-64-NEXT: } +# LLVM-EXPAND-64-NEXT:] + + +# JSON-EXPAND-64:Relocations [ +# JSON-EXPAND-64-NEXT: Section (2) .rel.text { +# JSON-EXPAND-64-NEXT: Relocation { +# JSON-EXPAND-64-NEXT: Offset: 0x0 +# JSON-EXPAND-64-NEXT: Type: R_X86_64_NONE (0) +# JSON-EXPAND-64-NEXT: Symbol: rel_0 (1) +# JSON-EXPAND-64-NEXT: } +# JSON-EXPAND-64-NEXT: Relocation { +# JSON-EXPAND-64-NEXT: Offset: 0x1 +# JSON-EXPAND-64-NEXT: Type: R_X86_64_PC32 (2) +# JSON-EXPAND-64-NEXT: Symbol: rel_neg (2) +# JSON-EXPAND-64-NEXT: } +# JSON-EXPAND-64-NEXT: Relocation { +# JSON-EXPAND-64-NEXT: Offset: 0x5 +# JSON-EXPAND-64-NEXT: Type: R_X86_64_PLT32 (4) +# JSON-EXPAND-64-NEXT: Symbol: rel_pos (3) +# JSON-EXPAND-64-NEXT: } +# JSON-EXPAND-64-NEXT: Relocation { +# JSON-EXPAND-64-NEXT: Offset: 0x9 +# JSON-EXPAND-64-NEXT: Type: R_X86_64_64 (1) +# JSON-EXPAND-64-NEXT: Symbol: rel_64 (4) +# JSON-EXPAND-64-NEXT: } +# JSON-EXPAND-64-NEXT: } +# JSON-EXPAND-64-NEXT: Section (3) .rela.text { +# JSON-EXPAND-64-NEXT: Relocation { +# JSON-EXPAND-64-NEXT: Offset: 0x0 +# JSON-EXPAND-64-NEXT: Type: R_X86_64_NONE (0) +# JSON-EXPAND-64-NEXT: Symbol: rela_0 (5) +# JSON-EXPAND-64-NEXT: Addend: 0x0 +# JSON-EXPAND-64-NEXT: } +# JSON-EXPAND-64-NEXT: Relocation { +# JSON-EXPAND-64-NEXT: Offset: 0x1 +# JSON-EXPAND-64-NEXT: Type: R_X86_64_PC32 (2) +# JSON-EXPAND-64-NEXT: Symbol: rela_neg (6) +# JSON-EXPAND-64-NEXT: Addend: 0xFFFFFFFFFFFFFFFF +# JSON-EXPAND-64-NEXT: } +# JSON-EXPAND-64-NEXT: Relocation { +# JSON-EXPAND-64-NEXT: Offset: 0x5 +# JSON-EXPAND-64-NEXT: Type: R_X86_64_PLT32 (4) +# JSON-EXPAND-64-NEXT: Symbol: rela_pos (7) +# JSON-EXPAND-64-NEXT: Addend: 0x2 +# JSON-EXPAND-64-NEXT: } +# JSON-EXPAND-64-NEXT: Relocation { +# JSON-EXPAND-64-NEXT: Offset: 0xFFFFFFFFFFFFFFFF +# JSON-EXPAND-64-NEXT: Type: R_X86_64_64 (1) +# JSON-EXPAND-64-NEXT: Symbol: rela_minneg (8) +# JSON-EXPAND-64-NEXT: Addend: 0x8000000000000000 +# JSON-EXPAND-64-NEXT: } +# JSON-EXPAND-64-NEXT: Relocation { +# JSON-EXPAND-64-NEXT: Offset: 0x9 +# JSON-EXPAND-64-NEXT: Type: R_X86_64_32S (11) +# JSON-EXPAND-64-NEXT: Symbol: rela_maxpos (9) +# JSON-EXPAND-64-NEXT: Addend: 0x7FFFFFFFFFFFFFFF +# JSON-EXPAND-64-NEXT: } +# JSON-EXPAND-64-NEXT: } +# JSON-EXPAND-64-NEXT:] + + + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name: .text + Type: SHT_PROGBITS + Content: '00FFFFFFFF020000001234567890ABCDEF' + - Name: .rel.text + Type: SHT_REL + Info: .text + Link: [[LINK=.symtab]] + ShName: [[SHNAME=]] + EntSize: [[ENTSIZEREL=]] + Relocations: + - Symbol: rel_0 + Type: R_X86_64_NONE + - Offset: 0x1 + Symbol: rel_neg + Type: R_X86_64_PC32 + - Offset: 0x5 + Symbol: rel_pos + Type: R_X86_64_PLT32 + - Offset: 0x9 + Symbol: rel_64 + Type: R_X86_64_64 + - Name: .rela.text + Type: SHT_RELA + Info: .text + Link: [[LINK=.symtab]] + ShName: [[SHNAME=]] + EntSize: [[ENTSIZERELA=]] + Relocations: + - Symbol: rela_0 + Type: R_X86_64_NONE + Addend: 0 + - Offset: 0x1 + Symbol: rela_neg + Type: R_X86_64_PC32 + Addend: -1 + - Offset: 0x5 + Symbol: rela_pos + Type: R_X86_64_PLT32 + Addend: 2 + - Offset: 0xFFFFFFFFFFFFFFFF + Symbol: rela_minneg + Type: R_X86_64_64 + Addend: -9223372036854775808 ## Min 64-bit signed. + - Offset: 0x9 + Symbol: rela_maxpos + Type: R_X86_64_32S + Addend: 9223372036854775807 ## Max 64-bit signed. +Symbols: + - Name: rel_0 + Section: .text + Value: 0 + - Name: rel_neg + Section: .text + Value: 1 + - Name: rel_pos + Section: .text + Value: 2 + - Name: rel_64 + Section: .text + Value: 0xFFFFFFFFFFFFFFFF + - Name: rela_0 + Section: .text + Value: 0 + - Name: rela_neg + Section: .text + Value: 1 + - Name: rela_pos + Section: .text + Value: 2 + - Name: rela_minneg + Section: .text + Value: 3 + - Name: rela_maxpos + Section: .text + Value: 0xFFFFFFFFFFFFFFFF + + 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 @@ -710,6 +710,13 @@ protected: void printSymbolOtherField(const Elf_Sym &Symbol) const; + virtual void printExpandedRelRelaReloc(const Relocation &R, + const StringRef SymbolName, + const StringRef RelocName); + virtual void printDefaultRelRelaReloc(const Relocation &R, + const StringRef SymbolName, + const StringRef RelocName); + ScopedPrinter &W; }; @@ -727,6 +734,10 @@ const Archive *A) override; virtual void printZeroSymbolOtherField(const Elf_Sym &Symbol) const override; + void printDefaultRelRelaReloc(const Relocation &R, + const StringRef SymbolName, + const StringRef RelocName) override; + private: std::unique_ptr FileScope; }; @@ -6676,6 +6687,29 @@ W.startLine() << W.hex(R) << "\n"; } +template +void LLVMELFDumper::printExpandedRelRelaReloc( + const Relocation &R, const StringRef SymbolName, const StringRef RelocName) { + DictScope Group(W, "Relocation"); + W.printHex("Offset", R.Offset); + W.printNumber("Type", RelocName, R.Type); + W.printNumber("Symbol", !SymbolName.empty() ? SymbolName : "-", R.Symbol); + if (R.Addend) + W.printHex("Addend", (uintX_t)*R.Addend); +} + +template +void LLVMELFDumper::printDefaultRelRelaReloc(const Relocation &R, + const StringRef SymbolName, + const StringRef RelocName) { + raw_ostream &OS = W.startLine(); + OS << W.hex(R.Offset) << " " << RelocName << " " + << (!SymbolName.empty() ? SymbolName : "-"); + if (R.Addend) + OS << " " << W.hex((uintX_t)*R.Addend); + OS << "\n"; +} + template void LLVMELFDumper::printRelRelaReloc(const Relocation &R, const RelSymbol &RelSym) { @@ -6684,19 +6718,9 @@ this->Obj.getRelocationTypeName(R.Type, RelocName); if (opts::ExpandRelocs) { - DictScope Group(W, "Relocation"); - W.printHex("Offset", R.Offset); - W.printNumber("Type", RelocName, R.Type); - W.printNumber("Symbol", !SymbolName.empty() ? SymbolName : "-", R.Symbol); - if (R.Addend) - W.printHex("Addend", (uintX_t)*R.Addend); + printExpandedRelRelaReloc(R, SymbolName, RelocName); } else { - raw_ostream &OS = W.startLine(); - OS << W.hex(R.Offset) << " " << RelocName << " " - << (!SymbolName.empty() ? SymbolName : "-"); - if (R.Addend) - OS << " " << W.hex((uintX_t)*R.Addend); - OS << "\n"; + printDefaultRelRelaReloc(R, SymbolName, RelocName); } } @@ -7576,3 +7600,9 @@ this->printSymbolOtherField(Symbol); } +template +void JSONELFDumper::printDefaultRelRelaReloc( + const Relocation &R, const StringRef SymbolName, const StringRef RelocName) { + this->printExpandedRelRelaReloc(R, SymbolName, RelocName); +} +