aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFred Grim <fgrim@apple.com>2024-06-24 11:25:18 -0700
committerGitHub <noreply@github.com>2024-06-24 11:25:18 -0700
commit0ab81986be7c2df8dc784e9e950c906274b51fd4 (patch)
treed82c43884dae95b30ae7d690b3004f7f332b1ff5
parent962d7ac7fcdf6f0cb43e36dec2a6a67cadd7c46c (diff)
downloadllvm-0ab81986be7c2df8dc784e9e950c906274b51fd4.zip
llvm-0ab81986be7c2df8dc784e9e950c906274b51fd4.tar.gz
llvm-0ab81986be7c2df8dc784e9e950c906274b51fd4.tar.bz2
[llvm-readobj][ELF] Implement JSON output for --dynamic-table (#95976)
When printing JSON output with --dynamic-table I noticed that the output is invalid JSON. This patch overrides the printDynamicTable() function in the JSONELFDumper to return a list of dictionaries for the DynamicSection value. Before the output was: ``` { "FileSummary": { "File": "bin/llvm-readelf", "Format": "elf64-x86-64", "Arch": "x86_64", "AddressSize": "64bit", "LoadName": "<Not found>" }DynamicSection [ (35 entries) Tag Type Name/Value 0x000000000000001D RUNPATH Library runpath: [$ORIGIN/../lib:] 0x0000000000000001 NEEDED Shared library: [libm.so.6] 0x0000000000000001 NEEDED Shared library: [libz.so.1] 0x0000000000000001 NEEDED Shared library: [libzstd.so.1] ``` Now the output looks like: ``` "DynamicSection": [ { "Tag": 29, "Type": "RUNPATH", "Value": 6322, "Path": [ "$ORIGIN/../lib" ] }, { "Tag": 1, "Type": "NEEDED", "Value": 6109, "Library": "libm.so.6" }, ```
-rw-r--r--llvm/test/tools/llvm-readobj/ELF/dynamic-tags.test357
-rw-r--r--llvm/tools/llvm-readobj/ELFDumper.cpp61
2 files changed, 418 insertions, 0 deletions
diff --git a/llvm/test/tools/llvm-readobj/ELF/dynamic-tags.test b/llvm/test/tools/llvm-readobj/ELF/dynamic-tags.test
index 5610ed8..d05eed0 100644
--- a/llvm/test/tools/llvm-readobj/ELF/dynamic-tags.test
+++ b/llvm/test/tools/llvm-readobj/ELF/dynamic-tags.test
@@ -8,6 +8,8 @@
# RUN: llvm-readelf --dynamic-table %t1 \
# RUN: | FileCheck %s --strict-whitespace --match-full-lines --check-prefix=GNU64
# RUN: llvm-readelf -d %t1 | FileCheck %s --check-prefix=GNU64
+# RUN: llvm-readelf --dynamic-table --pretty-print --elf-output-style=JSON %t1 \
+# RUN: | FileCheck %s --strict-whitespace --check-prefix=JSON64
# LLVM64:DynamicSection [ (61 entries)
# LLVM64-NEXT: Tag Type Name/Value
@@ -138,6 +140,361 @@
# GNU64-NEXT: 0x0000000076543210 (<unknown:>0x76543210) 0x5555666677778888
# GNU64-NEXT: 0x0000000000000000 (NULL) 0x0
+# JSON64:"DynamicSection": [
+# JSON64-NEXT: {
+# JSON64-NEXT: "Tag": 1,
+# JSON64-NEXT: "Type": "NEEDED",
+# JSON64-NEXT: "Value": 1,
+# JSON64-NEXT: "Library": "D"
+# JSON64-NEXT: },
+# JSON64-NEXT: {
+# JSON64-NEXT: "Tag": 2,
+# JSON64-NEXT: "Type": "PLTRELSZ",
+# JSON64-NEXT: "Value": 16
+# JSON64-NEXT: },
+# JSON64-NEXT: {
+# JSON64-NEXT: "Tag": 3,
+# JSON64-NEXT: "Type": "PLTGOT",
+# JSON64-NEXT: "Value": 4096
+# JSON64-NEXT: },
+# JSON64-NEXT: {
+# JSON64-NEXT: "Tag": 4,
+# JSON64-NEXT: "Type": "HASH",
+# JSON64-NEXT: "Value": 4096
+# JSON64-NEXT: },
+# JSON64-NEXT: {
+# JSON64-NEXT: "Tag": 5,
+# JSON64-NEXT: "Type": "STRTAB",
+# JSON64-NEXT: "Value": 4096
+# JSON64-NEXT: },
+# JSON64-NEXT: {
+# JSON64-NEXT: "Tag": 6,
+# JSON64-NEXT: "Type": "SYMTAB",
+# JSON64-NEXT: "Value": 4096
+# JSON64-NEXT: },
+# JSON64-NEXT: {
+# JSON64-NEXT: "Tag": 7,
+# JSON64-NEXT: "Type": "RELA",
+# JSON64-NEXT: "Value": 4096
+# JSON64-NEXT: },
+# JSON64-NEXT: {
+# JSON64-NEXT: "Tag": 8,
+# JSON64-NEXT: "Type": "RELASZ",
+# JSON64-NEXT: "Value": 16
+# JSON64-NEXT: },
+# JSON64-NEXT: {
+# JSON64-NEXT: "Tag": 9,
+# JSON64-NEXT: "Type": "RELAENT",
+# JSON64-NEXT: "Value": 1929
+# JSON64-NEXT: },
+# JSON64-NEXT: {
+# JSON64-NEXT: "Tag": 10,
+# JSON64-NEXT: "Type": "STRSZ",
+# JSON64-NEXT: "Value": 16
+# JSON64-NEXT: },
+# JSON64-NEXT: {
+# JSON64-NEXT: "Tag": 11,
+# JSON64-NEXT: "Type": "SYMENT",
+# JSON64-NEXT: "Value": 2439
+# JSON64-NEXT: },
+# JSON64-NEXT: {
+# JSON64-NEXT: "Tag": 12,
+# JSON64-NEXT: "Type": "INIT",
+# JSON64-NEXT: "Value": 4096
+# JSON64-NEXT: },
+# JSON64-NEXT: {
+# JSON64-NEXT: "Tag": 13,
+# JSON64-NEXT: "Type": "FINI",
+# JSON64-NEXT: "Value": 4096
+# JSON64-NEXT: },
+# JSON64-NEXT: {
+# JSON64-NEXT: "Tag": 14,
+# JSON64-NEXT: "Type": "SONAME",
+# JSON64-NEXT: "Value": 3,
+# JSON64-NEXT: "Name": "U"
+# JSON64-NEXT: },
+# JSON64-NEXT: {
+# JSON64-NEXT: "Tag": 15,
+# JSON64-NEXT: "Type": "RPATH",
+# JSON64-NEXT: "Value": 5,
+# JSON64-NEXT: "Path": [
+# JSON64-NEXT: "f"
+# JSON64-NEXT: ]
+# JSON64-NEXT: },
+# JSON64-NEXT: {
+# JSON64-NEXT: "Tag": 16,
+# JSON64-NEXT: "Type": "SYMBOLIC",
+# JSON64-NEXT: "Value": 1311768467294899695
+# JSON64-NEXT: },
+# JSON64-NEXT: {
+# JSON64-NEXT: "Tag": 17,
+# JSON64-NEXT: "Type": "REL",
+# JSON64-NEXT: "Value": 4096
+# JSON64-NEXT: },
+# JSON64-NEXT: {
+# JSON64-NEXT: "Tag": 18,
+# JSON64-NEXT: "Type": "RELSZ",
+# JSON64-NEXT: "Value": 16
+# JSON64-NEXT: },
+# JSON64-NEXT: {
+# JSON64-NEXT: "Tag": 19,
+# JSON64-NEXT: "Type": "RELENT",
+# JSON64-NEXT: "Value": 291
+# JSON64-NEXT: },
+# JSON64-NEXT: {
+# JSON64-NEXT: "Tag": 20,
+# JSON64-NEXT: "Type": "PLTREL",
+# JSON64-NEXT: "Value": 7
+# JSON64-NEXT: },
+# JSON64-NEXT: {
+# JSON64-NEXT: "Tag": 21,
+# JSON64-NEXT: "Type": "DEBUG",
+# JSON64-NEXT: "Value": 18364757930599072545
+# JSON64-NEXT: },
+# JSON64-NEXT: {
+# JSON64-NEXT: "Tag": 22,
+# JSON64-NEXT: "Type": "TEXTREL",
+# JSON64-NEXT: "Value": 1234605616436508552
+# JSON64-NEXT: },
+# JSON64-NEXT: {
+# JSON64-NEXT: "Tag": 23,
+# JSON64-NEXT: "Type": "JMPREL",
+# JSON64-NEXT: "Value": 4096
+# JSON64-NEXT: },
+# JSON64-NEXT: {
+# JSON64-NEXT: "Tag": 24,
+# JSON64-NEXT: "Type": "BIND_NOW",
+# JSON64-NEXT: "Value": 9833440827789222417
+# JSON64-NEXT: },
+# JSON64-NEXT: {
+# JSON64-NEXT: "Tag": 25,
+# JSON64-NEXT: "Type": "INIT_ARRAY",
+# JSON64-NEXT: "Value": 4096
+# JSON64-NEXT: },
+# JSON64-NEXT: {
+# JSON64-NEXT: "Tag": 26,
+# JSON64-NEXT: "Type": "FINI_ARRAY",
+# JSON64-NEXT: "Value": 4096
+# JSON64-NEXT: },
+# JSON64-NEXT: {
+# JSON64-NEXT: "Tag": 27,
+# JSON64-NEXT: "Type": "INIT_ARRAYSZ",
+# JSON64-NEXT: "Value": 16
+# JSON64-NEXT: },
+# JSON64-NEXT: {
+# JSON64-NEXT: "Tag": 28,
+# JSON64-NEXT: "Type": "FINI_ARRAYSZ",
+# JSON64-NEXT: "Value": 16
+# JSON64-NEXT: },
+# JSON64-NEXT: {
+# JSON64-NEXT: "Tag": 29,
+# JSON64-NEXT: "Type": "RUNPATH",
+# JSON64-NEXT: "Value": 7,
+# JSON64-NEXT: "Path": [
+# JSON64-NEXT: "w"
+# JSON64-NEXT: ]
+# JSON64-NEXT: },
+# JSON64-NEXT: {
+# JSON64-NEXT: "Tag": 30,
+# JSON64-NEXT: "Type": "FLAGS",
+# JSON64-NEXT: "Value": 18446744073709551615,
+# JSON64-NEXT: "Flags": [
+# JSON64-NEXT: "ORIGIN",
+# JSON64-NEXT: "SYMBOLIC",
+# JSON64-NEXT: "TEXTREL",
+# JSON64-NEXT: "BIND_NOW",
+# JSON64-NEXT: "STATIC_TLS"
+# JSON64-NEXT: ]
+# JSON64-NEXT: },
+# JSON64-NEXT: {
+# JSON64-NEXT: "Tag": 32,
+# JSON64-NEXT: "Type": "PREINIT_ARRAY",
+# JSON64-NEXT: "Value": 4096
+# JSON64-NEXT: },
+# JSON64-NEXT: {
+# JSON64-NEXT: "Tag": 33,
+# JSON64-NEXT: "Type": "PREINIT_ARRAYSZ",
+# JSON64-NEXT: "Value": 16
+# JSON64-NEXT: },
+# JSON64-NEXT: {
+# JSON64-NEXT: "Tag": 34,
+# JSON64-NEXT: "Type": "SYMTAB_SHNDX",
+# JSON64-NEXT: "Value": 4096
+# JSON64-NEXT: },
+# JSON64-NEXT: {
+# JSON64-NEXT: "Tag": 35,
+# JSON64-NEXT: "Type": "RELRSZ",
+# JSON64-NEXT: "Value": 16
+# JSON64-NEXT: },
+# JSON64-NEXT: {
+# JSON64-NEXT: "Tag": 36,
+# JSON64-NEXT: "Type": "RELR",
+# JSON64-NEXT: "Value": 4096
+# JSON64-NEXT: },
+# JSON64-NEXT: {
+# JSON64-NEXT: "Tag": 37,
+# JSON64-NEXT: "Type": "RELRENT",
+# JSON64-NEXT: "Value": 17185
+# JSON64-NEXT: },
+# JSON64-NEXT: {
+# JSON64-NEXT: "Tag": 1610612751,
+# JSON64-NEXT: "Type": "ANDROID_REL",
+# JSON64-NEXT: "Value": 4096
+# JSON64-NEXT: },
+# JSON64-NEXT: {
+# JSON64-NEXT: "Tag": 1610612752,
+# JSON64-NEXT: "Type": "ANDROID_RELSZ",
+# JSON64-NEXT: "Value": 16
+# JSON64-NEXT: },
+# JSON64-NEXT: {
+# JSON64-NEXT: "Tag": 1610612753,
+# JSON64-NEXT: "Type": "ANDROID_RELA",
+# JSON64-NEXT: "Value": 4096
+# JSON64-NEXT: },
+# JSON64-NEXT: {
+# JSON64-NEXT: "Tag": 1610612754,
+# JSON64-NEXT: "Type": "ANDROID_RELASZ",
+# JSON64-NEXT: "Value": 16
+# JSON64-NEXT: },
+# JSON64-NEXT: {
+# JSON64-NEXT: "Tag": 1879040000,
+# JSON64-NEXT: "Type": "ANDROID_RELR",
+# JSON64-NEXT: "Value": 4096
+# JSON64-NEXT: },
+# JSON64-NEXT: {
+# JSON64-NEXT: "Tag": 1879040001,
+# JSON64-NEXT: "Type": "ANDROID_RELRSZ",
+# JSON64-NEXT: "Value": 16
+# JSON64-NEXT: },
+# JSON64-NEXT: {
+# JSON64-NEXT: "Tag": 1879040003,
+# JSON64-NEXT: "Type": "ANDROID_RELRENT",
+# JSON64-NEXT: "Value": 4660
+# JSON64-NEXT: },
+# JSON64-NEXT: {
+# JSON64-NEXT: "Tag": 1879047925,
+# JSON64-NEXT: "Type": "GNU_HASH",
+# JSON64-NEXT: "Value": 4096
+# JSON64-NEXT: },
+# JSON64-NEXT: {
+# JSON64-NEXT: "Tag": 1879047926,
+# JSON64-NEXT: "Type": "TLSDESC_PLT",
+# JSON64-NEXT: "Value": 4096
+# JSON64-NEXT: },
+# JSON64-NEXT: {
+# JSON64-NEXT: "Tag": 1879047927,
+# JSON64-NEXT: "Type": "TLSDESC_GOT",
+# JSON64-NEXT: "Value": 4096
+# JSON64-NEXT: },
+# JSON64-NEXT: {
+# JSON64-NEXT: "Tag": 1879048185,
+# JSON64-NEXT: "Type": "RELACOUNT",
+# JSON64-NEXT: "Value": 0
+# JSON64-NEXT: },
+# JSON64-NEXT: {
+# JSON64-NEXT: "Tag": 1879048186,
+# JSON64-NEXT: "Type": "RELCOUNT",
+# JSON64-NEXT: "Value": 0
+# JSON64-NEXT: },
+# JSON64-NEXT: {
+# JSON64-NEXT: "Tag": 1879048187,
+# JSON64-NEXT: "Type": "FLAGS_1"
+# JSON64-NEXT: "Value": 18446744073709551615,
+# JSON64-NEXT: "Flags": [
+# JSON64-NEXT: "NOW",
+# JSON64-NEXT: "GLOBAL",
+# JSON64-NEXT: "GROUP",
+# JSON64-NEXT: "NODELETE",
+# JSON64-NEXT: "LOADFLTR",
+# JSON64-NEXT: "INITFIRST",
+# JSON64-NEXT: "NOOPEN",
+# JSON64-NEXT: "ORIGIN",
+# JSON64-NEXT: "DIRECT",
+# JSON64-NEXT: "TRANS",
+# JSON64-NEXT: "INTERPOSE",
+# JSON64-NEXT: "NODEFLIB",
+# JSON64-NEXT: "NODUMP",
+# JSON64-NEXT: "CONFALT",
+# JSON64-NEXT: "ENDFILTEE",
+# JSON64-NEXT: "DISPRELDNE",
+# JSON64-NEXT: "DISPRELPND",
+# JSON64-NEXT: "NODIRECT",
+# JSON64-NEXT: "IGNMULDEF",
+# JSON64-NEXT: "NOKSYMS",
+# JSON64-NEXT: "NOHDR",
+# JSON64-NEXT: "EDITED",
+# JSON64-NEXT: "NORELOC",
+# JSON64-NEXT: "SYMINTPOSE",
+# JSON64-NEXT: "GLOBAUDIT",
+# JSON64-NEXT: "SINGLETON",
+# JSON64-NEXT: "PIE"
+# JSON64-NEXT: ]
+# JSON64-NEXT: },
+# JSON64-NEXT: {
+# JSON64-NEXT: "Tag": 1879048176,
+# JSON64-NEXT: "Type": "VERSYM",
+# JSON64-NEXT: "Value": 4096
+# JSON64-NEXT: },
+# JSON64-NEXT: {
+# JSON64-NEXT: "Tag": 1879048188,
+# JSON64-NEXT: "Type": "VERDEF",
+# JSON64-NEXT: "Value": 4096
+# JSON64-NEXT: },
+# JSON64-NEXT: {
+# JSON64-NEXT: "Tag": 1879048189,
+# JSON64-NEXT: "Type": "VERDEFNUM",
+# JSON64-NEXT: "Value": 0
+# JSON64-NEXT: },
+# JSON64-NEXT: {
+# JSON64-NEXT: "Tag": 1879048190,
+# JSON64-NEXT: "Type": "VERNEED",
+# JSON64-NEXT: "Value": 4096
+# JSON64-NEXT: },
+# JSON64-NEXT: {
+# JSON64-NEXT: "Tag": 1879048191,
+# JSON64-NEXT: "Type": "VERNEEDNUM",
+# JSON64-NEXT: "Value": 0
+# JSON64-NEXT: },
+# JSON64-NEXT: {
+# JSON64-NEXT: "Tag": 2147483645,
+# JSON64-NEXT: "Type": "AUXILIARY"
+# JSON64-NEXT: "Value": 1,
+# JSON64-NEXT: "Library": "D"
+# JSON64-NEXT: },
+# JSON64-NEXT: {
+# JSON64-NEXT: "Tag": 2147483646,
+# JSON64-NEXT: "Type": "USED",
+# JSON64-NEXT: "Value": 3,
+# JSON64-NEXT: "Object": "U"
+# JSON64-NEXT: },
+# JSON64-NEXT: {
+# JSON64-NEXT: "Tag": 2147483647,
+# JSON64-NEXT: "Type": "FILTER",
+# JSON64-NEXT: "Value": 3,
+# JSON64-NEXT: "Library": "U"
+# JSON64-NEXT: },
+# JSON64-NEXT: {
+# JSON64-NEXT: "Tag": 305419896,
+# JSON64-NEXT: "Type": "<unknown:>0x12345678",
+# JSON64-NEXT: "Value": 9756277979052589857
+# JSON64-NEXT: },
+# JSON64-NEXT: {
+# JSON64-NEXT: "Tag": 1790762736,
+# JSON64-NEXT: "Type": "<unknown:>0x6abcdef0",
+# JSON64-NEXT: "Value": 11063223766036525858
+# JSON64-NEXT: },
+# JSON64-NEXT: {
+# JSON64-NEXT: "Tag": 1985229328,
+# JSON64-NEXT: "Type": "<unknown:>0x76543210",
+# JSON64-NEXT: "Value": 6148933456521300104
+# JSON64-NEXT: },
+# JSON64-NEXT: {
+# JSON64-NEXT: "Tag": 0,
+# JSON64-NEXT: "Type": "NULL",
+# JSON64-NEXT: "Value": 0
+# JSON64-NEXT: }
+# JSON64-NEXT:]
+
--- !ELF
FileHeader:
Class: ELFCLASS[[BITS=64]]
diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp
index c696934..734b28d 100644
--- a/llvm/tools/llvm-readobj/ELFDumper.cpp
+++ b/llvm/tools/llvm-readobj/ELFDumper.cpp
@@ -793,7 +793,11 @@ public:
void printEmptyGroupMessage() const override;
+ void printDynamicTable() override;
+
private:
+ void printAuxillaryDynamicTableEntryInfo(const Elf_Dyn &Entry);
+
std::unique_ptr<DictScope> FileScope;
};
@@ -7365,6 +7369,63 @@ template <class ELFT> void LLVMELFDumper<ELFT>::printDynamicTable() {
W.startLine() << "]\n";
}
+template <class ELFT>
+void JSONELFDumper<ELFT>::printAuxillaryDynamicTableEntryInfo(
+ const Elf_Dyn &Entry) {
+ auto FormatFlags = [this, Value = Entry.getVal()](auto Flags) {
+ ListScope L(this->W, "Flags");
+ for (const auto &Flag : Flags) {
+ if (Flag.Value != 0 && (Value & Flag.Value) == Flag.Value)
+ this->W.printString(Flag.Name);
+ }
+ };
+ switch (Entry.getTag()) {
+ case DT_SONAME:
+ this->W.printString("Name", this->getDynamicString(Entry.getVal()));
+ break;
+ case DT_AUXILIARY:
+ case DT_FILTER:
+ case DT_NEEDED:
+ this->W.printString("Library", this->getDynamicString(Entry.getVal()));
+ break;
+ case DT_USED:
+ this->W.printString("Object", this->getDynamicString(Entry.getVal()));
+ break;
+ case DT_RPATH:
+ case DT_RUNPATH: {
+ StringRef Value = this->getDynamicString(Entry.getVal());
+ ListScope L(this->W, "Path");
+ while (!Value.empty()) {
+ auto [Front, Back] = Value.split(':');
+ this->W.printString(Front);
+ Value = Back;
+ }
+ break;
+ }
+ case DT_FLAGS:
+ FormatFlags(ArrayRef(ElfDynamicDTFlags));
+ break;
+ case DT_FLAGS_1:
+ FormatFlags(ArrayRef(ElfDynamicDTFlags1));
+ break;
+ default:
+ return;
+ }
+}
+
+template <class ELFT> void JSONELFDumper<ELFT>::printDynamicTable() {
+ Elf_Dyn_Range Table = this->dynamic_table();
+ ListScope L(this->W, "DynamicSection");
+ for (const auto &Entry : Table) {
+ DictScope D(this->W);
+ uintX_t Tag = Entry.getTag();
+ this->W.printHex("Tag", Tag);
+ this->W.printString("Type", this->Obj.getDynamicTagAsString(Tag));
+ this->W.printHex("Value", Entry.getVal());
+ this->printAuxillaryDynamicTableEntryInfo(Entry);
+ }
+}
+
template <class ELFT> void LLVMELFDumper<ELFT>::printDynamicRelocations() {
W.startLine() << "Dynamic Relocations {\n";
W.indent();