This is the mail archive of the elfutils-devel@sourceware.org mailing list for the elfutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] readelf: Handle .debug_loclists.


The new DWARF5 .debug_loclists sections are like .debug_rnglists, but
plus locations. For Split Dwarf GCC generates the .debug_loclists fully
in the split .dwo file. Any references to addresses need to be resolved
through the skeleton .debug_addr section.

Signed-off-by: Mark Wielaard <mark@klomp.org>
---
 libdw/ChangeLog           |  15 ++
 libdw/dwarf.h             |  16 ++
 libdw/dwarf_begin_elf.c   |   1 +
 libdw/dwarf_error.c       |   4 +-
 libdw/dwarf_formudata.c   |  23 +-
 libdw/dwarf_getlocation.c |   4 +-
 libdw/libdwP.h            |   5 +-
 src/ChangeLog             |  19 ++
 src/readelf.c             | 562 ++++++++++++++++++++++++++++++++++++++++++++--
 tests/ChangeLog           |   4 +
 tests/run-readelf-loc.sh  | 560 +++++++++++++++++++++++++++++++++++++++++++++
 11 files changed, 1191 insertions(+), 22 deletions(-)

diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index 9991686..0db49bf 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,18 @@
+2018-04-12  Mark Wielaard  <mark@klomp.org>
+
+	* dwarf.h: Add DWARF5 location list entry DW_LLE encodings.
+	* begin_elf.c (dwarf_scnnames): Add IDX_debug_loclists.
+	* dwarf_error.c (errmsgs): Remove DWARF_E_NO_LOCLIST. And replace
+	with DWARF_E_NO_DEBUG_LOC, DWARF_E_NO_DEBUG_LOCLISTS and
+	DWARF_E_NO_LOC_VALUE.
+	* dwarf_formudata.c (dwarf_formudata): Handle DW_AT_loclists_base
+	and DW_FORM_loclistx.
+	* dwarf_getlocation.c (attr_ok): Use DWARF_E_NO_LOC_VALUE.
+	(initial_offset): Use DWARF_E_NO_DEBUG_LOC.
+	* libdwP.h: Add IDX_debug_rnglists. Remove DWARF_E_NO_LOCLIST.
+	Add DWARF_E_NO_DEBUG_LOC, DWARF_E_NO_DEBUG_LOCLISTS and
+	DWARF_E_NO_LOC_VALUE.
+
 2018-05-25  Mark Wielaard  <mark@klomp.org>
 
 	* libdw_find_split_unit.c (__libdw_find_split_unit): Extract linking
diff --git a/libdw/dwarf.h b/libdw/dwarf.h
index 9c2495e..8985a9d 100644
--- a/libdw/dwarf.h
+++ b/libdw/dwarf.h
@@ -899,6 +899,22 @@ enum
     DW_RLE_start_length = 0x7
   };
 
+
+/* Location list entry encoding.  */
+enum
+  {
+    DW_LLE_end_of_list = 0x0,
+    DW_LLE_base_addressx = 0x1,
+    DW_LLE_startx_endx = 0x2,
+    DW_LLE_startx_length = 0x3,
+    DW_LLE_offset_pair = 0x4,
+    DW_LLE_default_location = 0x5,
+    DW_LLE_base_address = 0x6,
+    DW_LLE_start_end = 0x7,
+    DW_LLE_start_length = 0x8
+  };
+
+
 /* DWARF call frame instruction encodings.  */
 enum
   {
diff --git a/libdw/dwarf_begin_elf.c b/libdw/dwarf_begin_elf.c
index 2e8c5f3..af5096f 100644
--- a/libdw/dwarf_begin_elf.c
+++ b/libdw/dwarf_begin_elf.c
@@ -58,6 +58,7 @@ static const char dwarf_scnnames[IDX_last][19] =
   [IDX_debug_line_str] = ".debug_line_str",
   [IDX_debug_frame] = ".debug_frame",
   [IDX_debug_loc] = ".debug_loc",
+  [IDX_debug_loclists] = ".debug_loclists",
   [IDX_debug_pubnames] = ".debug_pubnames",
   [IDX_debug_str] = ".debug_str",
   [IDX_debug_str_offsets] = ".debug_str_offsets",
diff --git a/libdw/dwarf_error.c b/libdw/dwarf_error.c
index 2e8cd77..46ea16b 100644
--- a/libdw/dwarf_error.c
+++ b/libdw/dwarf_error.c
@@ -85,7 +85,9 @@ static const char *errmsgs[] =
     [DWARF_E_VERSION] = N_("invalid DWARF version"),
     [DWARF_E_INVALID_DIR_IDX] = N_("invalid directory index"),
     [DWARF_E_ADDR_OUTOFRANGE] = N_("address out of range"),
-    [DWARF_E_NO_LOCLIST] = N_("no location list value"),
+    [DWARF_E_NO_DEBUG_LOC] = N_(".debug_loc section missing"),
+    [DWARF_E_NO_DEBUG_LOCLISTS] = N_(".debug_loclists section missing"),
+    [DWARF_E_NO_LOC_VALUE] = N_("not a location list value"),
     [DWARF_E_NO_BLOCK] = N_("no block data"),
     [DWARF_E_INVALID_LINE_IDX] = N_("invalid line index"),
     [DWARF_E_INVALID_ARANGE_IDX] = N_("invalid address range index"),
diff --git a/libdw/dwarf_formudata.c b/libdw/dwarf_formudata.c
index 280fef2..26f86f1 100644
--- a/libdw/dwarf_formudata.c
+++ b/libdw/dwarf_formudata.c
@@ -184,11 +184,23 @@ dwarf_formudata (Dwarf_Attribute *attr, Dwarf_Word *return_uval)
 	    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,
-				   return_uval) == NULL)
-		return -1;
+	    case DW_AT_loclists_base:
+	      if (attr->cu->version < 5)
+		{
+		  /* loclistptr */
+		  if (__libdw_formptr (attr, IDX_debug_loc,
+				       DWARF_E_NO_DEBUG_LOC, NULL,
+				       return_uval) == NULL)
+		    return -1;
+		}
+	      else
+		{
+		  /* loclist, loclistsptr */
+		  if (__libdw_formptr (attr, IDX_debug_loclists,
+				       DWARF_E_NO_DEBUG_LOCLISTS, NULL,
+				       return_uval) == NULL)
+		    return -1;
+		}
 	      break;
 
 	    case DW_AT_macro_info:
@@ -291,6 +303,7 @@ dwarf_formudata (Dwarf_Attribute *attr, Dwarf_Word *return_uval)
 
     case DW_FORM_udata:
     case DW_FORM_rnglistx:
+    case DW_FORM_loclistx:
       if (datap + 1 > endp)
 	goto invalid;
       get_uleb128 (*return_uval, datap, endp);
diff --git a/libdw/dwarf_getlocation.c b/libdw/dwarf_getlocation.c
index 0e7115f..d4b8eff 100644
--- a/libdw/dwarf_getlocation.c
+++ b/libdw/dwarf_getlocation.c
@@ -87,7 +87,7 @@ attr_ok (Dwarf_Attribute *attr)
       break;
 
     default:
-      __libdw_seterrno (DWARF_E_NO_LOCLIST);
+      __libdw_seterrno (DWARF_E_NO_LOC_VALUE);
       return false;
     }
 
@@ -700,7 +700,7 @@ initial_offset (Dwarf_Attribute *attr, ptrdiff_t *offset)
 
   Dwarf_Word start_offset;
   if (__libdw_formptr (attr, secidx,
-		       DWARF_E_NO_LOCLIST,
+		       DWARF_E_NO_DEBUG_LOC,
 		       NULL, &start_offset) == NULL)
     return -1;
 
diff --git a/libdw/libdwP.h b/libdw/libdwP.h
index 18576d6..f99ea58 100644
--- a/libdw/libdwP.h
+++ b/libdw/libdwP.h
@@ -78,6 +78,7 @@ enum
     IDX_debug_line_str,
     IDX_debug_frame,
     IDX_debug_loc,
+    IDX_debug_loclists,
     IDX_debug_pubnames,
     IDX_debug_str,
     IDX_debug_str_offsets,
@@ -124,7 +125,9 @@ enum
   DWARF_E_VERSION,
   DWARF_E_INVALID_DIR_IDX,
   DWARF_E_ADDR_OUTOFRANGE,
-  DWARF_E_NO_LOCLIST,
+  DWARF_E_NO_DEBUG_LOC,
+  DWARF_E_NO_DEBUG_LOCLISTS,
+  DWARF_E_NO_LOC_VALUE,
   DWARF_E_NO_BLOCK,
   DWARF_E_INVALID_LINE_IDX,
   DWARF_E_INVALID_ARANGE_IDX,
diff --git a/src/ChangeLog b/src/ChangeLog
index c99bb41..8e02d3c 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,22 @@
+2018-04-12  Mark Wielaard  <mark@klomp.org>
+
+	* readelf.c (dwarf_loc_list_encoding_string): New functions.
+	(dwarf_loc_list_encoding_name): Likewise.
+	(known_loclistptr): Renamed and split in two...
+	(known_locsptr): this and ...
+	(known_loclistsptr): this.
+	(listptr_base): Split out...
+	(cudie_base): ...this.
+	(is_split_dwarf): New function.
+	(attr_callback): Handle DW_AT_loclists_base and notice sec_offset
+	in correct list.
+	(print_debug_rnglists_section): Use spit_dwarf_cu_base.
+	(print_debug_loclists_section): New function.
+	(print_debug_loc_section): Use known_locsptr instead of
+	known_loclistptr.
+	(print_debug): Recognize .debug_loclists. Reset known_locsptr and
+	known_loclistsptr.
+
 2018-05-25  Mark Wielaard  <mark@klomp.org>
 
 	* readelf.c (DWARF_SKELETON): New constant.
diff --git a/src/readelf.c b/src/readelf.c
index b82e9ca..311a3ca 100644
--- a/src/readelf.c
+++ b/src/readelf.c
@@ -4026,6 +4026,20 @@ dwarf_range_list_encoding_string (unsigned int kind)
 
 
 static const char *
+dwarf_loc_list_encoding_string (unsigned int kind)
+{
+  switch (kind)
+    {
+#define DWARF_ONE_KNOWN_DW_LLE(NAME, CODE) case CODE: return #NAME;
+      DWARF_ALL_KNOWN_DW_LLE
+#undef DWARF_ONE_KNOWN_DW_LLE
+    default:
+      return NULL;
+    }
+}
+
+
+static const char *
 dwarf_line_content_description_string (unsigned int kind)
 {
   switch (kind)
@@ -4195,6 +4209,14 @@ dwarf_range_list_encoding_name (unsigned int kind)
 
 
 static const char *
+dwarf_loc_list_encoding_name (unsigned int kind)
+{
+  const char *ret = dwarf_loc_list_encoding_string (kind);
+  return string_or_unknown (ret, kind, 0, 0, false);
+}
+
+
+static const char *
 dwarf_line_content_description_name (unsigned int kind)
 {
   const char *ret = dwarf_line_content_description_string (kind);
@@ -4710,25 +4732,31 @@ struct listptr
 #define listptr_address_size(p)	((p)->addr64 ? 8 : 4)
 
 static Dwarf_Addr
-listptr_base (struct listptr *p)
+cudie_base (Dwarf_Die *cudie)
 {
   Dwarf_Addr base;
-  Dwarf_Die cu = CUDIE (p->cu);
   /* Find the base address of the compilation unit.  It will normally
      be specified by DW_AT_low_pc.  In DWARF-3 draft 4, the base
      address could be overridden by DW_AT_entry_pc.  It's been
      removed, but GCC emits DW_AT_entry_pc and not DW_AT_lowpc for
      compilation units with discontinuous ranges.  */
-  if (unlikely (dwarf_lowpc (&cu, &base) != 0))
+  if (unlikely (dwarf_lowpc (cudie, &base) != 0))
     {
       Dwarf_Attribute attr_mem;
-      if (dwarf_formaddr (dwarf_attr (&cu, DW_AT_entry_pc, &attr_mem),
+      if (dwarf_formaddr (dwarf_attr (cudie, DW_AT_entry_pc, &attr_mem),
 			  &base) != 0)
 	base = 0;
     }
   return base;
 }
 
+static Dwarf_Addr
+listptr_base (struct listptr *p)
+{
+  Dwarf_Die cu = CUDIE (p->cu);
+  return cudie_base (&cu);
+}
+
 static int
 compare_listptr (const void *a, const void *b, void *arg)
 {
@@ -4785,7 +4813,8 @@ struct listptr_table
   struct listptr *table;
 };
 
-static struct listptr_table known_loclistptr;
+static struct listptr_table known_locsptr;
+static struct listptr_table known_loclistsptr;
 static struct listptr_table known_rangelistptr;
 static struct listptr_table known_rnglistptr;
 
@@ -5231,6 +5260,27 @@ print_debug_aranges_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
     }
 }
 
+
+static bool is_split_dwarf (Dwarf *dbg, uint64_t *id, Dwarf_CU **split_cu);
+
+/* Returns true and sets cu and cu_base if the given Dwarf is a split
+   DWARF (.dwo) file.  */
+static bool
+split_dwarf_cu_base (Dwarf *dbg, Dwarf_CU **cu, Dwarf_Addr *cu_base)
+{
+  uint64_t id;
+  if (is_split_dwarf (dbg, &id, cu))
+    {
+      Dwarf_Die cudie;
+      if (dwarf_cu_info (*cu, NULL, NULL, &cudie, NULL, NULL, NULL, NULL) == 0)
+	{
+	  *cu_base = cudie_base (&cudie);
+	  return true;
+	}
+    }
+  return false;
+}
+
 /* Print content of DWARF .debug_rnglists section.  */
 static void
 print_debug_rnglists_section (Dwfl_Module *dwflmod,
@@ -5334,7 +5384,8 @@ print_debug_rnglists_section (Dwfl_Module *dwflmod,
       if (listptr_cu (&known_rnglistptr, &listptr_idx,
 		      (Dwarf_Off) offset,
 		      (Dwarf_Off) (nexthdr - (unsigned char *) data->d_buf),
-		      &cu_base, &cu))
+		      &cu_base, &cu)
+	  || split_dwarf_cu_base (dbg, &cu, &cu_base))
 	{
 	  char *basestr = format_dwarf_addr (dwflmod, address_size,
 					     cu_base, cu_base);
@@ -6772,9 +6823,50 @@ attr_callback (Dwarf_Attribute *attrp, void *arg)
 	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, attr);
+	    bool nlpt;
+	    if (cbargs->cu->version < 5)
+	      nlpt = notice_listptr (section_loc, &known_locsptr,
+				     cbargs->addrsize, cbargs->offset_size,
+				     cbargs->cu, num, attr);
+	    else
+	      {
+		/* Only register for a real section offset.  Otherwise
+		   it is a DW_FORM_loclistx which is just an index
+		   number and we should already have registered the
+		   section offset for the index when we saw the
+		   DW_AT_loclists_base CU attribute.  */
+		if (form == DW_FORM_sec_offset)
+		  nlpt = notice_listptr (section_loc, &known_loclistsptr,
+					 cbargs->addrsize, cbargs->offset_size,
+					 cbargs->cu, num, attr);
+		else
+		  nlpt = true;
+
+	      }
+
+	    if (!cbargs->silent)
+	      {
+		if (cbargs->cu->version < 5 || form == DW_FORM_sec_offset)
+		  printf ("           %*s%-20s (%s) location list [%6"
+			  PRIxMAX "]%s\n",
+			  (int) (level * 2), "", dwarf_attr_name (attr),
+			  dwarf_form_name (form), (uintmax_t) num,
+			  nlpt ? "" : " <WARNING offset too big>");
+		else
+		  printf ("           %*s%-20s (%s) location index [%6"
+			  PRIxMAX "]\n",
+			  (int) (level * 2), "", dwarf_attr_name (attr),
+			  dwarf_form_name (form), (uintmax_t) num);
+	      }
+	  }
+	  return DWARF_CB_OK;
+
+	case DW_AT_loclists_base:
+	  {
+	    bool nlpt = notice_listptr (section_loc, &known_loclistsptr,
+                                        cbargs->addrsize, cbargs->offset_size,
+                                        cbargs->cu, num, attr);
+
 	    if (!cbargs->silent)
 	      printf ("           %*s%-20s (%s) location list [%6" PRIxMAX "]%s\n",
 		      (int) (level * 2), "", dwarf_attr_name (attr),
@@ -8370,6 +8462,446 @@ print_debug_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
 
 
 static void
+print_debug_loclists_section (Dwfl_Module *dwflmod,
+			      Ebl *ebl, GElf_Ehdr *ehdr,
+			      Elf_Scn *scn, GElf_Shdr *shdr,
+			      Dwarf *dbg)
+{
+  printf (gettext ("\
+\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
+	  elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
+	  (uint64_t) shdr->sh_offset);
+
+  Elf_Data *data = (dbg->sectiondata[IDX_debug_loclists]
+		    ?: elf_rawdata (scn, NULL));
+  if (unlikely (data == NULL))
+    {
+      error (0, 0, gettext ("cannot get .debug_loclists content: %s"),
+	     elf_errmsg (-1));
+      return;
+    }
+
+  /* For the listptr to get the base address/CU.  */
+  sort_listptr (&known_loclistsptr, "loclistsptr");
+  size_t listptr_idx = 0;
+
+  const unsigned char *readp = data->d_buf;
+  const unsigned char *const dataend = ((unsigned char *) data->d_buf
+					+ data->d_size);
+  while (readp < dataend)
+    {
+      if (unlikely (readp > dataend - 4))
+	{
+	invalid_data:
+	  error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
+		 elf_ndxscn (scn), section_name (ebl, ehdr, shdr));
+	  return;
+	}
+
+      ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
+      printf (gettext ("Table at Offset 0x%" PRIx64 ":\n\n"),
+	      (uint64_t) offset);
+
+      uint64_t unit_length = read_4ubyte_unaligned_inc (dbg, readp);
+      unsigned int offset_size = 4;
+      if (unlikely (unit_length == 0xffffffff))
+	{
+	  if (unlikely (readp > dataend - 8))
+	    goto invalid_data;
+
+	  unit_length = read_8ubyte_unaligned_inc (dbg, readp);
+	  offset_size = 8;
+	}
+      printf (gettext (" Length:         %8" PRIu64 "\n"), unit_length);
+
+      /* We need at least 2-bytes + 1-byte + 1-byte + 4-bytes = 8
+	 bytes to complete the header.  And this unit cannot go beyond
+	 the section data.  */
+      if (readp > dataend - 8
+	  || unit_length < 8
+	  || unit_length > (uint64_t) (dataend - readp))
+	goto invalid_data;
+
+      const unsigned char *nexthdr = readp + unit_length;
+
+      uint16_t version = read_2ubyte_unaligned_inc (dbg, readp);
+      printf (gettext (" DWARF version:  %8" PRIu16 "\n"), version);
+
+      if (version != 5)
+	{
+	  error (0, 0, gettext ("Unknown version"));
+	  goto next_table;
+	}
+
+      uint8_t address_size = *readp++;
+      printf (gettext (" Address size:   %8" PRIu64 "\n"),
+	      (uint64_t) address_size);
+
+      if (address_size != 4 && address_size != 8)
+	{
+	  error (0, 0, gettext ("unsupported address size"));
+	  goto next_table;
+	}
+
+      uint8_t segment_size = *readp++;
+      printf (gettext (" Segment size:   %8" PRIu64 "\n"),
+	      (uint64_t) segment_size);
+
+      if (segment_size != 0)
+        {
+          error (0, 0, gettext ("unsupported segment size"));
+          goto next_table;
+        }
+
+      uint32_t offset_entry_count = read_4ubyte_unaligned_inc (dbg, readp);
+      printf (gettext (" Offset entries: %8" PRIu64 "\n"),
+	      (uint64_t) offset_entry_count);
+
+      /* We need the CU that uses this unit to get the initial base address. */
+      Dwarf_Addr cu_base = 0;
+      struct Dwarf_CU *cu = NULL;
+      if (listptr_cu (&known_loclistsptr, &listptr_idx,
+		      (Dwarf_Off) offset,
+		      (Dwarf_Off) (nexthdr - (unsigned char *) data->d_buf),
+		      &cu_base, &cu)
+	  || split_dwarf_cu_base (dbg, &cu, &cu_base))
+	{
+	  char *basestr = format_dwarf_addr (dwflmod, address_size,
+					     cu_base, cu_base);
+	  Dwarf_Die cudie;
+	  if (dwarf_cu_die (cu, &cudie,
+			    NULL, NULL, NULL, NULL,
+			    NULL, NULL) == NULL)
+	    printf (gettext (" Unknown CU base: %s\n"), basestr);
+	  else
+	    printf (gettext (" CU [%6" PRIx64 "] base: %s\n"),
+		    dwarf_dieoffset (&cudie), basestr);
+	  free (basestr);
+	}
+      else
+	printf (gettext (" Not associated with a CU.\n"));
+
+      printf ("\n");
+
+      const unsigned char *offset_array_start = readp;
+      if (offset_entry_count > 0)
+	{
+	  uint64_t needed = offset_entry_count * offset_size;
+	  if (unit_length - 8 < needed)
+	    {
+	      error (0, 0,
+		     gettext ("too many offset entries for unit length"));
+	      goto next_table;
+	    }
+
+	  printf (gettext ("  Offsets starting at 0x%" PRIx64 ":\n"),
+		  (uint64_t) (offset_array_start
+			      - (unsigned char *) data->d_buf));
+	  for (uint32_t idx = 0; idx < offset_entry_count; idx++)
+	    {
+	      printf ("   [%6" PRIu32 "] ", idx);
+	      if (offset_size == 4)
+		{
+		  uint32_t off = read_4ubyte_unaligned_inc (dbg, readp);
+		  printf ("0x%" PRIx32 "\n", off);
+		}
+	      else
+		{
+		  uint64_t off = read_8ubyte_unaligned_inc (dbg, readp);
+		  printf ("0x%" PRIx64 "\n", off);
+		}
+	    }
+	  printf ("\n");
+	}
+
+      Dwarf_Addr base = cu_base;
+      bool start_of_list = true;
+      while (readp < nexthdr)
+	{
+	  uint8_t kind = *readp++;
+	  uint64_t op1, op2, len;
+	  char *a1, *a2;
+
+	  /* Skip padding.  */
+	  if (start_of_list && kind == DW_LLE_end_of_list)
+	    continue;
+
+	  if (start_of_list)
+	    {
+	      base = cu_base;
+	      printf ("  Offset: %" PRIx64 ", Index: %" PRIx64 "\n",
+		      (uint64_t) (readp - (unsigned char *) data->d_buf - 1),
+		      (uint64_t) (readp - offset_array_start - 1));
+	      start_of_list = false;
+	    }
+
+	  printf ("    %s", dwarf_loc_list_encoding_name (kind));
+	  switch (kind)
+	    {
+	    case DW_LLE_end_of_list:
+	      start_of_list = true;
+	      printf ("\n\n");
+	      break;
+
+	    case DW_LLE_base_addressx:
+	      if ((uint64_t) (nexthdr - readp) < 1)
+		{
+		invalid_entry:
+		  error (0, 0, gettext ("invalid loclists data"));
+		  goto next_table;
+		}
+	      get_uleb128 (op1, readp, nexthdr);
+	      printf (" %" PRIx64 "\n", op1);
+	      if (! print_unresolved_addresses)
+		{
+		  Dwarf_Addr addr;
+		  if (get_indexed_addr (cu, op1, &addr) != 0)
+		    printf ("      ???\n");
+		  else
+		    {
+		      a1 = format_dwarf_addr (dwflmod, address_size,
+					      addr, addr);
+		      printf ("      %s\n", a1);
+		      free (a1);
+		    }
+		}
+	      break;
+
+	    case DW_LLE_startx_endx:
+	      if ((uint64_t) (nexthdr - readp) < 1)
+		goto invalid_entry;
+	      get_uleb128 (op1, readp, nexthdr);
+	      if ((uint64_t) (nexthdr - readp) < 1)
+		goto invalid_entry;
+	      get_uleb128 (op2, readp, nexthdr);
+	      printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
+	      if (! print_unresolved_addresses)
+		{
+		  Dwarf_Addr addr1;
+		  Dwarf_Addr addr2;
+		  if (get_indexed_addr (cu, op1, &addr1) != 0
+		      || get_indexed_addr (cu, op2, &addr2) != 0)
+		    {
+		      printf ("      ???..\n");
+		      printf ("      ???\n");
+		    }
+		  else
+		    {
+		      a1 = format_dwarf_addr (dwflmod, address_size,
+					      addr1, addr1);
+		      a2 = format_dwarf_addr (dwflmod, address_size,
+					      addr2 - 1, addr2);
+		      printf ("      %s..\n", a1);
+		      printf ("      %s\n", a2);
+		      free (a1);
+		      free (a2);
+		    }
+		}
+	      if ((uint64_t) (nexthdr - readp) < 1)
+		goto invalid_entry;
+	      get_uleb128 (len, readp, nexthdr);
+	      if ((uint64_t) (nexthdr - readp) < len)
+		goto invalid_entry;
+	      print_ops (dwflmod, dbg, 8, 8, version,
+			 address_size, offset_size, cu, len, readp);
+	      readp += len;
+	      break;
+
+	    case DW_LLE_startx_length:
+	      if ((uint64_t) (nexthdr - readp) < 1)
+		goto invalid_entry;
+	      get_uleb128 (op1, readp, nexthdr);
+	      if ((uint64_t) (nexthdr - readp) < 1)
+		goto invalid_entry;
+	      get_uleb128 (op2, readp, nexthdr);
+	      printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
+	      if (! print_unresolved_addresses)
+		{
+		  Dwarf_Addr addr1;
+		  Dwarf_Addr addr2;
+		  if (get_indexed_addr (cu, op1, &addr1) != 0)
+		    {
+		      printf ("      ???..\n");
+		      printf ("      ???\n");
+		    }
+		  else
+		    {
+		      addr2 = addr1 + op2;
+		      a1 = format_dwarf_addr (dwflmod, address_size,
+					      addr1, addr1);
+		      a2 = format_dwarf_addr (dwflmod, address_size,
+					      addr2 - 1, addr2);
+		      printf ("      %s..\n", a1);
+		      printf ("      %s..\n", a2);
+		      free (a1);
+		      free (a2);
+		    }
+		}
+	      if ((uint64_t) (nexthdr - readp) < 1)
+		goto invalid_entry;
+	      get_uleb128 (len, readp, nexthdr);
+	      if ((uint64_t) (nexthdr - readp) < len)
+		goto invalid_entry;
+	      print_ops (dwflmod, dbg, 8, 8, version,
+			 address_size, offset_size, cu, len, readp);
+	      readp += len;
+	      break;
+
+	    case DW_LLE_offset_pair:
+	      if ((uint64_t) (nexthdr - readp) < 1)
+		goto invalid_entry;
+	      get_uleb128 (op1, readp, nexthdr);
+	      if ((uint64_t) (nexthdr - readp) < 1)
+		goto invalid_entry;
+	      get_uleb128 (op2, readp, nexthdr);
+	      printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
+	      if (! print_unresolved_addresses)
+		{
+		  op1 += base;
+		  op2 += base;
+		  a1 = format_dwarf_addr (dwflmod, address_size, op1, op1);
+		  a2 = format_dwarf_addr (dwflmod, address_size,
+					  op2 - 1, op2);
+		  printf ("      %s..\n", a1);
+		  printf ("      %s\n", a2);
+		  free (a1);
+		  free (a2);
+		}
+	      if ((uint64_t) (nexthdr - readp) < 1)
+		goto invalid_entry;
+	      get_uleb128 (len, readp, nexthdr);
+	      if ((uint64_t) (nexthdr - readp) < len)
+		goto invalid_entry;
+	      print_ops (dwflmod, dbg, 8, 8, version,
+			 address_size, offset_size, cu, len, readp);
+	      readp += len;
+	      break;
+
+	    case DW_LLE_default_location:
+	      if ((uint64_t) (nexthdr - readp) < 1)
+		goto invalid_entry;
+	      get_uleb128 (len, readp, nexthdr);
+	      if ((uint64_t) (nexthdr - readp) < len)
+		goto invalid_entry;
+	      print_ops (dwflmod, dbg, 8, 8, version,
+			 address_size, offset_size, cu, len, readp);
+	      readp += len;
+	      break;
+
+	    case DW_LLE_base_address:
+	      if (address_size == 4)
+		{
+		  if ((uint64_t) (nexthdr - readp) < 4)
+		    goto invalid_entry;
+		  op1 = read_4ubyte_unaligned_inc (dbg, readp);
+		}
+	      else
+		{
+		  if ((uint64_t) (nexthdr - readp) < 8)
+		    goto invalid_entry;
+		  op1 = read_8ubyte_unaligned_inc (dbg, readp);
+		}
+	      base = op1;
+	      printf (" 0x%" PRIx64 "\n", base);
+	      if (! print_unresolved_addresses)
+		{
+		  a1 = format_dwarf_addr (dwflmod, address_size, base, base);
+		  printf ("      %s\n", a1);
+		  free (a1);
+		}
+	      break;
+
+	    case DW_LLE_start_end:
+	      if (address_size == 4)
+		{
+		  if ((uint64_t) (nexthdr - readp) < 8)
+		    goto invalid_entry;
+		  op1 = read_4ubyte_unaligned_inc (dbg, readp);
+		  op2 = read_4ubyte_unaligned_inc (dbg, readp);
+		}
+	      else
+		{
+		  if ((uint64_t) (nexthdr - readp) < 16)
+		    goto invalid_entry;
+		  op1 = read_8ubyte_unaligned_inc (dbg, readp);
+		  op2 = read_8ubyte_unaligned_inc (dbg, readp);
+		}
+	      printf (" 0x%" PRIx64 "..0x%" PRIx64 "\n", op1, op2);
+	      if (! print_unresolved_addresses)
+		{
+		  a1 = format_dwarf_addr (dwflmod, address_size, op1, op1);
+		  a2 = format_dwarf_addr (dwflmod, address_size,
+					  op2 - 1, op2);
+		  printf ("      %s..\n", a1);
+		  printf ("      %s\n", a2);
+		  free (a1);
+		  free (a2);
+		}
+	      if ((uint64_t) (nexthdr - readp) < 1)
+		goto invalid_entry;
+	      get_uleb128 (len, readp, nexthdr);
+	      if ((uint64_t) (nexthdr - readp) < len)
+		goto invalid_entry;
+	      print_ops (dwflmod, dbg, 8, 8, version,
+			 address_size, offset_size, cu, len, readp);
+	      readp += len;
+	      break;
+
+	    case DW_LLE_start_length:
+	      if (address_size == 4)
+		{
+		  if ((uint64_t) (nexthdr - readp) < 4)
+		    goto invalid_entry;
+		  op1 = read_4ubyte_unaligned_inc (dbg, readp);
+		}
+	      else
+		{
+		  if ((uint64_t) (nexthdr - readp) < 8)
+		    goto invalid_entry;
+		  op1 = read_8ubyte_unaligned_inc (dbg, readp);
+		}
+	      if ((uint64_t) (nexthdr - readp) < 1)
+		goto invalid_entry;
+	      get_uleb128 (op2, readp, nexthdr);
+	      printf (" 0x%" PRIx64 ", %" PRIx64 "\n", op1, op2);
+	      if (! print_unresolved_addresses)
+		{
+		  a1 = format_dwarf_addr (dwflmod, address_size, op1, op1);
+		  op2 = op1 + op2;
+		  a2 = format_dwarf_addr (dwflmod, address_size,
+					  op2 - 1, op2);
+		  printf ("      %s..\n", a1);
+		  printf ("      %s\n", a2);
+		  free (a1);
+		  free (a2);
+		}
+	      if ((uint64_t) (nexthdr - readp) < 1)
+		goto invalid_entry;
+	      get_uleb128 (len, readp, nexthdr);
+	      if ((uint64_t) (nexthdr - readp) < len)
+		goto invalid_entry;
+	      print_ops (dwflmod, dbg, 8, 8, version,
+			 address_size, offset_size, cu, len, readp);
+	      readp += len;
+	      break;
+
+	    default:
+	      goto invalid_entry;
+	    }
+	}
+
+    next_table:
+      if (readp != nexthdr)
+	{
+          size_t padding = nexthdr - readp;
+          printf (gettext ("   %zu padding bytes\n\n"), padding);
+	  readp = nexthdr;
+	}
+    }
+}
+
+
+static void
 print_debug_loc_section (Dwfl_Module *dwflmod,
 			 Ebl *ebl, GElf_Ehdr *ehdr,
 			 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
@@ -8389,7 +8921,7 @@ print_debug_loc_section (Dwfl_Module *dwflmod,
 	  elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
 	  (uint64_t) shdr->sh_offset);
 
-  sort_listptr (&known_loclistptr, "loclistptr");
+  sort_listptr (&known_locsptr, "loclistptr");
   size_t listptr_idx = 0;
 
   uint_fast8_t address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
@@ -8406,7 +8938,7 @@ print_debug_loc_section (Dwfl_Module *dwflmod,
       Dwarf_CU *cu = last_cu;
       unsigned int attr = 0;
 
-      if (first && skip_listptr_hole (&known_loclistptr, &listptr_idx,
+      if (first && skip_listptr_hole (&known_locsptr, &listptr_idx,
 				      &address_size, &offset_size, &base,
 				      &cu, offset, &readp, endp, &attr))
 	continue;
@@ -8429,7 +8961,7 @@ print_debug_loc_section (Dwfl_Module *dwflmod,
 
       if (attr == DW_AT_GNU_locviews)
 	{
-	  Dwarf_Off next_off = next_listptr_offset (&known_loclistptr,
+	  Dwarf_Off next_off = next_listptr_offset (&known_loclistsptr,
 						    listptr_idx);
 	  const unsigned char *locp = readp;
 	  const unsigned char *locendp;
@@ -9945,6 +10477,9 @@ print_debug (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr)
 	      NEW_SECTION (types),
 	      NEW_SECTION (line),
 	      NEW_SECTION (loc),
+	      /* loclists is loc for DWARF5.  */
+	      { ".debug_loclists", section_loc,
+		print_debug_loclists_section },
 	      NEW_SECTION (pubnames),
 	      NEW_SECTION (str),
 	      /* A DWARF5 specialised debug string section.  */
@@ -10000,7 +10535,8 @@ print_debug (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr)
   dwfl_end (skel_dwfl);
   free (skel_name);
 
-  reset_listptr (&known_loclistptr);
+  reset_listptr (&known_locsptr);
+  reset_listptr (&known_loclistsptr);
   reset_listptr (&known_rangelistptr);
   reset_listptr (&known_rnglistptr);
 }
diff --git a/tests/ChangeLog b/tests/ChangeLog
index 5eb1e77..6e366eb 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,3 +1,7 @@
+2018-04-12  Mark Wielaard  <mark@klomp.org>
+
+	* run-readelf-loc.sh: Add new testcases.
+
 2018-04-06  Mark Wielaard  <mark@klomp.org>
 
 	* testfileranges5.debug.bz2: New testfile.
diff --git a/tests/run-readelf-loc.sh b/tests/run-readelf-loc.sh
index e5152df..622cc19 100755
--- a/tests/run-readelf-loc.sh
+++ b/tests/run-readelf-loc.sh
@@ -167,4 +167,564 @@ DWARF section [34] '.debug_ranges' at offset 0xd94:
           range 12, 1a
 EOF
 
+# .debug_rnglists (DWARF5), see tests/testfile-dwarf-45.source
+testfiles testfile-dwarf-5
+testrun_compare ${abs_top_builddir}/src/readelf --debug-dump=loc testfile-dwarf-5<<\EOF
+
+DWARF section [31] '.debug_loclists' at offset 0x1c0c:
+Table at Offset 0x0:
+
+ Length:               96
+ DWARF version:         5
+ Address size:          8
+ Segment size:          0
+ Offset entries:        0
+ CU [     c] base: 0x0000000000400510 <foo>
+
+  Offset: c, Index: 0
+    offset_pair 0, a
+      0x0000000000400510 <foo>..
+      0x0000000000400519 <foo+0x9>
+        [ 0] reg5
+    offset_pair a, 34
+      0x000000000040051a <foo+0xa>..
+      0x0000000000400543 <foo+0x33>
+        [ 0] entry_value:
+             [ 0] reg5
+        [ 3] stack_value
+    end_of_list
+
+  Offset: 1a, Index: e
+    offset_pair 1b, 2d
+      0x000000000040052b <foo+0x1b>..
+      0x000000000040053c <foo+0x2c>
+        [ 0] addr 0x601038 <m>
+    end_of_list
+
+  Offset: 28, Index: 1c
+    offset_pair 1b, 21
+      0x000000000040052b <foo+0x1b>..
+      0x0000000000400530 <foo+0x20>
+        [ 0] reg5
+    end_of_list
+
+  Offset: 2e, Index: 22
+    offset_pair 1b, 27
+      0x000000000040052b <foo+0x1b>..
+      0x0000000000400536 <foo+0x26>
+        [ 0] reg5
+    offset_pair 29, 2d
+      0x0000000000400539 <foo+0x29>..
+      0x000000000040053c <foo+0x2c>
+        [ 0] reg5
+    end_of_list
+
+  Offset: 39, Index: 2d
+    offset_pair 21, 27
+      0x0000000000400531 <foo+0x21>..
+      0x0000000000400536 <foo+0x26>
+        [ 0] reg5
+    offset_pair 29, 2d
+      0x0000000000400539 <foo+0x29>..
+      0x000000000040053c <foo+0x2c>
+        [ 0] reg5
+    end_of_list
+
+  Offset: 44, Index: 38
+    offset_pair 21, 2d
+      0x0000000000400531 <foo+0x21>..
+      0x000000000040053c <foo+0x2c>
+        [ 0] reg5
+    end_of_list
+
+  Offset: 4a, Index: 3e
+    offset_pair 2d, 33
+      0x000000000040053d <foo+0x2d>..
+      0x0000000000400542 <foo+0x32>
+        [ 0] reg5
+    end_of_list
+
+  Offset: 50, Index: 44
+    offset_pair 40, 4f
+      0x0000000000400550 <baz>..
+      0x000000000040055e <baz+0xe>
+        [ 0] reg5
+    offset_pair 4f, 51
+      0x000000000040055f <baz+0xf>..
+      0x0000000000400560 <baz+0x10>
+        [ 0] entry_value:
+             [ 0] reg5
+        [ 3] stack_value
+    end_of_list
+
+  Offset: 5e, Index: 52
+    offset_pair 40, 50
+      0x0000000000400550 <baz>..
+      0x000000000040055f <baz+0xf>
+        [ 0] reg5
+    end_of_list
+
+Table at Offset 0x64:
+
+ Length:              159
+ DWARF version:         5
+ Address size:          8
+ Segment size:          0
+ Offset entries:        0
+ CU [   218] base: 000000000000000000
+
+  Offset: 70, Index: 0
+    base_address 0x400410
+      0x0000000000400410 <main>
+    offset_pair 0, 14
+      0x0000000000400410 <main>..
+      0x0000000000400423 <main+0x13>
+        [ 0] reg5
+    offset_pair 14, 20
+      0x0000000000400424 <main+0x14>..
+      0x000000000040042f <main+0x1f>
+        [ 0] entry_value:
+             [ 0] reg5
+        [ 3] stack_value
+    end_of_list
+
+  Offset: 87, Index: 17
+    base_address 0x400410
+      0x0000000000400410 <main>
+    offset_pair 0, 18
+      0x0000000000400410 <main>..
+      0x0000000000400427 <main+0x17>
+        [ 0] reg4
+    offset_pair 18, 20
+      0x0000000000400428 <main+0x18>..
+      0x000000000040042f <main+0x1f>
+        [ 0] entry_value:
+             [ 0] reg4
+        [ 3] stack_value
+    end_of_list
+
+  Offset: 9e, Index: 2e
+    start_length 0x400421, 7
+      0x0000000000400421 <main+0x11>..
+      0x0000000000400427 <main+0x17>
+        [ 0] reg0
+    end_of_list
+
+  Offset: ab, Index: 3b
+    base_address 0x400570
+      0x0000000000400570 <calc>
+    offset_pair 0, 8
+      0x0000000000400570 <calc>..
+      0x0000000000400577 <calc+0x7>
+        [ 0] reg5
+    offset_pair 8, 2b
+      0x0000000000400578 <calc+0x8>..
+      0x000000000040059a <calc+0x2a>
+        [ 0] entry_value:
+             [ 0] reg5
+        [ 3] stack_value
+    end_of_list
+
+  Offset: c2, Index: 52
+    start_length 0x400588, b
+      0x0000000000400588 <calc+0x18>..
+      0x0000000000400592 <calc+0x22>
+        [ 0] reg0
+    end_of_list
+
+  Offset: cf, Index: 5f
+    base_address 0x400588
+      0x0000000000400588 <calc+0x18>
+    offset_pair 0, 2
+      0x0000000000400588 <calc+0x18>..
+      0x0000000000400589 <calc+0x19>
+        [ 0] reg1
+    offset_pair 2, 7
+      0x000000000040058a <calc+0x1a>..
+      0x000000000040058e <calc+0x1e>
+        [ 0] reg5
+    offset_pair 7, b
+      0x000000000040058f <calc+0x1f>..
+      0x0000000000400592 <calc+0x22>
+        [ 0] entry_value:
+             [ 0] reg5
+        [ 3] deref_size 1
+        [ 5] const1u 56
+        [ 7] shl
+        [ 8] const1u 56
+        [10] shra
+        [11] stack_value
+    end_of_list
+
+  Offset: f3, Index: 83
+    base_address 0x400588
+      0x0000000000400588 <calc+0x18>
+    offset_pair 0, 2
+      0x0000000000400588 <calc+0x18>..
+      0x0000000000400589 <calc+0x19>
+        [ 0] reg1
+    offset_pair 2, b
+      0x000000000040058a <calc+0x1a>..
+      0x0000000000400592 <calc+0x22>
+        [ 0] reg5
+    end_of_list
+
+EOF
+
+# Same as above, but for DWARF4, note completely different encoding, but
+# the information is the same (check with diff -uwb).
+testfiles testfile-dwarf-4
+testrun_compare ${abs_top_builddir}/src/readelf --debug-dump=loc testfile-dwarf-4<<\EOF
+
+DWARF section [31] '.debug_loc' at offset 0x1c86:
+
+ CU [     b] base: 0x0000000000400510 <foo>
+ [     0] range 0, a
+          0x0000000000400510 <foo>..
+          0x0000000000400519 <foo+0x9>
+           [ 0] reg5
+          range a, 34
+          0x000000000040051a <foo+0xa>..
+          0x0000000000400543 <foo+0x33>
+           [ 0] GNU_entry_value:
+                [ 0] reg5
+           [ 3] stack_value
+ [    39] range 1b, 2d
+          0x000000000040052b <foo+0x1b>..
+          0x000000000040053c <foo+0x2c>
+           [ 0] addr 0x601038 <m>
+ [    64] range 1b, 21
+          0x000000000040052b <foo+0x1b>..
+          0x0000000000400530 <foo+0x20>
+           [ 0] reg5
+ [    87] range 1b, 27
+          0x000000000040052b <foo+0x1b>..
+          0x0000000000400536 <foo+0x26>
+           [ 0] reg5
+          range 29, 2d
+          0x0000000000400539 <foo+0x29>..
+          0x000000000040053c <foo+0x2c>
+           [ 0] reg5
+ [    bd] range 21, 27
+          0x0000000000400531 <foo+0x21>..
+          0x0000000000400536 <foo+0x26>
+           [ 0] reg5
+          range 29, 2d
+          0x0000000000400539 <foo+0x29>..
+          0x000000000040053c <foo+0x2c>
+           [ 0] reg5
+ [    f3] range 21, 2d
+          0x0000000000400531 <foo+0x21>..
+          0x000000000040053c <foo+0x2c>
+           [ 0] reg5
+ [   116] range 2d, 33
+          0x000000000040053d <foo+0x2d>..
+          0x0000000000400542 <foo+0x32>
+           [ 0] reg5
+ [   139] range 40, 4f
+          0x0000000000400550 <baz>..
+          0x000000000040055e <baz+0xe>
+           [ 0] reg5
+          range 4f, 51
+          0x000000000040055f <baz+0xf>..
+          0x0000000000400560 <baz+0x10>
+           [ 0] GNU_entry_value:
+                [ 0] reg5
+           [ 3] stack_value
+ [   172] range 40, 50
+          0x0000000000400550 <baz>..
+          0x000000000040055f <baz+0xf>
+           [ 0] reg5
+
+ CU [   21c] base: 000000000000000000
+ [   195] range 400410, 400424
+          0x0000000000400410 <main>..
+          0x0000000000400423 <main+0x13>
+           [ 0] reg5
+          range 400424, 400430
+          0x0000000000400424 <main+0x14>..
+          0x000000000040042f <main+0x1f>
+           [ 0] GNU_entry_value:
+                [ 0] reg5
+           [ 3] stack_value
+ [   1ce] range 400410, 400428
+          0x0000000000400410 <main>..
+          0x0000000000400427 <main+0x17>
+           [ 0] reg4
+          range 400428, 400430
+          0x0000000000400428 <main+0x18>..
+          0x000000000040042f <main+0x1f>
+           [ 0] GNU_entry_value:
+                [ 0] reg4
+           [ 3] stack_value
+ [   207] range 400421, 400428
+          0x0000000000400421 <main+0x11>..
+          0x0000000000400427 <main+0x17>
+           [ 0] reg0
+ [   22a] range 400570, 400578
+          0x0000000000400570 <calc>..
+          0x0000000000400577 <calc+0x7>
+           [ 0] reg5
+          range 400578, 40059b
+          0x0000000000400578 <calc+0x8>..
+          0x000000000040059a <calc+0x2a>
+           [ 0] GNU_entry_value:
+                [ 0] reg5
+           [ 3] stack_value
+ [   263] range 400588, 400593
+          0x0000000000400588 <calc+0x18>..
+          0x0000000000400592 <calc+0x22>
+           [ 0] reg0
+ [   286] range 400588, 40058a
+          0x0000000000400588 <calc+0x18>..
+          0x0000000000400589 <calc+0x19>
+           [ 0] reg1
+          range 40058a, 40058f
+          0x000000000040058a <calc+0x1a>..
+          0x000000000040058e <calc+0x1e>
+           [ 0] reg5
+          range 40058f, 400593
+          0x000000000040058f <calc+0x1f>..
+          0x0000000000400592 <calc+0x22>
+           [ 0] GNU_entry_value:
+                [ 0] reg5
+           [ 3] deref_size 1
+           [ 5] const1u 56
+           [ 7] shl
+           [ 8] const1u 56
+           [10] shra
+           [11] stack_value
+ [   2da] range 400588, 40058a
+          0x0000000000400588 <calc+0x18>..
+          0x0000000000400589 <calc+0x19>
+           [ 0] reg1
+          range 40058a, 400593
+          0x000000000040058a <calc+0x1a>..
+          0x0000000000400592 <calc+0x22>
+           [ 0] reg5
+EOF
+
+# Split DWARF5 variant. Note that the .debug_loclists moved to the .dwo file
+# and now uses an index and addrx indirections.
+testfiles testfile-splitdwarf-5 testfile-hello5.dwo testfile-world5.dwo
+testrun_compare ${abs_top_builddir}/src/readelf --debug-dump=loc --dwarf-skeleton=testfile-splitdwarf-5 testfile-hello5.dwo testfile-world5.dwo <<\EOF
+
+testfile-hello5.dwo:
+
+
+DWARF section [ 3] '.debug_loclists.dwo' at offset 0x236:
+Table at Offset 0x0:
+
+ Length:              125
+ DWARF version:         5
+ Address size:          8
+ Segment size:          0
+ Offset entries:        9
+ CU [    14] base: 0x0000000000401160 <foo>
+
+  Offsets starting at 0xc:
+   [     0] 0x24
+   [     1] 0x32
+   [     2] 0x39
+   [     3] 0x3f
+   [     4] 0x4a
+   [     5] 0x55
+   [     6] 0x5b
+   [     7] 0x61
+   [     8] 0x6f
+
+  Offset: 30, Index: 24
+    startx_length f, a
+      0x0000000000401160 <foo>..
+      0x0000000000401169 <foo+0x9>..
+        [ 0] reg5
+    startx_length 0, 2a
+      0x000000000040116a <foo+0xa>..
+      0x0000000000401193 <foo+0x33>..
+        [ 0] entry_value:
+             [ 0] reg5
+        [ 3] stack_value
+    end_of_list
+
+  Offset: 3e, Index: 32
+    startx_length 11, 12
+      0x000000000040117b <foo+0x1b>..
+      0x000000000040118c <foo+0x2c>..
+        [ 0] addrx [18] 0x404038 <m>
+    end_of_list
+
+  Offset: 45, Index: 39
+    startx_length 11, 6
+      0x000000000040117b <foo+0x1b>..
+      0x0000000000401180 <foo+0x20>..
+        [ 0] reg5
+    end_of_list
+
+  Offset: 4b, Index: 3f
+    startx_length 11, c
+      0x000000000040117b <foo+0x1b>..
+      0x0000000000401186 <foo+0x26>..
+        [ 0] reg5
+    startx_length 1, 4
+      0x0000000000401189 <foo+0x29>..
+      0x000000000040118c <foo+0x2c>..
+        [ 0] reg5
+    end_of_list
+
+  Offset: 56, Index: 4a
+    startx_length 4, 6
+      0x0000000000401181 <foo+0x21>..
+      0x0000000000401186 <foo+0x26>..
+        [ 0] reg5
+    startx_length 1, 4
+      0x0000000000401189 <foo+0x29>..
+      0x000000000040118c <foo+0x2c>..
+        [ 0] reg5
+    end_of_list
+
+  Offset: 61, Index: 55
+    startx_length 4, c
+      0x0000000000401181 <foo+0x21>..
+      0x000000000040118c <foo+0x2c>..
+        [ 0] reg5
+    end_of_list
+
+  Offset: 67, Index: 5b
+    startx_length 2, 6
+      0x000000000040118d <foo+0x2d>..
+      0x0000000000401192 <foo+0x32>..
+        [ 0] reg5
+    end_of_list
+
+  Offset: 6d, Index: 61
+    startx_length 9, f
+      0x00000000004011a0 <baz>..
+      0x00000000004011ae <baz+0xe>..
+        [ 0] reg5
+    startx_length 5, 2
+      0x00000000004011af <baz+0xf>..
+      0x00000000004011b0 <baz+0x10>..
+        [ 0] entry_value:
+             [ 0] reg5
+        [ 3] stack_value
+    end_of_list
+
+  Offset: 7b, Index: 6f
+    startx_length 9, 10
+      0x00000000004011a0 <baz>..
+      0x00000000004011af <baz+0xf>..
+        [ 0] reg5
+    end_of_list
+
+
+testfile-world5.dwo:
+
+
+DWARF section [ 3] '.debug_loclists.dwo' at offset 0x217:
+Table at Offset 0x0:
+
+ Length:              128
+ DWARF version:         5
+ Address size:          8
+ Segment size:          0
+ Offset entries:        7
+ CU [    14] base: 000000000000000000
+
+  Offsets starting at 0xc:
+   [     0] 0x1c
+   [     1] 0x2a
+   [     2] 0x38
+   [     3] 0x3e
+   [     4] 0x4c
+   [     5] 0x52
+   [     6] 0x6d
+
+  Offset: 28, Index: 1c
+    startx_length 2, 14
+      0x0000000000401060 <main>..
+      0x0000000000401073 <main+0x13>..
+        [ 0] reg5
+    startx_length 4, c
+      0x0000000000401074 <main+0x14>..
+      0x000000000040107f <main+0x1f>..
+        [ 0] entry_value:
+             [ 0] reg5
+        [ 3] stack_value
+    end_of_list
+
+  Offset: 36, Index: 2a
+    startx_length 2, 18
+      0x0000000000401060 <main>..
+      0x0000000000401077 <main+0x17>..
+        [ 0] reg4
+    startx_length 7, 6
+      0x0000000000401078 <main+0x18>..
+      0x000000000040107d <main+0x1d>..
+        [ 0] entry_value:
+             [ 0] reg4
+        [ 3] stack_value
+    end_of_list
+
+  Offset: 44, Index: 38
+    startx_length 3, 7
+      0x0000000000401071 <main+0x11>..
+      0x0000000000401077 <main+0x17>..
+        [ 0] reg0
+    end_of_list
+
+  Offset: 4a, Index: 3e
+    startx_length d, 8
+      0x00000000004011c0 <calc>..
+      0x00000000004011c7 <calc+0x7>..
+        [ 0] reg5
+    startx_length e, 23
+      0x00000000004011c8 <calc+0x8>..
+      0x00000000004011ea <calc+0x2a>..
+        [ 0] entry_value:
+             [ 0] reg5
+        [ 3] stack_value
+    end_of_list
+
+  Offset: 58, Index: 4c
+    startx_length f, b
+      0x00000000004011d8 <calc+0x18>..
+      0x00000000004011e2 <calc+0x22>..
+        [ 0] reg0
+    end_of_list
+
+  Offset: 5e, Index: 52
+    startx_length f, 2
+      0x00000000004011d8 <calc+0x18>..
+      0x00000000004011d9 <calc+0x19>..
+        [ 0] reg1
+    startx_length 10, 5
+      0x00000000004011da <calc+0x1a>..
+      0x00000000004011de <calc+0x1e>..
+        [ 0] reg5
+    startx_length 0, 4
+      0x00000000004011df <calc+0x1f>..
+      0x00000000004011e2 <calc+0x22>..
+        [ 0] entry_value:
+             [ 0] reg5
+        [ 3] deref_size 1
+        [ 5] const1u 56
+        [ 7] shl
+        [ 8] const1u 56
+        [10] shra
+        [11] stack_value
+    end_of_list
+
+  Offset: 79, Index: 6d
+    startx_length f, 2
+      0x00000000004011d8 <calc+0x18>..
+      0x00000000004011d9 <calc+0x19>..
+        [ 0] reg1
+    startx_length 10, 9
+      0x00000000004011da <calc+0x1a>..
+      0x00000000004011e2 <calc+0x22>..
+        [ 0] reg5
+    end_of_list
+
+EOF
+
 exit 0
-- 
1.8.3.1


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]