diff options
author | Fred Grim <fgrim@apple.com> | 2024-06-24 11:25:18 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-06-24 11:25:18 -0700 |
commit | 0ab81986be7c2df8dc784e9e950c906274b51fd4 (patch) | |
tree | d82c43884dae95b30ae7d690b3004f7f332b1ff5 | |
parent | 962d7ac7fcdf6f0cb43e36dec2a6a67cadd7c46c (diff) | |
download | llvm-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.test | 357 | ||||
-rw-r--r-- | llvm/tools/llvm-readobj/ELFDumper.cpp | 61 |
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(); |