[PATCH 4/5] readelf: Print CU, base address and unresolved .debug_range entries.

2017-11-29 Thread Mark Wielaard
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.

2017-11-29 Thread Mark Wielaard
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.

2017-11-29 Thread Mark Wielaard
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.

2017-11-29 Thread Mark Wielaard
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

2017-11-29 Thread Mark Wielaard
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.

2017-11-29 Thread Mark Wielaard
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.

2017-11-29 Thread Mark Wielaard
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