diff --git a/llvm/test/tools/llvm-readobj/ELF/RISCV/stother.test b/llvm/test/tools/llvm-readobj/ELF/RISCV/stother.test --- a/llvm/test/tools/llvm-readobj/ELF/RISCV/stother.test +++ b/llvm/test/tools/llvm-readobj/ELF/RISCV/stother.test @@ -3,6 +3,7 @@ # RUN: yaml2obj %s -o %t.o # RUN: llvm-readobj -s %t.o | FileCheck %s --check-prefix=LLVM # RUN: llvm-readelf -s %t.o | FileCheck %s --check-prefix=GNU +# RUN: llvm-readobj -s %t.o --pretty-print --elf-output-style=JSON | FileCheck %s --check-prefix=JSON # LLVM: Name: foo1 # LLVM: Other [ (0x80) @@ -18,6 +19,44 @@ # LLVM-NEXT: STV_PROTECTED (0x3) # LLVM-NEXT: ] +# JSON: "Value": "foo1", +# JSON-NEXT: "RawValue": 11 +# JSON: "Other": { +# JSON-NEXT: "RawFlags": 128, +# JSON-NEXT: "Flags": [ +# JSON-NEXT: { +# JSON-NEXT: "Name": "STO_RISCV_VARIANT_CC", +# JSON-NEXT: "Value": 128 +# JSON-NEXT: } +# JSON-NEXT: ] +# JSON-NEXT: }, +# JSON: "Value": "foo2", +# JSON-NEXT: "RawValue": 6 +# JSON: "Other": { +# JSON-NEXT: "RawFlags": 192, +# JSON-NEXT: "Flags": [ +# JSON-NEXT: { +# JSON-NEXT: "Name": "STO_RISCV_VARIANT_CC", +# JSON-NEXT: "Value": 128 +# JSON-NEXT: } +# JSON-NEXT: ] +# JSON-NEXT: }, +# JSON: "Value": "foo3", +# JSON-NEXT: "RawValue": 1 +# JSON: "Other": { +# JSON-NEXT: "RawFlags": 131, +# JSON-NEXT: "Flags": [ +# JSON-NEXT: { +# JSON-NEXT: "Name": "STO_RISCV_VARIANT_CC", +# JSON-NEXT: "Value": 128 +# JSON-NEXT: }, +# JSON-NEXT: { +# JSON-NEXT: "Name": "STV_PROTECTED", +# JSON-NEXT: "Value": 3 +# JSON-NEXT: } +# JSON-NEXT: ] +# JSON-NEXT: }, + # GNU: Symbol table '.symtab' contains 4 entries: # GNU: 1: 0000000000000000 0 NOTYPE LOCAL DEFAULT [VARIANT_CC] UND foo1 # GNU-NEXT: 2: 0000000000000000 0 NOTYPE LOCAL DEFAULT [VARIANT_CC | 40] UND foo2 diff --git a/llvm/test/tools/llvm-readobj/ELF/aarch64-symbols-stother.test b/llvm/test/tools/llvm-readobj/ELF/aarch64-symbols-stother.test --- a/llvm/test/tools/llvm-readobj/ELF/aarch64-symbols-stother.test +++ b/llvm/test/tools/llvm-readobj/ELF/aarch64-symbols-stother.test @@ -2,6 +2,7 @@ # RUN: yaml2obj %s -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 # RUN: llvm-readelf --symbols %t.o | FileCheck %s --check-prefix=GNU # LLVM: Name: foo1 @@ -28,6 +29,51 @@ # GNU-NEXT: 3: 0000000000000000 0 NOTYPE LOCAL PROTECTED [VARIANT_PCS] UND foo3 # GNU-NEXT: 4: 0000000000000000 0 NOTYPE LOCAL PROTECTED UND foo4 +# JSON: "Other": { +# JSON-NEXT: "RawFlags": 0, +# JSON-NEXT: "Flags": [] +# JSON-NEXT: }, +# JSON: "Other": { +# JSON-NEXT: "RawFlags": 128, +# JSON-NEXT: "Flags": [ +# JSON-NEXT: { +# JSON-NEXT: "Name": "STO_AARCH64_VARIANT_PCS", +# JSON-NEXT: "Value": 128 +# JSON-NEXT: } +# JSON-NEXT: ] +# JSON-NEXT: }, +# JSON: "Other": { +# JSON-NEXT: "RawFlags": 192, +# JSON-NEXT: "Flags": [ +# JSON-NEXT: { +# JSON-NEXT: "Name": "STO_AARCH64_VARIANT_PCS", +# JSON-NEXT: "Value": 128 +# JSON-NEXT: } +# JSON-NEXT: ] +# JSON-NEXT: }, +# JSON: "Other": { +# JSON-NEXT: "RawFlags": 131, +# JSON-NEXT: "Flags": [ +# JSON-NEXT: { +# JSON-NEXT: "Name": "STO_AARCH64_VARIANT_PCS", +# JSON-NEXT: "Value": 128 +# JSON-NEXT: }, +# JSON-NEXT: { +# JSON-NEXT: "Name": "STV_PROTECTED", +# JSON-NEXT: "Value": 3 +# JSON-NEXT: } +# JSON-NEXT: ] +# JSON-NEXT: }, +# JSON: "Other": { +# JSON-NEXT: "RawFlags": 3, +# JSON-NEXT: "Flags": [ +# JSON-NEXT: { +# JSON-NEXT: "Name": "STV_PROTECTED", +# JSON-NEXT: "Value": 3 +# JSON-NEXT: } +# JSON-NEXT: ] +# JSON-NEXT: }, + --- !ELF FileHeader: Class: ELFCLASS64 diff --git a/llvm/test/tools/llvm-readobj/ELF/mips-symbols-stother.test b/llvm/test/tools/llvm-readobj/ELF/mips-symbols-stother.test --- a/llvm/test/tools/llvm-readobj/ELF/mips-symbols-stother.test +++ b/llvm/test/tools/llvm-readobj/ELF/mips-symbols-stother.test @@ -3,6 +3,7 @@ # RUN: yaml2obj %s -o %t.o # RUN: llvm-readobj --symbols %t.o | FileCheck %s --strict-whitespace --check-prefix=MIPS-LLVM # RUN: llvm-readelf --symbols %t.o | FileCheck %s --strict-whitespace --check-prefix=MIPS-GNU +# RUN: llvm-readobj --symbols %t.o --pretty-print --elf-output-style=JSON | FileCheck %s --strict-whitespace --check-prefix=MIPS-JSON # MIPS-LLVM:Name: foo # MIPS-LLVM:Other [ @@ -17,6 +18,41 @@ # MIPS-LLVM-NEXT: STO_MIPS_MIPS16 (0xF0) # MIPS-LLVM-NEXT:] +# MIPS-JSON: "Value": "foo", +# MIPS-JSON: "Other": { +# MIPS-JSON-NEXT: "RawFlags": 172, +# MIPS-JSON-NEXT: "Flags": [ +# MIPS-JSON-NEXT: { +# MIPS-JSON-NEXT: "Name": "STO_MIPS_MICROMIPS", +# MIPS-JSON-NEXT: "Value": 128 +# MIPS-JSON-NEXT: }, +# MIPS-JSON-NEXT: { +# MIPS-JSON-NEXT: "Name": "STO_MIPS_OPTIONAL", +# MIPS-JSON-NEXT: "Value": 4 +# MIPS-JSON-NEXT: }, +# MIPS-JSON-NEXT: { +# MIPS-JSON-NEXT: "Name": "STO_MIPS_PIC", +# MIPS-JSON-NEXT: "Value": 32 +# MIPS-JSON-NEXT: }, +# MIPS-JSON-NEXT: { +# MIPS-JSON-NEXT: "Name": "STO_MIPS_PLT", +# MIPS-JSON-NEXT: "Value": 8 +# MIPS-JSON-NEXT: } +# MIPS-JSON-NEXT: ] +# MIPS-JSON-NEXT: }, + +# MIPS-JSON: "Value": "bar", +# MIPS-JSON: "Other": { +# MIPS-JSON-NEXT: "RawFlags": 240, +# MIPS-JSON-NEXT: "Flags": [ +# MIPS-JSON-NEXT: { +# MIPS-JSON-NEXT: "Name": "STO_MIPS_MIPS16", +# MIPS-JSON-NEXT: "Value": 240 +# MIPS-JSON-NEXT: } +# MIPS-JSON-NEXT: ] +# MIPS-JSON-NEXT: }, + + # MIPS-GNU:Symbol table '.symtab' contains 3 entries: # MIPS-GNU-NEXT: Num: Value Size Type Bind Vis Ndx Name # MIPS-GNU-NEXT: 0: 00000000 0 NOTYPE LOCAL DEFAULT UND diff --git a/llvm/test/tools/llvm-readobj/ELF/sections-ext.test b/llvm/test/tools/llvm-readobj/ELF/sections-ext.test --- a/llvm/test/tools/llvm-readobj/ELF/sections-ext.test +++ b/llvm/test/tools/llvm-readobj/ELF/sections-ext.test @@ -8,6 +8,8 @@ # RUN: llvm-readobj --sections --section-symbols %t > %t.readobj-st-no-alias # RUN: diff %t.readobj-st %t.readobj-st-no-alias # RUN: FileCheck %s --input-file=%t.readobj-st --check-prefixes=ALL,ST +# RUN: llvm-readobj --pretty-print --sections --section-symbols --elf-output-style=JSON %t > %t.readobj-json +# RUN: FileCheck %s --input-file=%t.readobj-json --check-prefixes=JSON ## Test --section-relocations (--sr) displays relocations for each section. # RUN: llvm-readobj --sections --sr %t > %t.readobj-sr @@ -69,6 +71,10 @@ # ST-NEXT: Binding: Local (0x0) # ST-NEXT: Type: None (0x0) # ST-NEXT: Other: 0 +# JSON: "Other": { +# JSON-NEXT: "RawFlags": 0, +# JSON-NEXT: "Flags": [] +# JSON-NEXT: } # ST-NEXT: Section: .text (0x1) # ST-NEXT: } # ST-NEXT: ] diff --git a/llvm/test/tools/llvm-readobj/ELF/symbol-visibility.test b/llvm/test/tools/llvm-readobj/ELF/symbol-visibility.test --- a/llvm/test/tools/llvm-readobj/ELF/symbol-visibility.test +++ b/llvm/test/tools/llvm-readobj/ELF/symbol-visibility.test @@ -7,6 +7,7 @@ # RUN: yaml2obj --docnum=1 %s -o %t1.o # RUN: llvm-readobj --symbols %t1.o | FileCheck %s --check-prefix=LLVM # RUN: llvm-readelf --symbols %t1.o | FileCheck %s --strict-whitespace --check-prefix=GNU +# RUN: llvm-readelf --symbols --pretty-print --elf-output-style=JSON %t1.o | FileCheck %s --check-prefix=JSON # LLVM: Name: default # LLVM: Other: 0 @@ -30,6 +31,45 @@ # GNU-NEXT: HIDDEN UND hidden # GNU-NEXT: PROTECTED UND protected +# JSON: "Value": "default", +# JSON: "Other": { +# JSON-NEXT: "RawFlags": 0, +# JSON-NEXT: "Flags": [] +# JSON-NEXT: }, +# JSON: "Value": "internal", +# JSON-NEXT: "RawValue": 16 +# JSON: "Other": { +# JSON-NEXT: "RawFlags": 1, +# JSON-NEXT: "Flags": [ +# JSON-NEXT: { +# JSON-NEXT: "Name": "STV_INTERNAL", +# JSON-NEXT: "Value": 1 +# JSON-NEXT: } +# JSON-NEXT: ] +# JSON-NEXT: }, +# JSON: "Value": "hidden", +# JSON-NEXT: "RawValue": 9 +# JSON: "Other": { +# JSON-NEXT: "RawFlags": 2, +# JSON-NEXT: "Flags": [ +# JSON-NEXT: { +# JSON-NEXT: "Name": "STV_HIDDEN", +# JSON-NEXT: "Value": 2 +# JSON-NEXT: } +# JSON-NEXT: ] +# JSON-NEXT: }, +# JSON: "Value": "protected", +# JSON-NEXT: "RawValue": 25 +# JSON: "Other": { +# JSON-NEXT: "RawFlags": 3, +# JSON-NEXT: "Flags": [ +# JSON-NEXT: { +# JSON-NEXT: "Name": "STV_PROTECTED", +# JSON-NEXT: "Value": 3 +# JSON-NEXT: } +# JSON-NEXT: ] +# JSON-NEXT: }, + --- !ELF FileHeader: Class: ELFCLASS32 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 @@ -685,14 +685,14 @@ void printNotes() override; void printELFLinkerOptions() override; void printStackSizes() override; + void printSymbolSection(const Elf_Sym &Symbol, unsigned SymIndex, + DataRegion ShndxTable) const; private: void printRelrReloc(const Elf_Relr &R) override; void printRelRelaReloc(const Relocation &R, const RelSymbol &RelSym) override; - void printSymbolSection(const Elf_Sym &Symbol, unsigned SymIndex, - DataRegion ShndxTable) const; void printSymbol(const Elf_Sym &Symbol, unsigned SymIndex, DataRegion ShndxTable, Optional StrTable, bool IsDynamic, @@ -723,6 +723,11 @@ ArrayRef InputFilenames, const Archive *A) override; + void printSymbol(const Elf_Sym &Symbol, unsigned SymIndex, + DataRegion ShndxTable, + Optional StrTable, bool IsDynamic, + bool /*NonVisibilityBitsUsed*/) const override; + private: std::unique_ptr FileScope; }; @@ -7553,3 +7558,31 @@ std::string(formatv("{0}bit", 8 * Obj.getBytesInAddress()))); this->printLoadName(); } + +template +void JSONELFDumper::printSymbol(const Elf_Sym &Symbol, unsigned SymIndex, + DataRegion ShndxTable, + Optional StrTable, + bool IsDynamic, + bool /*NonVisibilityBitsUsed*/) const { + std::string FullSymbolName = this->getFullSymbolName( + Symbol, SymIndex, ShndxTable, StrTable, IsDynamic); + unsigned char SymbolType = Symbol.getType(); + ScopedPrinter &W = this->W; + + DictScope D(W, "Symbol"); + W.printNumber("Name", FullSymbolName, Symbol.st_name); + W.printHex("Value", Symbol.st_value); + W.printNumber("Size", Symbol.st_size); + W.printEnum("Binding", Symbol.getBinding(), makeArrayRef(ElfSymbolBindings)); + if (this->Obj.getHeader().e_machine == ELF::EM_AMDGPU && + SymbolType >= ELF::STT_LOOS && SymbolType < ELF::STT_HIOS) + W.printEnum("Type", SymbolType, makeArrayRef(AMDGPUSymbolTypes)); + else + W.printEnum("Type", SymbolType, makeArrayRef(ElfSymbolTypes)); + + std::vector> SymOtherFlags = + this->getOtherFlagsFromSymbol(this->Obj.getHeader(), Symbol); + W.printFlags("Other", Symbol.st_other, makeArrayRef(SymOtherFlags), 0x3u); + this->printSymbolSection(Symbol, SymIndex, ShndxTable); +}