[PATCH 4/5] readelf: Print CU, base address and unresolved .debug_range entries.
Also adjust the formatting for the resolved addresses to print them on separate lines so they nicely line up even when the addresses are resolved to symbol+offset names. Signed-off-by: Mark Wielaard --- src/ChangeLog | 5 + src/readelf.c | 47 ++-- tests/ChangeLog | 5 + tests/run-readelf-loc.sh| 52 ++--- tests/run-readelf-zdebug.sh | 4 +++- 5 files changed, 89 insertions(+), 24 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 12cd571..3dd80fb 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,10 @@ 2017-11-29 Mark Wielaard + * readelf.c (print_debug_ranges_section): Print CU base and unresolved + addresses. Adjust formatting. + +2017-11-29 Mark Wielaard + * readelf.c (attr_callback): Set valuestr to resolved file name for DW_AT_decl_file and DW_AT_call_file. diff --git a/src/readelf.c b/src/readelf.c index 8661ba8..8e13462 100644 --- a/src/readelf.c +++ b/src/readelf.c @@ -5007,15 +5007,33 @@ print_debug_ranges_section (Dwfl_Module *dwflmod, Dwarf_Addr base = 0; unsigned char *const endp = (unsigned char *) data->d_buf + data->d_size; unsigned char *readp = data->d_buf; + Dwarf_CU *last_cu = NULL; while (readp < endp) { ptrdiff_t offset = readp - (unsigned char *) data->d_buf; + Dwarf_CU *cu; if (first && skip_listptr_hole (&known_rangelistptr, &listptr_idx, - &address_size, NULL, &base, NULL, + &address_size, NULL, &base, &cu, offset, &readp, endp)) continue; + if (last_cu != cu) + { + char *basestr = format_dwarf_addr (dwflmod, address_size, +base, base); + Dwarf_Die cudie; + if (dwarf_cu_die (cu, &cudie, + NULL, NULL, NULL, NULL, + NULL, NULL) == NULL) + printf (gettext ("\n Unknown CU base: %s\n"), basestr); + else + printf (gettext ("\n CU [%6" PRIx64 "] base: %s\n"), + dwarf_dieoffset (&cudie), basestr); + free (basestr); + } + last_cu = cu; + if (unlikely (data->d_size - offset < (size_t) address_size * 2)) { printf (gettext (" [%6tx] \n"), offset); @@ -5040,29 +5058,36 @@ print_debug_ranges_section (Dwfl_Module *dwflmod, if (begin == (Dwarf_Addr) -1l) /* Base address entry. */ { char *b = format_dwarf_addr (dwflmod, address_size, end, end); - printf (gettext (" [%6tx] base address %s\n"), offset, b); + printf (gettext (" [%6tx] base address\n %s\n"), offset, b); free (b); base = end; } else if (begin == 0 && end == 0) /* End of list entry. */ { if (first) - printf (gettext (" [%6tx] empty list\n"), offset); + printf (gettext (" [%6tx] empty list\n"), offset); first = true; } else { - char *b = format_dwarf_addr (dwflmod, address_size, base + begin, - begin); - char *e = format_dwarf_addr (dwflmod, address_size, base + end, - end); /* We have an address range entry. */ if (first)/* First address range entry in a list. */ - printf (gettext (" [%6tx] %s..%s\n"), offset, b, e); + printf (" [%6tx] ", offset); else - printf (gettext (" %s..%s\n"), b, e); - free (b); - free (e); + printf (" "); + + printf ("range %" PRIx64 ", %" PRIx64 "\n", begin, end); + if (! print_unresolved_addresses) + { + char *b = format_dwarf_addr (dwflmod, address_size, base + begin, + base + begin); + char *e = format_dwarf_addr (dwflmod, address_size, + base + end - 1, base + end); + printf (" %s..\n", b); + printf (" %s\n", e); + free (b); + free (e); + } first = false; } diff --git a/tests/ChangeLog b/tests/ChangeLog index c9fc53a..4666dcc 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,5 +1,10 @@ 2017-11-29 Mark Wielaard + * run-readelf-loc.sh: Adjust expected range list output. + * run-readelf-zdebug.sh: Likewise. + +2017-11-29 Mark Wielaard + * run-readelf-dwz-multi.sh: Add expected file names. * run-readelf-zdebug-rel.sh: Likewise. diff --git a/tests/run-readelf-loc.sh b/tests/run-readelf-loc.sh index 3959d3d..4b666cf 100755 --- a/tests/run-readelf-loc.sh +++ b/tests/run-readelf-loc.sh @@ -68,10 +68,22 @@ DWARF section [
[PATCH 3/5] readelf: Print actual file for decl_file and call_file attributes.
When we see a DW_AT_decl_file or DW_AT_call_file attribute print the actual file name. The current interface gives us a full (absolute) patch, but we only want to show the file name for now to not clutter the output too much. This helps a lot when trying to determine where something was declared if you are just looking at the DIE tree. Otherwise you'll have to cross match the number by hand with the corresponding line table entry. Signed-off-by: Mark Wielaard --- src/ChangeLog | 5 + src/readelf.c | 22 ++ tests/ChangeLog | 5 + tests/run-readelf-dwz-multi.sh | 32 tests/run-readelf-zdebug-rel.sh | 10 +- 5 files changed, 53 insertions(+), 21 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index e7e598d..12cd571 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,10 @@ 2017-11-29 Mark Wielaard + * readelf.c (attr_callback): Set valuestr to resolved file name + for DW_AT_decl_file and DW_AT_call_file. + +2017-11-29 Mark Wielaard + * readelf.c (print_debug_units): Print abbrev code after DIE tag. 2017-11-29 Mark Wielaard diff --git a/src/readelf.c b/src/readelf.c index e9887c4..8661ba8 100644 --- a/src/readelf.c +++ b/src/readelf.c @@ -6126,6 +6126,28 @@ attr_callback (Dwarf_Attribute *attrp, void *arg) case DW_AT_discr_list: valuestr = dwarf_discr_list_name (num); break; + case DW_AT_decl_file: + case DW_AT_call_file: + { + /* Try to get the actual file, the current interface only + gives us full paths, but we only want to show the file + name for now. */ + Dwarf_Die cudie; + if (dwarf_cu_die (cbargs->cu, &cudie, + NULL, NULL, NULL, NULL, NULL, NULL) != NULL) + { + Dwarf_Files *files; + size_t nfiles; + if (dwarf_getsrcfiles (&cudie, &files, &nfiles) == 0) + { + valuestr = dwarf_filesrc (files, num, NULL, NULL); + char *filename = strrchr (valuestr, '/'); + if (filename != NULL) + valuestr = filename + 1; + } + } + } + break; default: /* Nothing. */ break; diff --git a/tests/ChangeLog b/tests/ChangeLog index f522a69..c9fc53a 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,5 +1,10 @@ 2017-11-29 Mark Wielaard + * run-readelf-dwz-multi.sh: Add expected file names. + * run-readelf-zdebug-rel.sh: Likewise. + +2017-11-29 Mark Wielaard + * run-readelf-dwz-multi.sh: Add expected abbrev codes. * run-readelf-zdebug-rel.sh: Likewise. diff --git a/tests/run-readelf-dwz-multi.sh b/tests/run-readelf-dwz-multi.sh index 21456fd..4f317ac 100755 --- a/tests/run-readelf-dwz-multi.sh +++ b/tests/run-readelf-dwz-multi.sh @@ -100,7 +100,7 @@ DWARF section [28] '.debug_info' at offset 0x1078: [31]subprogram abbrev: 3 external (flag_present) yes name (strp) "main" - decl_file(data1) 1 + decl_file(data1) main.c (1) decl_line(data1) 3 prototyped (flag_present) yes type (GNU_ref_alt) [3e] @@ -112,21 +112,21 @@ DWARF section [28] '.debug_info' at offset 0x1078: sibling (ref_udata) [6e] [48] formal_parameter abbrev: 8 name (strp) "argc" - decl_file(data1) 1 + decl_file(data1) main.c (1) decl_line(data1) 3 type (GNU_ref_alt) [3e] location (exprloc) [ 0] fbreg -36 [56] formal_parameter abbrev: 4 name (strp) "argv" - decl_file(data1) 1 + decl_file(data1) main.c (1) decl_line(data1) 3 type (ref_udata) [6e] location (exprloc) [ 0] fbreg -48 [61] variable abbrev: 7 name (string) "b" - decl_file(data1) 1 + decl_file(data1) main.c (1) decl_line(data1) 5 type (GNU_ref_alt) [5a] location (exprloc) @@ -161,7 +161,7 @@ DWARF section [28] '.debug_info' at offset 0x1078: [31]subprogram abbrev: 3 external (flag_present) yes name (strp) "main" - decl_file
[PATCH 1/5] readelf: Adjust print_ops formatting.
Use only 2 spaces for index (there are never 1, the most seen in the wild is 64). Adjust re-indenting after GNU_entry_value. Signed-off-by: Mark Wielaard --- src/ChangeLog | 5 src/readelf.c | 58 - tests/ChangeLog | 7 + tests/run-readelf-dwz-multi.sh | 32 +++ tests/run-readelf-loc.sh| 18 ++--- tests/run-readelf-zdebug-rel.sh | 18 ++--- tests/run-readelf-zdebug.sh | 30 ++--- 7 files changed, 90 insertions(+), 78 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index c56c323..b88c319 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,8 @@ +2017-11-29 Mark Wielaard + + * readelf.c (print_ops): Use only2 space for index. re-indent +5 + for DW_OP_GNU_entry_value. + 2017-11-21 Mark Wielaard * readelf.c (attr_callback): Print attribute name and form in error diff --git a/src/readelf.c b/src/readelf.c index a9168d1..2faa1d5 100644 --- a/src/readelf.c +++ b/src/readelf.c @@ -1,5 +1,5 @@ /* Print information from ELF file in human-readable form. - Copyright (C) 1999-2016 Red Hat, Inc. + Copyright (C) 1999-2017 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper , 1999. @@ -4152,7 +4152,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest, CONSUME (addrsize); char *a = format_dwarf_addr (dwflmod, 0, addr, addr); - printf ("%*s[%4" PRIuMAX "] %s %s\n", + printf ("%*s[%2" PRIuMAX "] %s %s\n", indent, "", (uintmax_t) offset, op_name, a); free (a); @@ -4172,7 +4172,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest, data += ref_size; CONSUME (ref_size); /* addr is a DIE offset, so format it as one. */ - printf ("%*s[%4" PRIuMAX "] %s [%6" PRIxMAX "]\n", + printf ("%*s[%2" PRIuMAX "] %s [%6" PRIxMAX "]\n", indent, "", (uintmax_t) offset, op_name, (uintmax_t) addr); offset += 1 + ref_size; @@ -4184,7 +4184,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest, case DW_OP_const1u: // XXX value might be modified by relocation NEED (1); - printf ("%*s[%4" PRIuMAX "] %s %" PRIu8 "\n", + printf ("%*s[%2" PRIuMAX "] %s %" PRIu8 "\n", indent, "", (uintmax_t) offset, op_name, *((uint8_t *) data)); ++data; @@ -4195,7 +4195,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest, case DW_OP_const2u: NEED (2); // XXX value might be modified by relocation - printf ("%*s[%4" PRIuMAX "] %s %" PRIu16 "\n", + printf ("%*s[%2" PRIuMAX "] %s %" PRIu16 "\n", indent, "", (uintmax_t) offset, op_name, read_2ubyte_unaligned (dbg, data)); CONSUME (2); @@ -4206,7 +4206,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest, case DW_OP_const4u: NEED (4); // XXX value might be modified by relocation - printf ("%*s[%4" PRIuMAX "] %s %" PRIu32 "\n", + printf ("%*s[%2" PRIuMAX "] %s %" PRIu32 "\n", indent, "", (uintmax_t) offset, op_name, read_4ubyte_unaligned (dbg, data)); CONSUME (4); @@ -4217,7 +4217,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest, case DW_OP_const8u: NEED (8); // XXX value might be modified by relocation - printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 "\n", + printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 "\n", indent, "", (uintmax_t) offset, op_name, (uint64_t) read_8ubyte_unaligned (dbg, data)); CONSUME (8); @@ -4228,7 +4228,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest, case DW_OP_const1s: NEED (1); // XXX value might be modified by relocation - printf ("%*s[%4" PRIuMAX "] %s %" PRId8 "\n", + printf ("%*s[%2" PRIuMAX "] %s %" PRId8 "\n", indent, "", (uintmax_t) offset, op_name, *((int8_t *) data)); ++data; @@ -4239,7 +4239,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest, case DW_OP_const2s: NEED (2); // XXX value might be modified by relocation - printf ("%*s[%4" PRIuMAX "] %s %" PRId16 "\n", + printf ("%*s[%2" PRIuMAX "] %s %" PRId16 "\n", indent, "", (uintmax_t) offset, op_name, read_2sbyte_unaligned (dbg, data)); CONSUME (2); @@ -4250,7 +4250,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest, case DW_OP_const4s: NEED (4); // XXX va
[PATCH 2/5] readelf: Print abbrev code for DIE with --debug-dump=info.
If there is anything wrong with a DIE it is useful to know what the abbrev code was so you can lookup the abbrev description. Signed-off-by: Mark Wielaard --- src/ChangeLog | 4 +++ src/readelf.c | 9 --- tests/ChangeLog | 5 tests/run-readelf-dwz-multi.sh | 60 - tests/run-readelf-zdebug-rel.sh | 22 +++ 5 files changed, 56 insertions(+), 44 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index b88c319..e7e598d 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,9 @@ 2017-11-29 Mark Wielaard + * readelf.c (print_debug_units): Print abbrev code after DIE tag. + +2017-11-29 Mark Wielaard + * readelf.c (print_ops): Use only2 space for index. re-indent +5 for DW_OP_GNU_entry_value. diff --git a/src/readelf.c b/src/readelf.c index 2faa1d5..e9887c4 100644 --- a/src/readelf.c +++ b/src/readelf.c @@ -6371,9 +6371,12 @@ print_debug_units (Dwfl_Module *dwflmod, } if (!silent) - printf (" [%6" PRIx64 "] %*s%s\n", - (uint64_t) offset, (int) (level * 2), "", - dwarf_tag_name (tag)); + { + unsigned int code = dwarf_getabbrevcode (dies[level].abbrev); + printf (" [%6" PRIx64 "] %*s%-20s abbrev: %u\n", + (uint64_t) offset, (int) (level * 2), "", + dwarf_tag_name (tag), code); + } /* Print the attribute values. */ args.level = level; diff --git a/tests/ChangeLog b/tests/ChangeLog index 9633cd1..f522a69 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,5 +1,10 @@ 2017-11-29 Mark Wielaard + * run-readelf-dwz-multi.sh: Add expected abbrev codes. + * run-readelf-zdebug-rel.sh: Likewise. + +2017-11-29 Mark Wielaard + * run-readelf-dwz-multi.sh: Adjust expected ops index spaces. * run-readelf-loc.sh: Likewise. * run-readelf-zdebug-rel.sh: Likewise. diff --git a/tests/run-readelf-dwz-multi.sh b/tests/run-readelf-dwz-multi.sh index 139b8c1..21456fd 100755 --- a/tests/run-readelf-dwz-multi.sh +++ b/tests/run-readelf-dwz-multi.sh @@ -84,7 +84,7 @@ DWARF section [28] '.debug_info' at offset 0x1078: [Offset] Compilation unit at offset 0: Version: 4, Abbreviation section offset: 0, Address size: 8, Offset size: 4 - [ b] compile_unit + [ b] compile_unit abbrev: 6 producer (strp) "GNU C 4.7.0 20120507 (Red Hat 4.7.0-5) -mtune=generic -march=x86-64 -g" language (data1) C89 (1) name (strp) "main.c" @@ -92,12 +92,12 @@ DWARF section [28] '.debug_info' at offset 0x1078: low_pc (addr) 0x004006ac high_pc (udata) 44 (0x004006d8) stmt_list(sec_offset) 0 - [26]imported_unit + [26]imported_unitabbrev: 5 import (GNU_ref_alt) [ b] - [2b]pointer_type + [2b]pointer_type abbrev: 1 byte_size(data1) 8 type (GNU_ref_alt) [53] - [31]subprogram + [31]subprogram abbrev: 3 external (flag_present) yes name (strp) "main" decl_file(data1) 1 @@ -110,28 +110,28 @@ DWARF section [28] '.debug_info' at offset 0x1078: [ 0] call_frame_cfa GNU_all_tail_call_sites (flag_present) yes sibling (ref_udata) [6e] - [48] formal_parameter + [48] formal_parameter abbrev: 8 name (strp) "argc" decl_file(data1) 1 decl_line(data1) 3 type (GNU_ref_alt) [3e] location (exprloc) [ 0] fbreg -36 - [56] formal_parameter + [56] formal_parameter abbrev: 4 name (strp) "argv" decl_file(data1) 1 decl_line(data1) 3 type (ref_udata) [6e] location (exprloc) [ 0] fbreg -48 - [61] variable + [61] variable abbrev: 7 name (string) "b" decl_file(data1) 1 decl_line(data1) 5 type (GNU_ref_alt) [5a] location (exprloc) [ 0] fbreg -32 - [6e]pointer_type + [6e]pointer_type abbrev: 2 byte_size(data1) 8 type (ref_udata) [2b] EOF @@ -145,7 +145,7 @@ DWARF section [28] '.debug_info' at offset 0x1078: [Offset] Compilat
Various eu-readelf --debug-dump improvements
While working on the DWARF5 support I found various cases where the eu-readelf --debug-dump could be improved to provide a bit more information that helped debug issues. The following changes are not DWARF5 specific, but improve the --debug-dump output to make a more useful (IMHO). [PATCH 1/5] readelf: Adjust print_ops formatting. This simply makes the DWARF expressions a little more compact and the indenting a bit more consistent. In particular it only uses two space for the operand index (the max I found in the wild was 64, so reserving 4 spaces for possibly indexes seemed excessive. [PATCH 2/5] readelf: Print abbrev code for DIE with --debug-dump=info. This was really convenient when there seemed something wrong with the DIE information. It is also helpful to see how many DIEs share a particular abbrev. The output is now: [29]base_typeabbrev: 74 byte_size(data1) 8 encoding (data1) unsigned (7) name (strp) "long unsigned int" So you can easily lookup the corresponding abbrev with --debug-dump=abbrev [ 74] offset: 1019, children: no, tag: base_type attr: byte_size, form: data1, offset: 0x3fb attr: encoding, form: data1, offset: 0x3fd attr: name, form: strp, offset: 0x3ff And note that almost all base_types share the same abbrev code. [PATCH 3/5] readelf: Print actual file for decl_file and call_file. This was very helpful to understand where something was really defined. It simply resolves the file number from the stmt list, so you don't have to do that by hand anymore. New output: [4c]typedef abbrev: 26 name (strp) "size_t" decl_file(data1) stddef.h (13) decl_line(data1) 216 decl_column (data1) 23 type (ref4) [29] [PATCH 4/5] readelf: Print CU, base address and unresolved .debug_ranges. We helpfully resolve the addresses to actual symbol+offsets whenever possible, but this kind of obscured what the actual encoding was. And it made the output a bit messy because addresses didn't line up. It now also prints out the associated CU and the base address to the range list. CU [ 3582e] base: 0x0041de70 [ c370] range 2a, 6a 0x0041de9a .. 0x0041ded9 range 80, e5 0x0041def0 .. 0x0041df54 range f8, 11a 0x0041df68 .. 0x0041df89 [ c3b0] range 91, 9f 0x0041df01 .. 0x0041df0e range a3, a6 0x0041df13 .. 0x0041df15 [PATCH 5/5] readelf: Print CU, base address and unresolved .debug_loc. Like the .debug_ranges change, but including location list entries. The new output is (IMHO) a big improvement: CU [ 4a404] base: 0x0041f350 <__popcountdi2> [ 3c3e2] range 0, 24 0x0041f350 <__popcountdi2>.. 0x0041f373 <__popcountdi2+0x23> [ 0] reg5 range 24, 2b 0x0041f374 <__popcountdi2+0x24>.. 0x0041f37a <__popcountdi2+0x2a> [ 0] reg5 range 2b, 2e 0x0041f37b <__popcountdi2+0x2b>.. 0x0041f37d <__popcountdi2+0x2d> [ 0] reg0 range 2e, 3e 0x0041f37e <__popcountdi2+0x2e>.. 0x0041f38d <__popcountdi2+0x3d> [ 0] GNU_entry_value: [ 0] reg5 [ 3] GNU_entry_value: [ 0] reg5 [ 6] lit1 [ 7] shr [ 8] constu 6148914691236517205 [18] and [19] minus [20] stack_value range 3e, 48 0x0041f38e <__popcountdi2+0x3e>.. 0x0041f397 <__popcountdi2+0x47> [ 0] reg5 range 48, 4b 0x0041f398 <__popcountdi2+0x48>.. 0x0041f39a <__popcountdi2+0x4a> [ 0] breg0 0 [ 2] constu 1085102592571150095 [12] and [13] stack_value range 4b, 59 0x0041f39b <__popcountdi2+0x4b>.. 0x0041f3a8 <__popcountdi2+0x58> [ 0] reg0 range 59, 5e 0x0041f3a9 <__popcountdi2+0x59>.. 0x0041f3ad <__popcountdi2+0x5d> [ 0] breg5 0 [ 2] lit4 [ 3] shr [ 4] breg5 0 [ 6] plus [ 7] constu 1085102592571150095 [17] and [18] stack_value
[PATCH 5/5] readelf: Print CU, base address and unresolved .debug_loc entries.
Also adjust the formatting for the resolved addresses to print them on separate lines so they nicely line up even when the addresses are resolved to symbol+offset names. And print the operands starting on a new line. Signed-off-by: Mark Wielaard --- src/ChangeLog | 5 src/readelf.c | 51 ++--- tests/ChangeLog | 6 + tests/run-readelf-loc.sh| 51 + tests/run-readelf-zdebug-rel.sh | 17 +- tests/run-readelf-zdebug.sh | 17 +- 6 files changed, 112 insertions(+), 35 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 3dd80fb..612b365 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,10 @@ 2017-11-29 Mark Wielaard + * readelf.c (print_debug_loc_section): Print CU base and unresolved + addresses. Adjust formatting. + +2017-11-29 Mark Wielaard + * readelf.c (print_debug_ranges_section): Print CU base and unresolved addresses. Adjust formatting. diff --git a/src/readelf.c b/src/readelf.c index 8e13462..bb48af9 100644 --- a/src/readelf.c +++ b/src/readelf.c @@ -7130,19 +7130,36 @@ print_debug_loc_section (Dwfl_Module *dwflmod, uint_fast8_t offset_size = 4; bool first = true; - struct Dwarf_CU *cu = NULL; Dwarf_Addr base = 0; unsigned char *readp = data->d_buf; unsigned char *const endp = (unsigned char *) data->d_buf + data->d_size; + Dwarf_CU *last_cu = NULL; while (readp < endp) { ptrdiff_t offset = readp - (unsigned char *) data->d_buf; + Dwarf_CU *cu; if (first && skip_listptr_hole (&known_loclistptr, &listptr_idx, &address_size, &offset_size, &base, &cu, offset, &readp, endp)) continue; + if (last_cu != cu) + { + char *basestr = format_dwarf_addr (dwflmod, address_size, + base, base); + Dwarf_Die cudie; + if (dwarf_cu_die (cu, &cudie, + NULL, NULL, NULL, NULL, + NULL, NULL) == NULL) + printf (gettext ("\n Unknown CU base: %s\n"), basestr); + else + printf (gettext ("\n CU [%6" PRIx64 "] base: %s\n"), + dwarf_dieoffset (&cudie), basestr); + free (basestr); + } + last_cu = cu; + if (unlikely (data->d_size - offset < (size_t) address_size * 2)) { printf (gettext (" [%6tx] \n"), offset); @@ -7167,14 +7184,14 @@ print_debug_loc_section (Dwfl_Module *dwflmod, if (begin == (Dwarf_Addr) -1l) /* Base address entry. */ { char *b = format_dwarf_addr (dwflmod, address_size, end, end); - printf (gettext (" [%6tx] base address %s\n"), offset, b); + printf (gettext (" [%6tx] base address\n %s\n"), offset, b); free (b); base = end; } else if (begin == 0 && end == 0) /* End of list entry. */ { if (first) - printf (gettext (" [%6tx] empty list\n"), offset); + printf (gettext (" [%6tx] empty list\n"), offset); first = true; } else @@ -7182,18 +7199,23 @@ print_debug_loc_section (Dwfl_Module *dwflmod, /* We have a location expression entry. */ uint_fast16_t len = read_2ubyte_unaligned_inc (dbg, readp); - char *b = format_dwarf_addr (dwflmod, address_size, base + begin, - begin); - char *e = format_dwarf_addr (dwflmod, address_size, base + end, - end); - if (first)/* First entry in a list. */ - printf (gettext (" [%6tx] %s..%s"), offset, b, e); + printf (" [%6tx] ", offset); else - printf (gettext (" %s..%s"), b, e); + printf (" "); - free (b); - free (e); + printf ("range %" PRIx64 ", %" PRIx64 "\n", begin, end); + if (! print_unresolved_addresses) + { + char *b = format_dwarf_addr (dwflmod, address_size, base + begin, + base + begin); + char *e = format_dwarf_addr (dwflmod, address_size, + base + end - 1, base + end); + printf (" %s..\n", b); + printf (" %s\n", e); + free (b); + free (e); + } if (endp - readp <= (ptrdiff_t) len) { @@ -7201,8 +7223,9 @@ print_debug_loc_section (Dwfl_Module *dwflmod, break; } - print_ops (dwflmod, dbg, 1, 18 + (address_size * 4), -3 /*XXX*/, address_size, offset_size, cu, len, readp); + print_ops (dwflmod, dbg, 11, 11, +cu != NULL ? cu->version : 3, +
[PATCH] readelf: Hook up -g, --section-groups to display the section groups.
It was already possible to display the section groups using -a, but the argp options didn't yet have an -g, --section-groups entry to just display the section groups. Signed-off-by: Mark Wielaard --- src/ChangeLog | 4 src/readelf.c | 1 + 2 files changed, 5 insertions(+) diff --git a/src/ChangeLog b/src/ChangeLog index c56c323c..78def6ea 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,7 @@ +2017-11-29 Mark Wielaard + + * readelf.c (argp_options): Add "section-groups", 'g'. + 2017-11-21 Mark Wielaard * readelf.c (attr_callback): Print attribute name and form in error diff --git a/src/readelf.c b/src/readelf.c index a9168d1e..82fc7b6f 100644 --- a/src/readelf.c +++ b/src/readelf.c @@ -98,6 +98,7 @@ static const struct argp_option options[] = { "program-headers", 'l', NULL, 0, N_("Display the program headers"), 0 }, { "segments", 'l', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 0 }, { "relocs", 'r', NULL, 0, N_("Display relocations"), 0 }, + { "section-groups", 'g', NULL, 0, N_("Display the section groups"), 0 }, { "section-headers", 'S', NULL, 0, N_("Display the sections' headers"), 0 }, { "sections", 'S', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 0 }, { "symbols", 's', "SECTION", OPTION_ARG_OPTIONAL, -- 2.14.3