Blob Blame History Raw
commit 704f5fc477efaf120980449e677deb563da8491f
Author: Mark Wielaard <mark@klomp.org>
Date:   Wed Nov 29 15:43:26 2017 +0100

    readelf: Adjust print_ops formatting.
    
    Use only 2 spaces for index (there are never 10000, the most seen in the
    wild is 64). Adjust re-indenting after GNU_entry_value.
    
    Signed-off-by: Mark Wielaard <mark@klomp.org>

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 <drepper@redhat.com>, 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 value might be modified by relocation
-	  printf ("%*s[%4" PRIuMAX "] %s %" PRId32 "\n",
+	  printf ("%*s[%2" PRIuMAX "] %s %" PRId32 "\n",
 		  indent, "", (uintmax_t) offset,
 		  op_name, read_4sbyte_unaligned (dbg, data));
 	  CONSUME (4);
@@ -4261,7 +4261,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
 	case DW_OP_const8s:
 	  NEED (8);
 	  // XXX value might be modified by relocation
-	  printf ("%*s[%4" PRIuMAX "] %s %" PRId64 "\n",
+	  printf ("%*s[%2" PRIuMAX "] %s %" PRId64 "\n",
 		  indent, "", (uintmax_t) offset,
 		  op_name, read_8sbyte_unaligned (dbg, data));
 	  CONSUME (8);
@@ -4277,7 +4277,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
 	  uint64_t uleb;
 	  NEED (1);
 	  get_uleb128 (uleb, data, data + len);
-	  printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 "\n",
+	  printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 "\n",
 		  indent, "", (uintmax_t) offset, op_name, uleb);
 	  CONSUME (data - start);
 	  offset += 1 + (data - start);
@@ -4290,7 +4290,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
 	  get_uleb128 (uleb, data, data + len);
 	  NEED (1);
 	  get_uleb128 (uleb2, data, data + len);
-	  printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 ", %" PRIu64 "\n",
+	  printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 ", %" PRIu64 "\n",
 		  indent, "", (uintmax_t) offset, op_name, uleb, uleb2);
 	  CONSUME (data - start);
 	  offset += 1 + (data - start);
@@ -4303,7 +4303,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
 	  int64_t sleb;
 	  NEED (1);
 	  get_sleb128 (sleb, data, data + len);
-	  printf ("%*s[%4" PRIuMAX "] %s %" PRId64 "\n",
+	  printf ("%*s[%2" PRIuMAX "] %s %" PRId64 "\n",
 		  indent, "", (uintmax_t) offset, op_name, sleb);
 	  CONSUME (data - start);
 	  offset += 1 + (data - start);
@@ -4315,7 +4315,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
 	  get_uleb128 (uleb, data, data + len);
 	  NEED (1);
 	  get_sleb128 (sleb, data, data + len);
-	  printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 " %" PRId64 "\n",
+	  printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 " %" PRId64 "\n",
 		  indent, "", (uintmax_t) offset, op_name, uleb, sleb);
 	  CONSUME (data - start);
 	  offset += 1 + (data - start);
@@ -4323,7 +4323,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
 
 	case DW_OP_call2:
 	  NEED (2);
-	  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);
@@ -4332,7 +4332,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
 
 	case DW_OP_call4:
 	  NEED (4);
-	  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);
@@ -4342,7 +4342,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
 	case DW_OP_skip:
 	case DW_OP_bra:
 	  NEED (2);
-	  printf ("%*s[%4" PRIuMAX "] %s %" PRIuMAX "\n",
+	  printf ("%*s[%2" PRIuMAX "] %s %" PRIuMAX "\n",
 		  indent, "", (uintmax_t) offset, op_name,
 		  (uintmax_t) (offset + read_2sbyte_unaligned (dbg, data) + 3));
 	  CONSUME (2);
@@ -4354,7 +4354,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
 	  start = data;
 	  NEED (1);
 	  get_uleb128 (uleb, data, data + len);
-	  printf ("%*s[%4" PRIuMAX "] %s: ",
+	  printf ("%*s[%2" PRIuMAX "] %s: ",
 		  indent, "", (uintmax_t) offset, op_name);
 	  NEED (uleb);
 	  print_block (uleb, data);
@@ -4378,7 +4378,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
 	  NEED (1);
 	  get_sleb128 (sleb, data, data + len);
 
-	  printf ("%*s[%4" PRIuMAX "] %s [%6" PRIxMAX "] %+" PRId64 "\n",
+	  printf ("%*s[%2" PRIuMAX "] %s [%6" PRIxMAX "] %+" PRId64 "\n",
 		  indent, "", (intmax_t) offset,
 		  op_name, (uintmax_t) addr, sleb);
 	  CONSUME (data - start);
@@ -4390,10 +4390,10 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
 	  start = data;
 	  NEED (1);
 	  get_uleb128 (uleb, data, data + len);
-	  printf ("%*s[%4" PRIuMAX "] %s:\n",
+	  printf ("%*s[%2" PRIuMAX "] %s:\n",
 		  indent, "", (uintmax_t) offset, op_name);
 	  NEED (uleb);
-	  print_ops (dwflmod, dbg, indent + 6, indent + 6, vers,
+	  print_ops (dwflmod, dbg, indent + 5, indent + 5, vers,
 		     addrsize, offset_size, cu, uleb, data);
 	  data += uleb;
 	  CONSUME (data - start);
@@ -4411,7 +4411,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
 	  NEED (1);
 	  uint8_t usize = *(uint8_t *) data++;
 	  NEED (usize);
-	  printf ("%*s[%4" PRIuMAX "] %s [%6" PRIxMAX "] ",
+	  printf ("%*s[%2" PRIuMAX "] %s [%6" PRIxMAX "] ",
 		  indent, "", (uintmax_t) offset, op_name, uleb);
 	  print_block (usize, data);
 	  data += usize;
@@ -4429,7 +4429,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
 	  get_uleb128 (uleb2, data, data + len);
 	  if (! print_unresolved_addresses && cu != NULL)
 	    uleb2 += cu->start;
-	  printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 " [%6" PRIx64 "]\n",
+	  printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 " [%6" PRIx64 "]\n",
 		  indent, "", (uintmax_t) offset, op_name, uleb, uleb2);
 	  CONSUME (data - start);
 	  offset += 1 + (data - start);
@@ -4445,7 +4445,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
 	  get_uleb128 (uleb, data, data + len);
 	  if (! print_unresolved_addresses && cu != NULL)
 	    uleb += cu->start;
-	  printf ("%*s[%4" PRIuMAX "] %s %" PRIu8 " [%6" PRIxMAX "]\n",
+	  printf ("%*s[%2" PRIuMAX "] %s %" PRIu8 " [%6" PRIxMAX "]\n",
 		  indent, "", (uintmax_t) offset,
 		  op_name, usize, uleb);
 	  CONSUME (data - start);
@@ -4461,7 +4461,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
 	  get_uleb128 (uleb, data, data + len);
 	  if (uleb != 0 && ! print_unresolved_addresses && cu != NULL)
 	    uleb += cu->start;
-	  printf ("%*s[%4" PRIuMAX "] %s [%6" PRIxMAX "]\n",
+	  printf ("%*s[%2" PRIuMAX "] %s [%6" PRIxMAX "]\n",
 		  indent, "", (uintmax_t) offset, op_name, uleb);
 	  CONSUME (data - start);
 	  offset += 1 + (data - start);
@@ -4474,7 +4474,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
 	  uintmax_t param_off = (uintmax_t) read_4ubyte_unaligned (dbg, data);
 	  if (! print_unresolved_addresses && cu != NULL)
 	    param_off += cu->start;
-	  printf ("%*s[%4" PRIuMAX "] %s [%6" PRIxMAX "]\n",
+	  printf ("%*s[%2" PRIuMAX "] %s [%6" PRIxMAX "]\n",
 		  indent, "", (uintmax_t) offset, op_name, param_off);
 	  CONSUME (4);
 	  data += 4;
@@ -4483,7 +4483,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
 
 	default:
 	  /* No Operand.  */
-	  printf ("%*s[%4" PRIuMAX "] %s\n",
+	  printf ("%*s[%2" PRIuMAX "] %s\n",
 		  indent, "", (uintmax_t) offset, op_name);
 	  ++offset;
 	  break;
@@ -4493,7 +4493,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
       continue;
 
     invalid:
-      printf (gettext ("%*s[%4" PRIuMAX "] %s  <TRUNCATED>\n"),
+      printf (gettext ("%*s[%2" PRIuMAX "] %s  <TRUNCATED>\n"),
 	      indent, "", (uintmax_t) offset, op_name);
       break;
     }
diff --git a/tests/run-readelf-dwz-multi.sh b/tests/run-readelf-dwz-multi.sh
index 23ca944..139b8c1 100755
--- a/tests/run-readelf-dwz-multi.sh
+++ b/tests/run-readelf-dwz-multi.sh
@@ -107,7 +107,7 @@ DWARF section [28] '.debug_info' at offset 0x1078:
              low_pc               (addr) 0x00000000004006ac <main>
              high_pc              (udata) 44 (0x00000000004006d8)
              frame_base           (exprloc) 
-              [   0] call_frame_cfa
+              [ 0] call_frame_cfa
              GNU_all_tail_call_sites (flag_present) yes
              sibling              (ref_udata) [    6e]
  [    48]      formal_parameter
@@ -116,21 +116,21 @@ DWARF section [28] '.debug_info' at offset 0x1078:
                decl_line            (data1) 3
                type                 (GNU_ref_alt) [    3e]
                location             (exprloc) 
-                [   0] fbreg -36
+                [ 0] fbreg -36
  [    56]      formal_parameter
                name                 (strp) "argv"
                decl_file            (data1) 1
                decl_line            (data1) 3
                type                 (ref_udata) [    6e]
                location             (exprloc) 
-                [   0] fbreg -48
+                [ 0] fbreg -48
  [    61]      variable
                name                 (string) "b"
                decl_file            (data1) 1
                decl_line            (data1) 5
                type                 (GNU_ref_alt) [    5a]
                location             (exprloc) 
-                [   0] fbreg -32
+                [ 0] fbreg -32
  [    6e]    pointer_type
              byte_size            (data1) 8
              type                 (ref_udata) [    2b]
@@ -168,7 +168,7 @@ DWARF section [28] '.debug_info' at offset 0x1078:
              low_pc               (addr) 0x00000000004006ac <main>
              high_pc              (udata) 44 (0x00000000004006d8)
              frame_base           (exprloc) 
-              [   0] call_frame_cfa
+              [ 0] call_frame_cfa
              GNU_all_tail_call_sites (flag_present) yes
              sibling              (ref_udata) [    6e]
  [    48]      formal_parameter
@@ -177,21 +177,21 @@ DWARF section [28] '.debug_info' at offset 0x1078:
                decl_line            (data1) 3
                type                 (GNU_ref_alt) [    3e]
                location             (exprloc) 
-                [   0] fbreg -36
+                [ 0] fbreg -36
  [    56]      formal_parameter
                name                 (strp) "argv"
                decl_file            (data1) 1
                decl_line            (data1) 3
                type                 (ref_udata) [    6e]
                location             (exprloc) 
-                [   0] fbreg -48
+                [ 0] fbreg -48
  [    61]      variable
                name                 (string) "b"
                decl_file            (data1) 1
                decl_line            (data1) 5
                type                 (GNU_ref_alt) [    5a]
                location             (exprloc) 
-                [   0] fbreg -32
+                [ 0] fbreg -32
  [    6e]    pointer_type
              byte_size            (data1) 8
              type                 (ref_udata) [    2b]
@@ -225,7 +225,7 @@ DWARF section [25] '.debug_info' at offset 0x106c:
              low_pc               (addr) +0x0000000000000670 <call_foo>
              high_pc              (udata) 23 (+0x0000000000000687)
              frame_base           (exprloc) 
-              [   0] call_frame_cfa
+              [ 0] call_frame_cfa
              GNU_all_call_sites   (flag_present) yes
  [    41]      formal_parameter
                name                 (string) "fb"
@@ -233,7 +233,7 @@ DWARF section [25] '.debug_info' at offset 0x106c:
                decl_line            (data1) 3
                type                 (GNU_ref_alt) [    76]
                location             (exprloc) 
-                [   0] fbreg -24
+                [ 0] fbreg -24
 EOF
 
 # Same as above, but find alt debug file in a .dwz subdir.
@@ -265,7 +265,7 @@ DWARF section [25] '.debug_info' at offset 0x106c:
              low_pc               (addr) +0x0000000000000670 <call_foo>
              high_pc              (udata) 23 (+0x0000000000000687)
              frame_base           (exprloc) 
-              [   0] call_frame_cfa
+              [ 0] call_frame_cfa
              GNU_all_call_sites   (flag_present) yes
  [    41]      formal_parameter
                name                 (string) "fb"
@@ -273,7 +273,7 @@ DWARF section [25] '.debug_info' at offset 0x106c:
                decl_line            (data1) 3
                type                 (GNU_ref_alt) [    76]
                location             (exprloc) 
-                [   0] fbreg -24
+                [ 0] fbreg -24
 EOF
 mv .dwz/testfile_multi.dwz .
 rmdir .dwz
@@ -304,7 +304,7 @@ DWARF section [28] '.debug_info' at offset 0x1088:
              low_pc               (addr) 0x00000000004004ec <main>
              high_pc              (udata) 18 (0x00000000004004fe)
              frame_base           (exprloc) 
-              [   0] call_frame_cfa
+              [ 0] call_frame_cfa
              GNU_all_call_sites   (flag_present) yes
  [    41]      formal_parameter
                name                 (GNU_strp_alt) "argc"
@@ -312,21 +312,21 @@ DWARF section [28] '.debug_info' at offset 0x1088:
                decl_line            (data1) 8
                type                 (GNU_ref_alt) [    30]
                location             (exprloc) 
-                [   0] fbreg -36
+                [ 0] fbreg -36
  [    4f]      formal_parameter
                name                 (GNU_strp_alt) "argv"
                decl_file            (data1) 1
                decl_line            (data1) 8
                type                 (GNU_ref_alt) [    41]
                location             (exprloc) 
-                [   0] fbreg -48
+                [ 0] fbreg -48
  [    5d]      variable
                name                 (string) "fbb"
                decl_file            (data1) 1
                decl_line            (data1) 10
                type                 (GNU_ref_alt) [    14]
                location             (exprloc) 
-                [   0] fbreg -32
+                [ 0] fbreg -32
 EOF
 
 exit 0
diff --git a/tests/run-readelf-loc.sh b/tests/run-readelf-loc.sh
index 98870fc..3959d3d 100755
--- a/tests/run-readelf-loc.sh
+++ b/tests/run-readelf-loc.sh
@@ -63,9 +63,9 @@ testrun_compare ${abs_top_builddir}/src/readelf --debug-dump=loc --debug-dump=ra
   testfileloc<<\EOF
 
 DWARF section [33] '.debug_loc' at offset 0xd2a:
- [     0]  0x0000000000400480 <main>..0x000000000040048d <main+0xd> [   0] reg5
- [    23]  0x0000000000400485 <main+0x5>..0x000000000040048d <main+0xd> [   0] reg5
- [    46]  0x00000000004004b2 <say+0x12>..0x00000000004004ba <say+0x1a> [   0] breg5 0
+ [     0]  0x0000000000400480 <main>..0x000000000040048d <main+0xd> [ 0] reg5
+ [    23]  0x0000000000400485 <main+0x5>..0x000000000040048d <main+0xd> [ 0] reg5
+ [    46]  0x00000000004004b2 <say+0x12>..0x00000000004004ba <say+0x1a> [ 0] breg5 0
 
 DWARF section [34] '.debug_ranges' at offset 0xd94:
  [     0]  0x0000000000400480 <main>..0x0000000000400482 <main+0x2>
@@ -79,9 +79,9 @@ testrun_compare ${abs_top_builddir}/src/readelf -N --debug-dump=loc --debug-dump
   testfileloc<<\EOF
 
 DWARF section [33] '.debug_loc' at offset 0xd2a:
- [     0]  0x0000000000400480..0x000000000040048d [   0] reg5
- [    23]  0x0000000000400485..0x000000000040048d [   0] reg5
- [    46]  0x00000000004004b2..0x00000000004004ba [   0] breg5 0
+ [     0]  0x0000000000400480..0x000000000040048d [ 0] reg5
+ [    23]  0x0000000000400485..0x000000000040048d [ 0] reg5
+ [    46]  0x00000000004004b2..0x00000000004004ba [ 0] breg5 0
 
 DWARF section [34] '.debug_ranges' at offset 0xd94:
  [     0]  0x0000000000400480..0x0000000000400482
@@ -95,9 +95,9 @@ testrun_compare ${abs_top_builddir}/src/readelf -U --debug-dump=loc --debug-dump
   testfileloc<<\EOF
 
 DWARF section [33] '.debug_loc' at offset 0xd2a:
- [     0]  000000000000000000..0x000000000000000d [   0] reg5
- [    23]  0x0000000000000005..0x000000000000000d [   0] reg5
- [    46]  0x0000000000000012..0x000000000000001a [   0] breg5 0
+ [     0]  000000000000000000..0x000000000000000d [ 0] reg5
+ [    23]  0x0000000000000005..0x000000000000000d [ 0] reg5
+ [    46]  0x0000000000000012..0x000000000000001a [ 0] breg5 0
 
 DWARF section [34] '.debug_ranges' at offset 0xd94:
  [     0]  000000000000000000..0x0000000000000002
diff --git a/tests/run-readelf-zdebug-rel.sh b/tests/run-readelf-zdebug-rel.sh
index 1232d63..082971e 100755
--- a/tests/run-readelf-zdebug-rel.sh
+++ b/tests/run-readelf-zdebug-rel.sh
@@ -69,7 +69,7 @@ DWARF section [ 4] '.debug_info' at offset 0x58:
              low_pc               (addr) 000000000000000000
              high_pc              (data8) 24 (0x0000000000000018)
              frame_base           (exprloc) 
-              [   0] call_frame_cfa
+              [ 0] call_frame_cfa
              GNU_all_call_sites   (flag_present) yes
              sibling              (ref4) [    80]
  [    4e]      formal_parameter
@@ -84,7 +84,7 @@ DWARF section [ 4] '.debug_info' at offset 0x58:
                decl_line            (data1) 4
                type                 (ref4) [    87]
                location             (exprloc) 
-                [   0] reg4
+                [ 0] reg4
  [    6a]      variable
                name                 (string) "a"
                decl_file            (data1) 1
@@ -97,7 +97,7 @@ DWARF section [ 4] '.debug_info' at offset 0x58:
                decl_line            (data1) 7
                type                 (ref4) [    9a]
                location             (exprloc) 
-                [   0] reg5
+                [ 0] reg5
  [    80]    base_type
              byte_size            (data1) 4
              encoding             (data1) signed (5)
@@ -127,12 +127,12 @@ cat info.out | testrun_compare ${abs_top_builddir}/src/readelf -U --debug-dump=i
 cat > loc.out << \EOF
 
 DWARF section [ 7] '.debug_loc' at offset 0x185:
- [     0]  000000000000000000..0x0000000000000003 [   0] reg5
-           0x0000000000000003..0x0000000000000010 [   0] breg5 -42
-                                                  [   2] stack_value
-           0x0000000000000010..0x0000000000000018 [   0] GNU_entry_value:
-       [   0] reg5
-                                                  [   3] stack_value
+ [     0]  000000000000000000..0x0000000000000003 [ 0] reg5
+           0x0000000000000003..0x0000000000000010 [ 0] breg5 -42
+                                                  [ 2] stack_value
+           0x0000000000000010..0x0000000000000018 [ 0] GNU_entry_value:
+      [ 0] reg5
+                                                  [ 3] stack_value
 EOF
 
 cat loc.out | testrun_compare ${abs_top_builddir}/src/readelf -U --debug-dump=loc testfile-debug-rel.o
diff --git a/tests/run-readelf-zdebug.sh b/tests/run-readelf-zdebug.sh
index 37cf7ea..fc666fd 100755
--- a/tests/run-readelf-zdebug.sh
+++ b/tests/run-readelf-zdebug.sh
@@ -46,12 +46,12 @@ tempfiles loc.out aranges.out ranges.out macro.out line.out frame.out
 cat > loc.out << \EOF
 
 DWARF section [30] '.debug_loc' at offset 0xa17:
- [     0]  0x00000000004003c0..0x00000000004003c3 [   0] reg5
-           0x00000000004003c3..0x00000000004003d6 [   0] breg5 -42
-                                                  [   2] stack_value
-           0x00000000004003d6..0x00000000004003d9 [   0] GNU_entry_value:
-       [   0] reg5
-                                                  [   3] stack_value
+ [     0]  0x00000000004003c0..0x00000000004003c3 [ 0] reg5
+           0x00000000004003c3..0x00000000004003d6 [ 0] breg5 -42
+                                                  [ 2] stack_value
+           0x00000000004003d6..0x00000000004003d9 [ 0] GNU_entry_value:
+      [ 0] reg5
+                                                  [ 3] stack_value
 EOF
 
 cat loc.out | testrun_compare ${abs_top_builddir}/src/readelf -U --debug-dump=loc testfile-debug
@@ -476,15 +476,15 @@ Call frame information section [16] '.eh_frame' at offset 0x5b8:
      def_cfa_offset 24
      advance_loc 10 to 0x3b0
      def_cfa_expression 11
-          [   0] breg7 8
-          [   2] breg16 0
-          [   4] lit15
-          [   5] and
-          [   6] lit11
-          [   7] ge
-          [   8] lit3
-          [   9] shl
-          [  10] plus
+          [ 0] breg7 8
+          [ 2] breg16 0
+          [ 4] lit15
+          [ 5] and
+          [ 6] lit11
+          [ 7] ge
+          [ 8] lit3
+          [ 9] shl
+          [10] plus
      nop
      nop
      nop

commit 36eabdb739b16b934afe318c786a97c94b47bbf6
Author: Mark Wielaard <mark@klomp.org>
Date:   Wed Nov 29 16:27:33 2017 +0100

    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 <mark@klomp.org>

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]  <INVALID DATA>\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/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 [33] '.debug_loc' at offset 0xd2a:
  [    46]  0x00000000004004b2 <say+0x12>..0x00000000004004ba <say+0x1a> [ 0] breg5 0
 
 DWARF section [34] '.debug_ranges' at offset 0xd94:
- [     0]  0x0000000000400480 <main>..0x0000000000400482 <main+0x2>
-           0x0000000000400485 <main+0x5>..0x000000000040048d <main+0xd>
- [    30]  0x00000000004004ad <say+0xd>..0x00000000004004af <say+0xf>
-           0x00000000004004b2 <say+0x12>..0x00000000004004ba <say+0x1a>
+
+ CU [     b] base: 0x0000000000400480 <main>
+ [     0] range 0, 2
+          0x0000000000400480 <main>..
+          0x0000000000400481 <main+0x1>
+          range 5, d
+          0x0000000000400485 <main+0x5>..
+          0x000000000040048c <main+0xc>
+
+ CU [    e0] base: 0x00000000004004a0 <say>
+ [    30] range d, f
+          0x00000000004004ad <say+0xd>..
+          0x00000000004004ae <say+0xe>
+          range 12, 1a
+          0x00000000004004b2 <say+0x12>..
+          0x00000000004004b9 <say+0x19>
 EOF
 
 # Don't resolve addresses to symbols.
@@ -84,10 +96,22 @@ DWARF section [33] '.debug_loc' at offset 0xd2a:
  [    46]  0x00000000004004b2..0x00000000004004ba [ 0] breg5 0
 
 DWARF section [34] '.debug_ranges' at offset 0xd94:
- [     0]  0x0000000000400480..0x0000000000400482
-           0x0000000000400485..0x000000000040048d
- [    30]  0x00000000004004ad..0x00000000004004af
-           0x00000000004004b2..0x00000000004004ba
+
+ CU [     b] base: 0x0000000000400480
+ [     0] range 0, 2
+          0x0000000000400480..
+          0x0000000000400481
+          range 5, d
+          0x0000000000400485..
+          0x000000000040048c
+
+ CU [    e0] base: 0x00000000004004a0
+ [    30] range d, f
+          0x00000000004004ad..
+          0x00000000004004ae
+          range 12, 1a
+          0x00000000004004b2..
+          0x00000000004004b9
 EOF
 
 # Produce "raw" unprocessed content.
@@ -100,10 +124,14 @@ DWARF section [33] '.debug_loc' at offset 0xd2a:
  [    46]  0x0000000000000012..0x000000000000001a [ 0] breg5 0
 
 DWARF section [34] '.debug_ranges' at offset 0xd94:
- [     0]  000000000000000000..0x0000000000000002
-           0x0000000000000005..0x000000000000000d
- [    30]  0x000000000000000d..0x000000000000000f
-           0x0000000000000012..0x000000000000001a
+
+ CU [     b] base: 0x0000000000400480
+ [     0] range 0, 2
+          range 5, d
+
+ CU [    e0] base: 0x00000000004004a0
+ [    30] range d, f
+          range 12, 1a
 EOF
 
 exit 0
diff --git a/tests/run-readelf-zdebug.sh b/tests/run-readelf-zdebug.sh
index fc666fd..7be9bee 100755
--- a/tests/run-readelf-zdebug.sh
+++ b/tests/run-readelf-zdebug.sh
@@ -80,7 +80,9 @@ cat aranges.out | sed -e "s/.debug_aranges' at offset 0xa65/.zdebug_aranges' at
 cat > ranges.out << \EOF
 
 DWARF section [32] '.debug_ranges' at offset 0xa95:
- [     0]  0x00000000004003c0..0x00000000004003d9
+
+ CU [     b] base: 000000000000000000
+ [     0] range 4003c0, 4003d9
 EOF
 
 cat ranges.out | testrun_compare ${abs_top_builddir}/src/readelf -U --debug-dump=ranges testfile-debug

commit fbb6c932e3ff74d4fb8bc54b72d9c9bdc4513f69
Author: Mark Wielaard <mark@klomp.org>
Date:   Wed Nov 29 16:37:50 2017 +0100

    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 <mark@klomp.org>

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]  <INVALID DATA>\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,
+		     address_size, offset_size, cu, len, readp);
 
 	  first = false;
 	  readp += len;
diff --git a/tests/run-readelf-loc.sh b/tests/run-readelf-loc.sh
index 4b666cf..e5152df 100755
--- a/tests/run-readelf-loc.sh
+++ b/tests/run-readelf-loc.sh
@@ -63,9 +63,22 @@ testrun_compare ${abs_top_builddir}/src/readelf --debug-dump=loc --debug-dump=ra
   testfileloc<<\EOF
 
 DWARF section [33] '.debug_loc' at offset 0xd2a:
- [     0]  0x0000000000400480 <main>..0x000000000040048d <main+0xd> [ 0] reg5
- [    23]  0x0000000000400485 <main+0x5>..0x000000000040048d <main+0xd> [ 0] reg5
- [    46]  0x00000000004004b2 <say+0x12>..0x00000000004004ba <say+0x1a> [ 0] breg5 0
+
+ CU [     b] base: 0x0000000000400480 <main>
+ [     0] range 0, d
+          0x0000000000400480 <main>..
+          0x000000000040048c <main+0xc>
+           [ 0] reg5
+ [    23] range 5, d
+          0x0000000000400485 <main+0x5>..
+          0x000000000040048c <main+0xc>
+           [ 0] reg5
+
+ CU [    e0] base: 0x00000000004004a0 <say>
+ [    46] range 12, 1a
+          0x00000000004004b2 <say+0x12>..
+          0x00000000004004b9 <say+0x19>
+           [ 0] breg5 0
 
 DWARF section [34] '.debug_ranges' at offset 0xd94:
 
@@ -91,9 +104,22 @@ testrun_compare ${abs_top_builddir}/src/readelf -N --debug-dump=loc --debug-dump
   testfileloc<<\EOF
 
 DWARF section [33] '.debug_loc' at offset 0xd2a:
- [     0]  0x0000000000400480..0x000000000040048d [ 0] reg5
- [    23]  0x0000000000400485..0x000000000040048d [ 0] reg5
- [    46]  0x00000000004004b2..0x00000000004004ba [ 0] breg5 0
+
+ CU [     b] base: 0x0000000000400480
+ [     0] range 0, d
+          0x0000000000400480..
+          0x000000000040048c
+           [ 0] reg5
+ [    23] range 5, d
+          0x0000000000400485..
+          0x000000000040048c
+           [ 0] reg5
+
+ CU [    e0] base: 0x00000000004004a0
+ [    46] range 12, 1a
+          0x00000000004004b2..
+          0x00000000004004b9
+           [ 0] breg5 0
 
 DWARF section [34] '.debug_ranges' at offset 0xd94:
 
@@ -119,9 +145,16 @@ testrun_compare ${abs_top_builddir}/src/readelf -U --debug-dump=loc --debug-dump
   testfileloc<<\EOF
 
 DWARF section [33] '.debug_loc' at offset 0xd2a:
- [     0]  000000000000000000..0x000000000000000d [ 0] reg5
- [    23]  0x0000000000000005..0x000000000000000d [ 0] reg5
- [    46]  0x0000000000000012..0x000000000000001a [ 0] breg5 0
+
+ CU [     b] base: 0x0000000000400480
+ [     0] range 0, d
+           [ 0] reg5
+ [    23] range 5, d
+           [ 0] reg5
+
+ CU [    e0] base: 0x00000000004004a0
+ [    46] range 12, 1a
+           [ 0] breg5 0
 
 DWARF section [34] '.debug_ranges' at offset 0xd94:
 
diff --git a/tests/run-readelf-zdebug-rel.sh b/tests/run-readelf-zdebug-rel.sh
index 2b57d05..ccccd82 100755
--- a/tests/run-readelf-zdebug-rel.sh
+++ b/tests/run-readelf-zdebug-rel.sh
@@ -127,12 +127,17 @@ cat info.out | testrun_compare ${abs_top_builddir}/src/readelf -U --debug-dump=i
 cat > loc.out << \EOF
 
 DWARF section [ 7] '.debug_loc' at offset 0x185:
- [     0]  000000000000000000..0x0000000000000003 [ 0] reg5
-           0x0000000000000003..0x0000000000000010 [ 0] breg5 -42
-                                                  [ 2] stack_value
-           0x0000000000000010..0x0000000000000018 [ 0] GNU_entry_value:
-      [ 0] reg5
-                                                  [ 3] stack_value
+
+ CU [     b] base: 000000000000000000
+ [     0] range 0, 3
+           [ 0] reg5
+          range 3, 10
+           [ 0] breg5 -42
+           [ 2] stack_value
+          range 10, 18
+           [ 0] GNU_entry_value:
+                [ 0] reg5
+           [ 3] stack_value
 EOF
 
 cat loc.out | testrun_compare ${abs_top_builddir}/src/readelf -U --debug-dump=loc testfile-debug-rel.o
diff --git a/tests/run-readelf-zdebug.sh b/tests/run-readelf-zdebug.sh
index 7be9bee..28128ad 100755
--- a/tests/run-readelf-zdebug.sh
+++ b/tests/run-readelf-zdebug.sh
@@ -46,12 +46,17 @@ tempfiles loc.out aranges.out ranges.out macro.out line.out frame.out
 cat > loc.out << \EOF
 
 DWARF section [30] '.debug_loc' at offset 0xa17:
- [     0]  0x00000000004003c0..0x00000000004003c3 [ 0] reg5
-           0x00000000004003c3..0x00000000004003d6 [ 0] breg5 -42
-                                                  [ 2] stack_value
-           0x00000000004003d6..0x00000000004003d9 [ 0] GNU_entry_value:
-      [ 0] reg5
-                                                  [ 3] stack_value
+
+ CU [     b] base: 000000000000000000
+ [     0] range 4003c0, 4003c3
+           [ 0] reg5
+          range 4003c3, 4003d6
+           [ 0] breg5 -42
+           [ 2] stack_value
+          range 4003d6, 4003d9
+           [ 0] GNU_entry_value:
+                [ 0] reg5
+           [ 3] stack_value
 EOF
 
 cat loc.out | testrun_compare ${abs_top_builddir}/src/readelf -U --debug-dump=loc testfile-debug

commit e98f032d293a8ea8ea2b25949d7f452603e644d9
Author: Mark Wielaard <mark@klomp.org>
Date:   Thu Jan 25 13:24:19 2018 +0100

    readelf: Fix crash on reading loc data or range data with bad/no CUs.
    
    In print_debug_ranges_section and print_debug_loc_section we try to
    get the associated CU through skip_listptr_hole for the first data data.
    If no CU at all can be found (because the .debug_info section was bogus)
    this would keep the Dwarf_CU uninitialized causing a crash later on
    when it was compared to the last_cu and used because it was unequal.
    Fix this by explicitly initializing cu to last_cu (which is NULL on
    first use).
    
    Signed-off-by: Mark Wielaard <mark@klomp.org>

diff --git a/src/readelf.c b/src/readelf.c
index 4bdaef2..6c49d30 100644
--- a/src/readelf.c
+++ b/src/readelf.c
@@ -5014,7 +5014,7 @@ print_debug_ranges_section (Dwfl_Module *dwflmod,
   while (readp < endp)
     {
       ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
-      Dwarf_CU *cu;
+      Dwarf_CU *cu = last_cu;
 
       if (first && skip_listptr_hole (&known_rangelistptr, &listptr_idx,
 				      &address_size, NULL, &base, &cu,
@@ -7140,7 +7140,7 @@ print_debug_loc_section (Dwfl_Module *dwflmod,
   while (readp < endp)
     {
       ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
-      Dwarf_CU *cu;
+      Dwarf_CU *cu = last_cu;
 
       if (first && skip_listptr_hole (&known_loclistptr, &listptr_idx,
 				      &address_size, &offset_size, &base,

commit 0f1d3389f18887ff4ef411812e95deab3e8dfb7c
Author: Mark Wielaard <mark@klomp.org>
Date:   Thu Mar 1 00:14:52 2018 +0100

    readelf: Add some support for locviews.
    
    This adds minimal support for locviews as output by GCC8.
    It changes readelf to keep track of loclistptrs from DW_AT_GNU_locviews
    and prints the locview pairs for those. Since there is no terminator
    we have to keep track of where the next loclist entry starts.
    The --debug-dump=loc output looks as follows:
    
     CU [   714] base: +0x0000000000003020 <elf_hash>
     [    b4] view pair 1, 2
     [    b6] range 4, 7f
              +0x0000000000003024 <elf_hash+0x4>..
              +0x000000000000309e <elf_hash+0x7e>
               [ 0] reg5
     [    d9] view pair 3, 1
              view pair 1, 2
     [    dd] range 4, 4c
              +0x0000000000003024 <elf_hash+0x4>..
              +0x000000000000306b <elf_hash+0x4b>
               [ 0] reg5
              range 4c, 7f
              +0x000000000000306c <elf_hash+0x4c>..
              +0x000000000000309e <elf_hash+0x7e>
               [ 0] reg2
    
    Note that in the above output the view pairs correspond to the ranges
    immediately following in the loc list. This is how GCC8 currently
    outputs the locview pairs and ranges, but this is not guaranteed and
    you'll need to look at the location and GNU_locviews attributes of the
    DIE to know which really match up together. We might want to adjust the
    output to make this more clear.
    
    This does not yet add an locview accessor to libdw. It just recognizes
    the DW_AT_GNU_locviews attribute as a loclistptr when encoded as a
    sec_offset form.
    
    Signed-off-by: Mark Wielaard <mark@klomp.org>

diff --git a/libdw/dwarf.h b/libdw/dwarf.h
index 4f36206..d53a30d 100644
--- a/libdw/dwarf.h
+++ b/libdw/dwarf.h
@@ -339,6 +339,8 @@ enum
     DW_AT_GNU_all_tail_call_sites = 0x2116,
     DW_AT_GNU_all_call_sites = 0x2117,
     DW_AT_GNU_all_source_call_sites = 0x2118,
+    DW_AT_GNU_locviews = 0x2137,
+    DW_AT_GNU_entry_view = 0x2138,
     DW_AT_GNU_macros = 0x2119,
     DW_AT_GNU_deleted = 0x211a,
 
diff --git a/libdw/dwarf_formudata.c b/libdw/dwarf_formudata.c
index 9c1644e..95872d6 100644
--- a/libdw/dwarf_formudata.c
+++ b/libdw/dwarf_formudata.c
@@ -141,6 +141,7 @@ dwarf_formudata (Dwarf_Attribute *attr, Dwarf_Word *return_uval)
 	    case DW_AT_string_length:
 	    case DW_AT_use_location:
 	    case DW_AT_vtable_elem_location:
+	    case DW_AT_GNU_locviews:
 	      /* loclistptr */
 	      if (__libdw_formptr (attr, IDX_debug_loc,
 				   DWARF_E_NO_LOCLIST, NULL,
diff --git a/src/readelf.c b/src/readelf.c
index 2d49af3..098209f 100644
--- a/src/readelf.c
+++ b/src/readelf.c
@@ -4532,6 +4532,7 @@ struct listptr
   bool dwarf64:1;
   bool warned:1;
   struct Dwarf_CU *cu;
+  unsigned int attr;
 };
 
 #define listptr_offset_size(p)	((p)->dwarf64 ? 8 : 4)
@@ -4592,6 +4593,15 @@ compare_listptr (const void *a, const void *b, void *arg)
 		 gettext ("%s %#" PRIx64 " used with different base addresses"),
 		 name, (uint64_t) p1->offset);
 	}
+      if (p1->attr != p2 ->attr)
+	{
+	  p1->warned = p2->warned = true;
+	  error (0, 0,
+		 gettext ("%s %#" PRIx64
+			  " used with different attribute %s and %s"),
+		 name, (uint64_t) p1->offset, dwarf_attr_name (p2->attr),
+		 dwarf_attr_name (p2->attr));
+	}
     }
 
   return 0;
@@ -4619,7 +4629,7 @@ reset_listptr (struct listptr_table *table)
 static bool
 notice_listptr (enum section_e section, struct listptr_table *table,
 		uint_fast8_t address_size, uint_fast8_t offset_size,
-		struct Dwarf_CU *cu, Dwarf_Off offset)
+		struct Dwarf_CU *cu, Dwarf_Off offset, unsigned int attr)
 {
   if (print_debug_sections & section)
     {
@@ -4640,7 +4650,8 @@ notice_listptr (enum section_e section, struct listptr_table *table,
 	  .addr64 = address_size == 8,
 	  .dwarf64 = offset_size == 8,
 	  .offset = offset,
-	  .cu = cu
+	  .cu = cu,
+	  .attr = attr
 	};
 
       if (p->offset != offset)
@@ -4664,7 +4675,8 @@ static bool
 skip_listptr_hole (struct listptr_table *table, size_t *idxp,
 		   uint_fast8_t *address_sizep, uint_fast8_t *offset_sizep,
 		   Dwarf_Addr *base, struct Dwarf_CU **cu, ptrdiff_t offset,
-		   unsigned char **readp, unsigned char *endp)
+		   unsigned char **readp, unsigned char *endp,
+		   unsigned int *attr)
 {
   if (table->n == 0)
     return false;
@@ -4699,10 +4711,27 @@ skip_listptr_hole (struct listptr_table *table, size_t *idxp,
     *base = listptr_base (p);
   if (cu != NULL)
     *cu = p->cu;
+  if (attr != NULL)
+    *attr = p->attr;
 
   return false;
 }
 
+static Dwarf_Off
+next_listptr_offset (struct listptr_table *table, size_t idx)
+{
+  /* Note that multiple attributes could in theory point to the same loclist
+     offset, so make sure we pick one that is bigger than the current one.
+     The table is sorted on offset.  */
+  Dwarf_Off offset = table->table[idx].offset;
+  while (++idx < table->n)
+    {
+      Dwarf_Off next = table->table[idx].offset;
+      if (next > offset)
+	return next;
+    }
+  return 0;
+}
 
 static void
 print_debug_abbrev_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
@@ -5042,7 +5071,7 @@ print_debug_ranges_section (Dwfl_Module *dwflmod,
 
       if (first && skip_listptr_hole (&known_rangelistptr, &listptr_idx,
 				      &address_size, NULL, &base, &cu,
-				      offset, &readp, endp))
+				      offset, &readp, endp, NULL))
 	continue;
 
       if (last_cu != cu)
@@ -6121,10 +6150,11 @@ attr_callback (Dwarf_Attribute *attrp, void *arg)
 	case DW_AT_GNU_call_site_data_value:
 	case DW_AT_GNU_call_site_target:
 	case DW_AT_GNU_call_site_target_clobbered:
+	case DW_AT_GNU_locviews:
 	  {
 	    bool nlpt = notice_listptr (section_loc, &known_loclistptr,
 					cbargs->addrsize, cbargs->offset_size,
-					cbargs->cu, num);
+					cbargs->cu, num, attr);
 	    if (!cbargs->silent)
 	      printf ("           %*s%-20s (%s) location list [%6" PRIxMAX "]%s\n",
 		      (int) (level * 2), "", dwarf_attr_name (attr),
@@ -6137,7 +6167,7 @@ attr_callback (Dwarf_Attribute *attrp, void *arg)
 	  {
 	    bool nlpt = notice_listptr (section_ranges, &known_rangelistptr,
 					cbargs->addrsize, cbargs->offset_size,
-					cbargs->cu, num);
+					cbargs->cu, num, attr);
 	    if (!cbargs->silent)
 	      printf ("           %*s%-20s (%s) range list [%6" PRIxMAX "]%s\n",
 		      (int) (level * 2), "", dwarf_attr_name (attr),
@@ -7215,10 +7245,11 @@ print_debug_loc_section (Dwfl_Module *dwflmod,
     {
       ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
       Dwarf_CU *cu = last_cu;
+      unsigned int attr = 0;
 
       if (first && skip_listptr_hole (&known_loclistptr, &listptr_idx,
 				      &address_size, &offset_size, &base,
-				      &cu, offset, &readp, endp))
+				      &cu, offset, &readp, endp, &attr))
 	continue;
 
       if (last_cu != cu)
@@ -7237,6 +7268,40 @@ print_debug_loc_section (Dwfl_Module *dwflmod,
        }
       last_cu = cu;
 
+      if (attr == DW_AT_GNU_locviews)
+	{
+	  Dwarf_Off next_off = next_listptr_offset (&known_loclistptr,
+						    listptr_idx);
+	  const unsigned char *locp = readp;
+	  const unsigned char *locendp;
+	  if (next_off == 0)
+	    locendp = endp;
+	  else
+	    locendp = (const unsigned char *) data->d_buf + next_off;
+
+	  while (locp < locendp)
+	    {
+	      uint64_t v1, v2;
+	      get_uleb128 (v1, locp, locendp);
+	      if (locp >= locendp)
+		{
+		  printf (gettext (" [%6tx]  <INVALID DATA>\n"), offset);
+		  break;
+		}
+	      get_uleb128 (v2, locp, locendp);
+	      if (first)		/* First view pair in a list.  */
+		printf (" [%6tx] ", offset);
+	      else
+		printf ("          ");
+	      printf ("view pair %" PRId64 ", %" PRId64 "\n", v1, v2);
+	      first = false;
+	    }
+
+	  first = true;
+	  readp = (unsigned char *) locendp;
+	  continue;
+	}
+
       if (unlikely (data->d_size - offset < (size_t) address_size * 2))
 	{
 	  printf (gettext (" [%6tx]  <INVALID DATA>\n"), offset);