Skip to content

Commit b9b91c1

Browse files
committed
[llvm-readobj][ELF] Fix broken JSON output with --dynamic-table
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 this commit 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] Whereas now it is: "DynamicSection": [ { "Tag": 29, "Value": "Library runpath: [$ORIGIN/../lib:]", "Type": "RUNPATH" }, { "Tag": 1, "Value": "Shared library: [libm.so.6]", "Type": "NEEDED" },
1 parent 35a2b60 commit b9b91c1

File tree

2 files changed

+325
-0
lines changed

2 files changed

+325
-0
lines changed

llvm/test/tools/llvm-readobj/ELF/dynamic-tags.test

Lines changed: 310 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
# RUN: llvm-readelf --dynamic-table %t1 \
99
# RUN: | FileCheck %s --strict-whitespace --match-full-lines --check-prefix=GNU64
1010
# RUN: llvm-readelf -d %t1 | FileCheck %s --check-prefix=GNU64
11+
# RUN: llvm-readelf --dynamic-table --pretty-print --elf-output-style=JSON %t1 \
12+
# RUN: | FileCheck %s --strict-whitespace --check-prefix=JSON64
1113

1214
# LLVM64:DynamicSection [ (61 entries)
1315
# LLVM64-NEXT: Tag Type Name/Value
@@ -138,6 +140,314 @@
138140
# GNU64-NEXT: 0x0000000076543210 (<unknown:>0x76543210) 0x5555666677778888
139141
# GNU64-NEXT: 0x0000000000000000 (NULL) 0x0
140142

143+
# JSON64: "DynamicSection": [
144+
# JSON64-NEXT: {
145+
# JSON64-NEXT: "Tag": 1,
146+
# JSON64-NEXT: "Value": "Shared library: [D]",
147+
# JSON64-NEXT: "Type": "NEEDED"
148+
# JSON64-NEXT: },
149+
# JSON64-NEXT: {
150+
# JSON64-NEXT: "Tag": 2,
151+
# JSON64-NEXT: "Value": "16 (bytes)",
152+
# JSON64-NEXT: "Type": "PLTRELSZ"
153+
# JSON64-NEXT: },
154+
# JSON64-NEXT: {
155+
# JSON64-NEXT: "Tag": 3,
156+
# JSON64-NEXT: "Value": "0x1000",
157+
# JSON64-NEXT: "Type": "PLTGOT"
158+
# JSON64-NEXT: },
159+
# JSON64-NEXT: {
160+
# JSON64-NEXT: "Tag": 4,
161+
# JSON64-NEXT: "Value": "0x1000",
162+
# JSON64-NEXT: "Type": "HASH"
163+
# JSON64-NEXT: },
164+
# JSON64-NEXT: {
165+
# JSON64-NEXT: "Tag": 5,
166+
# JSON64-NEXT: "Value": "0x1000",
167+
# JSON64-NEXT: "Type": "STRTAB"
168+
# JSON64-NEXT: },
169+
# JSON64-NEXT: {
170+
# JSON64-NEXT: "Tag": 6,
171+
# JSON64-NEXT: "Value": "0x1000",
172+
# JSON64-NEXT: "Type": "SYMTAB"
173+
# JSON64-NEXT: },
174+
# JSON64-NEXT: {
175+
# JSON64-NEXT: "Tag": 7,
176+
# JSON64-NEXT: "Value": "0x1000",
177+
# JSON64-NEXT: "Type": "RELA"
178+
# JSON64-NEXT: },
179+
# JSON64-NEXT: {
180+
# JSON64-NEXT: "Tag": 8,
181+
# JSON64-NEXT: "Value": "16 (bytes)",
182+
# JSON64-NEXT: "Type": "RELASZ"
183+
# JSON64-NEXT: },
184+
# JSON64-NEXT: {
185+
# JSON64-NEXT: "Tag": 9,
186+
# JSON64-NEXT: "Value": "1929 (bytes)",
187+
# JSON64-NEXT: "Type": "RELAENT"
188+
# JSON64-NEXT: },
189+
# JSON64-NEXT: {
190+
# JSON64-NEXT: "Tag": 10,
191+
# JSON64-NEXT: "Value": "16 (bytes)",
192+
# JSON64-NEXT: "Type": "STRSZ"
193+
# JSON64-NEXT: },
194+
# JSON64-NEXT: {
195+
# JSON64-NEXT: "Tag": 11,
196+
# JSON64-NEXT: "Value": "2439 (bytes)",
197+
# JSON64-NEXT: "Type": "SYMENT"
198+
# JSON64-NEXT: },
199+
# JSON64-NEXT: {
200+
# JSON64-NEXT: "Tag": 12,
201+
# JSON64-NEXT: "Value": "0x1000",
202+
# JSON64-NEXT: "Type": "INIT"
203+
# JSON64-NEXT: },
204+
# JSON64-NEXT: {
205+
# JSON64-NEXT: "Tag": 13,
206+
# JSON64-NEXT: "Value": "0x1000",
207+
# JSON64-NEXT: "Type": "FINI"
208+
# JSON64-NEXT: },
209+
# JSON64-NEXT: {
210+
# JSON64-NEXT: "Tag": 14,
211+
# JSON64-NEXT: "Value": "Library soname: [U]",
212+
# JSON64-NEXT: "Type": "SONAME"
213+
# JSON64-NEXT: },
214+
# JSON64-NEXT: {
215+
# JSON64-NEXT: "Tag": 15,
216+
# JSON64-NEXT: "Value": "Library rpath: [f]",
217+
# JSON64-NEXT: "Type": "RPATH"
218+
# JSON64-NEXT: },
219+
# JSON64-NEXT: {
220+
# JSON64-NEXT: "Tag": 16,
221+
# JSON64-NEXT: "Value": "0x1234567890ABCDEF",
222+
# JSON64-NEXT: "Type": "SYMBOLIC"
223+
# JSON64-NEXT: },
224+
# JSON64-NEXT: {
225+
# JSON64-NEXT: "Tag": 17,
226+
# JSON64-NEXT: "Value": "0x1000",
227+
# JSON64-NEXT: "Type": "REL"
228+
# JSON64-NEXT: },
229+
# JSON64-NEXT: {
230+
# JSON64-NEXT: "Tag": 18,
231+
# JSON64-NEXT: "Value": "16 (bytes)",
232+
# JSON64-NEXT: "Type": "RELSZ"
233+
# JSON64-NEXT: },
234+
# JSON64-NEXT: {
235+
# JSON64-NEXT: "Tag": 19,
236+
# JSON64-NEXT: "Value": "291 (bytes)",
237+
# JSON64-NEXT: "Type": "RELENT"
238+
# JSON64-NEXT: },
239+
# JSON64-NEXT: {
240+
# JSON64-NEXT: "Tag": 20,
241+
# JSON64-NEXT: "Value": "RELA",
242+
# JSON64-NEXT: "Type": "PLTREL"
243+
# JSON64-NEXT: },
244+
# JSON64-NEXT: {
245+
# JSON64-NEXT: "Tag": 21,
246+
# JSON64-NEXT: "Value": "0xFEDCBA0987654321",
247+
# JSON64-NEXT: "Type": "DEBUG"
248+
# JSON64-NEXT: },
249+
# JSON64-NEXT: {
250+
# JSON64-NEXT: "Tag": 22,
251+
# JSON64-NEXT: "Value": "0x1122334455667788",
252+
# JSON64-NEXT: "Type": "TEXTREL"
253+
# JSON64-NEXT: },
254+
# JSON64-NEXT: {
255+
# JSON64-NEXT: "Tag": 23,
256+
# JSON64-NEXT: "Value": "0x1000",
257+
# JSON64-NEXT: "Type": "JMPREL"
258+
# JSON64-NEXT: },
259+
# JSON64-NEXT: {
260+
# JSON64-NEXT: "Tag": 24,
261+
# JSON64-NEXT: "Value": "0x8877665544332211",
262+
# JSON64-NEXT: "Type": "BIND_NOW"
263+
# JSON64-NEXT: },
264+
# JSON64-NEXT: {
265+
# JSON64-NEXT: "Tag": 25,
266+
# JSON64-NEXT: "Value": "0x1000",
267+
# JSON64-NEXT: "Type": "INIT_ARRAY"
268+
# JSON64-NEXT: },
269+
# JSON64-NEXT: {
270+
# JSON64-NEXT: "Tag": 26,
271+
# JSON64-NEXT: "Value": "0x1000",
272+
# JSON64-NEXT: "Type": "FINI_ARRAY"
273+
# JSON64-NEXT: },
274+
# JSON64-NEXT: {
275+
# JSON64-NEXT: "Tag": 27,
276+
# JSON64-NEXT: "Value": "16 (bytes)",
277+
# JSON64-NEXT: "Type": "INIT_ARRAYSZ"
278+
# JSON64-NEXT: },
279+
# JSON64-NEXT: {
280+
# JSON64-NEXT: "Tag": 28,
281+
# JSON64-NEXT: "Value": "16 (bytes)",
282+
# JSON64-NEXT: "Type": "FINI_ARRAYSZ"
283+
# JSON64-NEXT: },
284+
# JSON64-NEXT: {
285+
# JSON64-NEXT: "Tag": 29,
286+
# JSON64-NEXT: "Value": "Library runpath: [w]",
287+
# JSON64-NEXT: "Type": "RUNPATH"
288+
# JSON64-NEXT: },
289+
# JSON64-NEXT: {
290+
# JSON64-NEXT: "Tag": 30,
291+
# JSON64-NEXT: "Value": "ORIGIN SYMBOLIC TEXTREL BIND_NOW STATIC_TLS ",
292+
# JSON64-NEXT: "Type": "FLAGS"
293+
# JSON64-NEXT: },
294+
# JSON64-NEXT: {
295+
# JSON64-NEXT: "Tag": 32,
296+
# JSON64-NEXT: "Value": "0x1000",
297+
# JSON64-NEXT: "Type": "PREINIT_ARRAY"
298+
# JSON64-NEXT: },
299+
# JSON64-NEXT: {
300+
# JSON64-NEXT: "Tag": 33,
301+
# JSON64-NEXT: "Value": "16 (bytes)",
302+
# JSON64-NEXT: "Type": "PREINIT_ARRAYSZ"
303+
# JSON64-NEXT: },
304+
# JSON64-NEXT: {
305+
# JSON64-NEXT: "Tag": 34,
306+
# JSON64-NEXT: "Value": "0x1000",
307+
# JSON64-NEXT: "Type": "SYMTAB_SHNDX"
308+
# JSON64-NEXT: },
309+
# JSON64-NEXT: {
310+
# JSON64-NEXT: "Tag": 35,
311+
# JSON64-NEXT: "Value": "16 (bytes)",
312+
# JSON64-NEXT: "Type": "RELRSZ"
313+
# JSON64-NEXT: },
314+
# JSON64-NEXT: {
315+
# JSON64-NEXT: "Tag": 36,
316+
# JSON64-NEXT: "Value": "0x1000",
317+
# JSON64-NEXT: "Type": "RELR"
318+
# JSON64-NEXT: },
319+
# JSON64-NEXT: {
320+
# JSON64-NEXT: "Tag": 37,
321+
# JSON64-NEXT: "Value": "17185 (bytes)",
322+
# JSON64-NEXT: "Type": "RELRENT"
323+
# JSON64-NEXT: },
324+
# JSON64-NEXT: {
325+
# JSON64-NEXT: "Tag": 1610612751,
326+
# JSON64-NEXT: "Value": "0x1000",
327+
# JSON64-NEXT: "Type": "ANDROID_REL"
328+
# JSON64-NEXT: },
329+
# JSON64-NEXT: {
330+
# JSON64-NEXT: "Tag": 1610612752,
331+
# JSON64-NEXT: "Value": "16 (bytes)",
332+
# JSON64-NEXT: "Type": "ANDROID_RELSZ"
333+
# JSON64-NEXT: },
334+
# JSON64-NEXT: {
335+
# JSON64-NEXT: "Tag": 1610612753,
336+
# JSON64-NEXT: "Value": "0x1000",
337+
# JSON64-NEXT: "Type": "ANDROID_RELA"
338+
# JSON64-NEXT: },
339+
# JSON64-NEXT: {
340+
# JSON64-NEXT: "Tag": 1610612754,
341+
# JSON64-NEXT: "Value": "16 (bytes)",
342+
# JSON64-NEXT: "Type": "ANDROID_RELASZ"
343+
# JSON64-NEXT: },
344+
# JSON64-NEXT: {
345+
# JSON64-NEXT: "Tag": 1879040000,
346+
# JSON64-NEXT: "Value": "0x1000",
347+
# JSON64-NEXT: "Type": "ANDROID_RELR"
348+
# JSON64-NEXT: },
349+
# JSON64-NEXT: {
350+
# JSON64-NEXT: "Tag": 1879040001,
351+
# JSON64-NEXT: "Value": "0x10",
352+
# JSON64-NEXT: "Type": "ANDROID_RELRSZ"
353+
# JSON64-NEXT: },
354+
# JSON64-NEXT: {
355+
# JSON64-NEXT: "Tag": 1879040003,
356+
# JSON64-NEXT: "Value": "0x1234",
357+
# JSON64-NEXT: "Type": "ANDROID_RELRENT"
358+
# JSON64-NEXT: },
359+
# JSON64-NEXT: {
360+
# JSON64-NEXT: "Tag": 1879047925,
361+
# JSON64-NEXT: "Value": "0x1000",
362+
# JSON64-NEXT: "Type": "GNU_HASH"
363+
# JSON64-NEXT: },
364+
# JSON64-NEXT: {
365+
# JSON64-NEXT: "Tag": 1879047926,
366+
# JSON64-NEXT: "Value": "0x1000",
367+
# JSON64-NEXT: "Type": "TLSDESC_PLT"
368+
# JSON64-NEXT: },
369+
# JSON64-NEXT: {
370+
# JSON64-NEXT: "Tag": 1879047927,
371+
# JSON64-NEXT: "Value": "0x1000",
372+
# JSON64-NEXT: "Type": "TLSDESC_GOT"
373+
# JSON64-NEXT: },
374+
# JSON64-NEXT: {
375+
# JSON64-NEXT: "Tag": 1879048185,
376+
# JSON64-NEXT: "Value": "0",
377+
# JSON64-NEXT: "Type": "RELACOUNT"
378+
# JSON64-NEXT: },
379+
# JSON64-NEXT: {
380+
# JSON64-NEXT: "Tag": 1879048186,
381+
# JSON64-NEXT: "Value": "0",
382+
# JSON64-NEXT: "Type": "RELCOUNT"
383+
# JSON64-NEXT: },
384+
# JSON64-NEXT: {
385+
# JSON64-NEXT: "Tag": 1879048187,
386+
# JSON64-NEXT: "Value": "NOW GLOBAL GROUP NODELETE LOADFLTR INITFIRST NOOPEN ORIGIN DIRECT TRANS INTERPOSE NODEFLIB NODUMP CONFALT ENDFILTEE DISPRELDNE DISPRELPND NODIRECT IGNMULDEF NOKSYMS NOHDR EDITED NORELOC SYMINTPOSE GLOBAUDIT SINGLETON PIE ",
387+
# JSON64-NEXT: "Type": "FLAGS_1"
388+
# JSON64-NEXT: },
389+
# JSON64-NEXT: {
390+
# JSON64-NEXT: "Tag": 1879048176,
391+
# JSON64-NEXT: "Value": "0x1000",
392+
# JSON64-NEXT: "Type": "VERSYM"
393+
# JSON64-NEXT: },
394+
# JSON64-NEXT: {
395+
# JSON64-NEXT: "Tag": 1879048188,
396+
# JSON64-NEXT: "Value": "0x1000",
397+
# JSON64-NEXT: "Type": "VERDEF"
398+
# JSON64-NEXT: },
399+
# JSON64-NEXT: {
400+
# JSON64-NEXT: "Tag": 1879048189,
401+
# JSON64-NEXT: "Value": "0",
402+
# JSON64-NEXT: "Type": "VERDEFNUM"
403+
# JSON64-NEXT: },
404+
# JSON64-NEXT: {
405+
# JSON64-NEXT: "Tag": 1879048190,
406+
# JSON64-NEXT: "Value": "0x1000",
407+
# JSON64-NEXT: "Type": "VERNEED"
408+
# JSON64-NEXT: },
409+
# JSON64-NEXT: {
410+
# JSON64-NEXT: "Tag": 1879048191,
411+
# JSON64-NEXT: "Value": "0",
412+
# JSON64-NEXT: "Type": "VERNEEDNUM"
413+
# JSON64-NEXT: },
414+
# JSON64-NEXT: {
415+
# JSON64-NEXT: "Tag": 2147483645,
416+
# JSON64-NEXT: "Value": "Auxiliary library: [D]",
417+
# JSON64-NEXT: "Type": "AUXILIARY"
418+
# JSON64-NEXT: },
419+
# JSON64-NEXT: {
420+
# JSON64-NEXT: "Tag": 2147483646,
421+
# JSON64-NEXT: "Value": "Not needed object: [U]",
422+
# JSON64-NEXT: "Type": "USED"
423+
# JSON64-NEXT: },
424+
# JSON64-NEXT: {
425+
# JSON64-NEXT: "Tag": 2147483647,
426+
# JSON64-NEXT: "Value": "Filter library: [U]",
427+
# JSON64-NEXT: "Type": "FILTER"
428+
# JSON64-NEXT: },
429+
# JSON64-NEXT: {
430+
# JSON64-NEXT: "Tag": 305419896,
431+
# JSON64-NEXT: "Value": "0x8765432187654321",
432+
# JSON64-NEXT: "Type": "<unknown:>0x12345678"
433+
# JSON64-NEXT: },
434+
# JSON64-NEXT: {
435+
# JSON64-NEXT: "Tag": 1790762736,
436+
# JSON64-NEXT: "Value": "0x9988776655443322",
437+
# JSON64-NEXT: "Type": "<unknown:>0x6abcdef0"
438+
# JSON64-NEXT: },
439+
# JSON64-NEXT: {
440+
# JSON64-NEXT: "Tag": 1985229328,
441+
# JSON64-NEXT: "Value": "0x5555666677778888",
442+
# JSON64-NEXT: "Type": "<unknown:>0x76543210"
443+
# JSON64-NEXT: },
444+
# JSON64-NEXT: {
445+
# JSON64-NEXT: "Tag": 0,
446+
# JSON64-NEXT: "Value": "0x0",
447+
# JSON64-NEXT: "Type": "NULL"
448+
# JSON64-NEXT: }
449+
# JSON64-NEXT:]
450+
141451
--- !ELF
142452
FileHeader:
143453
Class: ELFCLASS[[BITS=64]]

llvm/tools/llvm-readobj/ELFDumper.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -793,6 +793,8 @@ template <typename ELFT> class JSONELFDumper : public LLVMELFDumper<ELFT> {
793793

794794
void printEmptyGroupMessage() const override;
795795

796+
void printDynamicTable() override;
797+
796798
private:
797799
std::unique_ptr<DictScope> FileScope;
798800
};
@@ -7365,6 +7367,19 @@ template <class ELFT> void LLVMELFDumper<ELFT>::printDynamicTable() {
73657367
W.startLine() << "]\n";
73667368
}
73677369

7370+
template <class ELFT> void JSONELFDumper<ELFT>::printDynamicTable() {
7371+
Elf_Dyn_Range Table = this->dynamic_table();
7372+
ListScope L(this->W, "DynamicSection");
7373+
for (const auto &Entry : Table) {
7374+
DictScope D(this->W);
7375+
uintX_t Tag = Entry.getTag();
7376+
std::string Value = this->getDynamicEntry(Tag, Entry.getVal());
7377+
this->W.printHex("Tag", Tag);
7378+
this->W.printString("Value", Value);
7379+
this->W.printString("Type", this->Obj.getDynamicTagAsString(Tag));
7380+
}
7381+
}
7382+
73687383
template <class ELFT> void LLVMELFDumper<ELFT>::printDynamicRelocations() {
73697384
W.startLine() << "Dynamic Relocations {\n";
73707385
W.indent();

0 commit comments

Comments
 (0)