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] libdw: Handle .debug_loclists in dwarf_getlocation.


Handle all new DW_LLE opcodes in .debug_loclists in dwarf_getlocation.
__libdw_read_begin_end_pair_inc now also handles a default location
(which is simply the range [0,-1]). Since expression blocks can now
also come from the .debug_loclists section add a new fake_loclists_cu
necessary for checking bounds while parsing expression blocks. Adapt
varlocs test to handle .debug only files. Run it on testfileranges5.debug
and testfilesplitranges5.debug.

testfilesplitranges5.debug had to be regenerated with a newer GCC because
of a bug in the generation of DW_LLE_startx_length:
https://gcc.gnu.org/ml/gcc-patches/2018-05/msg01562.html

Signed-off-by: Mark Wielaard <mark@klomp.org>
---
 libdw/ChangeLog                      |  17 ++++
 libdw/dwarf_begin_elf.c              |  27 +++++++
 libdw/dwarf_end.c                    |   5 ++
 libdw/dwarf_getlocation.c            |  99 ++++++++++++++++++++---
 libdw/dwarf_getlocation_attr.c       |   6 +-
 libdw/dwarf_ranges.c                 | 114 +++++++++++++++++++++++++++
 libdw/libdwP.h                       |  87 +++++++++++++++++++-
 libdw/libdw_findcu.c                 |   1 +
 src/ChangeLog                        |   5 ++
 src/readelf.c                        |   4 +-
 tests/ChangeLog                      |  11 +++
 tests/run-varlocs.sh                 | 148 +++++++++++++++++++++++++++++++++++
 tests/testfile-ranges-hello5.dwo.bz2 | Bin 1296 -> 1261 bytes
 tests/testfile-ranges-world5.dwo.bz2 | Bin 1466 -> 1514 bytes
 tests/testfilesplitranges5.debug.bz2 | Bin 2235 -> 2246 bytes
 tests/varlocs.c                      |  39 +++++++--
 16 files changed, 538 insertions(+), 25 deletions(-)

diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index 0db49bf..22712f1 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,20 @@
+2018-04-07  Mark Wielaard  <mark@klomp.org>
+
+	* libdwP.h (struct Dwarf_CU): Add locs_base.
+	(__libdw_cu_locs_base): New static inline function.
+	* libdw_findcu.c (__libdw_intern_next_unit): Initialize locs_base.
+	* dwarf_begin_elf.c (valid_p): Create fake_loclists_cu if necessary.
+	* dwarf_end.c (dwarf_end): Clean up fake_loclists_cu.
+	* dwarf_getlocation.c (initial_offset): Handle .debug_loclists.
+	(getlocations_addr): Likewise.
+	(dwarf_getlocation_addr): Likewise.
+	* dwarf_getlocation_attr.c (attr_form_cu): Use fake_loclists_cu for
+	DWARF5.
+	(initial_offset): Handle DW_FORM_loclistx.
+	* dwarf_ranges.c (__libdw_read_begin_end_pair_inc): Handle
+	.debug_loclists.
+	* libdwP.h (struct Dwarf): Add fake_loclists_cu.
+
 2018-04-12  Mark Wielaard  <mark@klomp.org>
 
 	* dwarf.h: Add DWARF5 location list entry DW_LLE encodings.
diff --git a/libdw/dwarf_begin_elf.c b/libdw/dwarf_begin_elf.c
index af5096f..513af2b 100644
--- a/libdw/dwarf_begin_elf.c
+++ b/libdw/dwarf_begin_elf.c
@@ -226,6 +226,9 @@ valid_p (Dwarf *result)
       result = NULL;
     }
 
+  /* For dwarf_location_attr () we need a "fake" CU to indicate
+     where the "fake" attribute data comes from.  This is a block
+     inside the .debug_loc or .debug_loclists section.  */
   if (result != NULL && result->sectiondata[IDX_debug_loc] != NULL)
     {
       result->fake_loc_cu = (Dwarf_CU *) calloc (1, sizeof (Dwarf_CU));
@@ -248,6 +251,29 @@ valid_p (Dwarf *result)
 	}
     }
 
+  if (result != NULL && result->sectiondata[IDX_debug_loclists] != NULL)
+    {
+      result->fake_loclists_cu = (Dwarf_CU *) calloc (1, sizeof (Dwarf_CU));
+      if (unlikely (result->fake_loclists_cu == NULL))
+	{
+	  Dwarf_Sig8_Hash_free (&result->sig8_hash);
+	  __libdw_seterrno (DWARF_E_NOMEM);
+	  free (result->fake_loc_cu);
+	  free (result);
+	  result = NULL;
+	}
+      else
+	{
+	  result->fake_loclists_cu->sec_idx = IDX_debug_loclists;
+	  result->fake_loclists_cu->dbg = result;
+	  result->fake_loclists_cu->startp
+	    = result->sectiondata[IDX_debug_loclists]->d_buf;
+	  result->fake_loclists_cu->endp
+	    = (result->sectiondata[IDX_debug_loclists]->d_buf
+	       + result->sectiondata[IDX_debug_loclists]->d_size);
+	}
+    }
+
   /* For DW_OP_constx/GNU_const_index and DW_OP_addrx/GNU_addr_index
      the dwarf_location_attr () will need a "fake" address CU to
      indicate where the attribute data comes from.  This is a just
@@ -260,6 +286,7 @@ valid_p (Dwarf *result)
 	  Dwarf_Sig8_Hash_free (&result->sig8_hash);
 	  __libdw_seterrno (DWARF_E_NOMEM);
 	  free (result->fake_loc_cu);
+	  free (result->fake_loclists_cu);
 	  free (result);
 	  result = NULL;
 	}
diff --git a/libdw/dwarf_end.c b/libdw/dwarf_end.c
index 1954674..23a50a0 100644
--- a/libdw/dwarf_end.c
+++ b/libdw/dwarf_end.c
@@ -113,6 +113,11 @@ dwarf_end (Dwarf *dwarf)
 	  cu_free (dwarf->fake_loc_cu);
 	  free (dwarf->fake_loc_cu);
 	}
+      if (dwarf->fake_loclists_cu != NULL)
+	{
+	  cu_free (dwarf->fake_loclists_cu);
+	  free (dwarf->fake_loclists_cu);
+	}
       if (dwarf->fake_addr_cu != NULL)
 	{
 	  cu_free (dwarf->fake_addr_cu);
diff --git a/libdw/dwarf_getlocation.c b/libdw/dwarf_getlocation.c
index d4b8eff..d293e75 100644
--- a/libdw/dwarf_getlocation.c
+++ b/libdw/dwarf_getlocation.c
@@ -696,13 +696,77 @@ __libdw_cu_base_address (Dwarf_CU *cu)
 static int
 initial_offset (Dwarf_Attribute *attr, ptrdiff_t *offset)
 {
-  size_t secidx = IDX_debug_loc;
+  size_t secidx = (attr->cu->version < 5
+		   ? IDX_debug_loc : IDX_debug_loclists);
 
   Dwarf_Word start_offset;
-  if (__libdw_formptr (attr, secidx,
-		       DWARF_E_NO_DEBUG_LOC,
-		       NULL, &start_offset) == NULL)
-    return -1;
+  if (attr->form == DW_FORM_loclistx)
+    {
+      Dwarf_Word idx;
+      Dwarf_CU *cu = attr->cu;
+      const unsigned char *datap = attr->valp;
+      const unsigned char *endp = cu->endp;
+      if (datap >= endp)
+	{
+	  __libdw_seterrno (DWARF_E_INVALID_DWARF);
+	  return -1;
+	}
+      get_uleb128 (idx, datap, endp);
+
+      Elf_Data *data = cu->dbg->sectiondata[secidx];
+      if (data == NULL && cu->unit_type == DW_UT_split_compile)
+	{
+	  cu = __libdw_find_split_unit (cu);
+	  if (cu != NULL)
+	    data = cu->dbg->sectiondata[secidx];
+	}
+
+      if (data == NULL)
+	{
+	  __libdw_seterrno (secidx == IDX_debug_loc
+                            ? DWARF_E_NO_DEBUG_LOC
+                            : DWARF_E_NO_DEBUG_LOCLISTS);
+	  return -1;
+	}
+
+      Dwarf_Off loc_base_off = __libdw_cu_locs_base (cu);
+
+      /* The section should at least contain room for one offset.  */
+      size_t sec_size = cu->dbg->sectiondata[secidx]->d_size;
+      size_t offset_size = cu->offset_size;
+      if (offset_size > sec_size)
+	{
+	invalid_offset:
+	  __libdw_seterrno (DWARF_E_INVALID_OFFSET);
+	  return -1;
+	}
+
+      /* And the base offset should be at least inside the section.  */
+      if (loc_base_off > (sec_size - offset_size))
+	goto invalid_offset;
+
+      size_t max_idx = (sec_size - offset_size - loc_base_off) / offset_size;
+      if (idx > max_idx)
+	goto invalid_offset;
+
+      datap = (cu->dbg->sectiondata[secidx]->d_buf
+	       + loc_base_off + (idx * offset_size));
+      if (offset_size == 4)
+	start_offset = read_4ubyte_unaligned (cu->dbg, datap);
+      else
+	start_offset = read_8ubyte_unaligned (cu->dbg, datap);
+
+      start_offset += loc_base_off;
+    }
+  else
+    {
+      if (__libdw_formptr (attr, secidx,
+			   (secidx == IDX_debug_loc
+			    ? DWARF_E_NO_DEBUG_LOC
+			    : DWARF_E_NO_DEBUG_LOCLISTS),
+			    NULL, &start_offset) == NULL)
+	return -1;
+    }
 
   *offset = start_offset;
   return 0;
@@ -716,7 +780,7 @@ getlocations_addr (Dwarf_Attribute *attr, ptrdiff_t offset,
 {
   Dwarf_CU *cu = attr->cu;
   Dwarf *dbg = cu->dbg;
-  size_t secidx = IDX_debug_loc;
+  size_t secidx = cu->version < 5 ? IDX_debug_loc : IDX_debug_loclists;
   const unsigned char *readp = locs->d_buf + offset;
   const unsigned char *readendp = locs->d_buf + locs->d_size;
 
@@ -741,13 +805,22 @@ getlocations_addr (Dwarf_Attribute *attr, ptrdiff_t offset,
 
   /* We have a location expression.  */
   Dwarf_Block block;
-  if (readendp - readp < 2)
+  if (secidx == IDX_debug_loc)
     {
-    invalid:
-      __libdw_seterrno (DWARF_E_INVALID_DWARF);
-      return -1;
+      if (readendp - readp < 2)
+	{
+	invalid:
+	  __libdw_seterrno (DWARF_E_INVALID_DWARF);
+	  return -1;
+	}
+      block.length = read_2ubyte_unaligned_inc (dbg, readp);
+    }
+  else
+    {
+      if (readendp - readp < 1)
+	goto invalid;
+      get_uleb128 (block.length, readp, readendp);
     }
-  block.length = read_2ubyte_unaligned_inc (dbg, readp);
   block.data = (unsigned char *) readp;
   if (readendp - readp < (ptrdiff_t) block.length)
     goto invalid;
@@ -815,7 +888,7 @@ dwarf_getlocation_addr (Dwarf_Attribute *attr, Dwarf_Addr address,
   if (initial_offset (attr, &off) != 0)
     return -1;
 
-  size_t secidx = IDX_debug_loc;
+  size_t secidx = attr->cu->version < 5 ? IDX_debug_loc : IDX_debug_loclists;
   const Elf_Data *d = attr->cu->dbg->sectiondata[secidx];
 
   while (got < maxlocs
@@ -896,7 +969,7 @@ dwarf_getlocations (Dwarf_Attribute *attr, ptrdiff_t offset, Dwarf_Addr *basep,
 	return -1;
     }
 
-  size_t secidx = IDX_debug_loc;
+  size_t secidx = attr->cu->version < 5 ? IDX_debug_loc : IDX_debug_loclists;
   const Elf_Data *d = attr->cu->dbg->sectiondata[secidx];
 
   return getlocations_addr (attr, offset, basep, startp, endp,
diff --git a/libdw/dwarf_getlocation_attr.c b/libdw/dwarf_getlocation_attr.c
index 9d7fd4b..875fc5d 100644
--- a/libdw/dwarf_getlocation_attr.c
+++ b/libdw/dwarf_getlocation_attr.c
@@ -38,7 +38,7 @@ attr_form_cu (Dwarf_Attribute *attr)
 {
   /* If the attribute has block/expr form the data comes from the
      .debug_info from the same cu as the attr.  Otherwise it comes from
-     the .debug_loc data section.  */
+     the .debug_loc or .debug_loclists data section.  */
   switch (attr->form)
     {
     case DW_FORM_block1:
@@ -48,7 +48,9 @@ attr_form_cu (Dwarf_Attribute *attr)
     case DW_FORM_exprloc:
       return attr->cu;
     default:
-      return attr->cu->dbg->fake_loc_cu;
+      return (attr->cu->version < 5
+	      ? attr->cu->dbg->fake_loc_cu
+	      : attr->cu->dbg->fake_loclists_cu);
     }
 }
 
diff --git a/libdw/dwarf_ranges.c b/libdw/dwarf_ranges.c
index fa65e5c..0f3ee6b 100644
--- a/libdw/dwarf_ranges.c
+++ b/libdw/dwarf_ranges.c
@@ -36,6 +36,7 @@
 
 /* Read up begin/end pair and increment read pointer.
     - If it's normal range record, set up `*beginp' and `*endp' and return 0.
+    - If it's a default location, set `*beginp' (0), `*endp' (-1) and return 0.
     - If it's base address selection record, set up `*basep' and return 1.
     - If it's end of rangelist, don't set anything and return 2
     - If an error occurs, don't set anything and return -1.  */
@@ -197,6 +198,119 @@ __libdw_read_begin_end_pair_inc (Dwarf_CU *cu, int sec_index,
 	  goto invalid;
 	}
     }
+  else if (sec_index == IDX_debug_loclists)
+    {
+      const unsigned char *addr = *addrp;
+      if (addrend - addr < 1)
+	goto invalid;
+
+      const char code = *addr++;
+      uint64_t begin = 0, end = 0, base = *basep, addr_idx;
+      switch (code)
+	{
+	case DW_LLE_end_of_list:
+	  *addrp = addr;
+	  return 2;
+
+	case DW_LLE_base_addressx:
+	  if (addrend - addr < 1)
+	    goto invalid;
+	  get_uleb128 (addr_idx, addr, addrend);
+	  if (__libdw_addrx (cu, addr_idx, &base) != 0)
+	    return -1;
+
+	  *basep = base;
+	  *addrp = addr;
+	  return 1;
+
+	case DW_LLE_startx_endx:
+	  if (addrend - addr < 1)
+	    goto invalid;
+	  get_uleb128 (addr_idx, addr, addrend);
+	  if (__libdw_addrx (cu, addr_idx, &begin) != 0)
+	    return -1;
+	  if (addrend - addr < 1)
+	    goto invalid;
+	  get_uleb128 (addr_idx, addr, addrend);
+	  if (__libdw_addrx (cu, addr_idx, &end) != 0)
+	    return -1;
+
+	  *beginp = begin;
+	  *endp = end;
+	  *addrp = addr;
+	  return 0;
+
+	case DW_LLE_startx_length:
+	  if (addrend - addr < 1)
+	    goto invalid;
+	  get_uleb128 (addr_idx, addr, addrend);
+	  if (__libdw_addrx (cu, addr_idx, &begin) != 0)
+	    return -1;
+	  if (addrend - addr < 1)
+	    goto invalid;
+	  get_uleb128 (end, addr, addrend);
+
+	  *beginp = begin;
+	  *endp = begin + end;
+	  *addrp = addr;
+	  return 0;
+
+	case DW_LLE_offset_pair:
+	  if (addrend - addr < 1)
+	    goto invalid;
+	  get_uleb128 (begin, addr, addrend);
+	  if (addrend - addr < 1)
+	    goto invalid;
+	  get_uleb128 (end, addr, addrend);
+
+	  *beginp = begin + base;
+	  *endp = end + base;
+	  *addrp = addr;
+	  return 0;
+
+	case DW_LLE_default_location:
+	  *beginp = 0;
+	  *endp = (Dwarf_Addr) -1;
+	  *addrp = addr;
+	  return 0;
+
+	case DW_LLE_base_address:
+	  if (addrend - addr < width)
+	    goto invalid;
+	  __libdw_read_address_inc (dbg, sec_index, &addr, width, &base);
+
+	  *basep = base;
+	  *addrp = addr;
+	  return 1;
+
+	case DW_LLE_start_end:
+	  if (addrend - addr < 2 * width)
+	    goto invalid;
+	  __libdw_read_address_inc (dbg, sec_index, &addr, width, &begin);
+	  __libdw_read_address_inc (dbg, sec_index, &addr, width, &end);
+
+	  *beginp = begin;
+	  *endp = end;
+	  *addrp = addr;
+	  return 0;
+
+	case DW_LLE_start_length:
+	  if (addrend - addr < width)
+	    goto invalid;
+	  __libdw_read_address_inc (dbg, sec_index, &addr, width, &begin);
+	  if (addrend - addr < 1)
+	    goto invalid;
+	  get_uleb128 (end, addr, addrend);
+
+	  *beginp = begin;
+	  *endp = begin + end;
+	  *addrp = addr;
+	  return 0;
+
+	default:
+	  goto invalid;
+	}
+    }
   else
     {
       __libdw_seterrno (DWARF_E_INVALID_DWARF);
diff --git a/libdw/libdwP.h b/libdw/libdwP.h
index f99ea58..dd47009 100644
--- a/libdw/libdwP.h
+++ b/libdw/libdwP.h
@@ -206,8 +206,11 @@ struct Dwarf
   struct Dwarf_CFI_s *cfi;
 
   /* Fake loc CU.  Used when synthesizing attributes for Dwarf_Ops that
-     came from a location list entry in dwarf_getlocation_attr.  */
+     came from a location list entry in dwarf_getlocation_attr.
+     Depending on version this is the .debug_loc or .debug_loclists
+     section (could be both if mixing CUs with different DWARF versions).  */
   struct Dwarf_CU *fake_loc_cu;
+  struct Dwarf_CU *fake_loclists_cu;
 
   /* Similar for addrx/constx, which will come from .debug_addr section.  */
   struct Dwarf_CU *fake_addr_cu;
@@ -365,6 +368,10 @@ struct Dwarf_CU
      __libdw_cu_ranges_base.  */
   Dwarf_Off ranges_base;
 
+  /* The start of the offset table in .debug_loclists.
+     Don't access directly, call __libdw_cu_locs_base.  */
+  Dwarf_Off locs_base;
+
   /* Memory boundaries of this CU.  */
   void *startp;
   void *endp;
@@ -1177,6 +1184,84 @@ __libdw_cu_ranges_base (Dwarf_CU *cu)
 }
 
 
+/* The start of the offset table in .debug_loclists for DWARF5.  */
+static inline Dwarf_Off
+__libdw_cu_locs_base (Dwarf_CU *cu)
+{
+  if (cu->locs_base == (Dwarf_Off) -1)
+    {
+      Dwarf_Off offset = 0;
+      Dwarf_Die cu_die = CUDIE(cu);
+      Dwarf_Attribute attr;
+      if (dwarf_attr (&cu_die, DW_AT_loclists_base, &attr) != NULL)
+	{
+	  Dwarf_Word off;
+	  if (dwarf_formudata (&attr, &off) == 0)
+	    offset = off;
+	}
+
+      /* There wasn't an loclists_base, if the Dwarf does have a
+	 .debug_loclists section, then it might be we need the
+	 base after the first header. */
+      Elf_Data *data = cu->dbg->sectiondata[IDX_debug_loclists];
+      if (offset == 0 && data != NULL)
+	{
+	  Dwarf *dbg = cu->dbg;
+	  const unsigned char *readp = data->d_buf;
+	  const unsigned char *const dataend
+	    = (unsigned char *) data->d_buf + data->d_size;
+
+	  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 no_header;
+
+	      unit_length = read_8ubyte_unaligned_inc (dbg, readp);
+	      offset_size = 8;
+	    }
+
+	  if (readp > dataend - 8
+	      || unit_length < 8
+	      || unit_length > (uint64_t) (dataend - readp))
+	    goto no_header;
+
+	  uint16_t version = read_2ubyte_unaligned_inc (dbg, readp);
+	  if (version != 5)
+	    goto no_header;
+
+	  uint8_t address_size = *readp++;
+	  if (address_size != 4 && address_size != 8)
+	    goto no_header;
+
+	  uint8_t segment_size = *readp++;
+	  if (segment_size != 0)
+	    goto no_header;
+
+	  uint32_t offset_entry_count;
+	  offset_entry_count = read_4ubyte_unaligned_inc (dbg, readp);
+
+	  const unsigned char *offset_array_start = readp;
+	  if (offset_entry_count <= 0)
+	    goto no_header;
+
+	  uint64_t needed = offset_entry_count * offset_size;
+	  if (unit_length - 8 < needed)
+	    goto no_header;
+
+	  offset = (Dwarf_Off) (offset_array_start
+				- (unsigned char *) data->d_buf);
+	}
+
+    no_header:
+      cu->locs_base = offset;
+    }
+
+  return cu->locs_base;
+}
+
+
 /* Link skeleton and split compile units.  */
 static inline void
 __libdw_link_skel_split (Dwarf_CU *skel, Dwarf_CU *split)
diff --git a/libdw/libdw_findcu.c b/libdw/libdw_findcu.c
index 83c2eb1..9d23199 100644
--- a/libdw/libdw_findcu.c
+++ b/libdw/libdw_findcu.c
@@ -122,6 +122,7 @@ __libdw_intern_next_unit (Dwarf *dbg, bool debug_types)
   newp->addr_base = (Dwarf_Off) -1;
   newp->str_off_base = (Dwarf_Off) -1;
   newp->ranges_base = (Dwarf_Off) -1;
+  newp->locs_base = (Dwarf_Off) -1;
 
   newp->startp = data->d_buf + newp->start;
   newp->endp = data->d_buf + newp->end;
diff --git a/src/ChangeLog b/src/ChangeLog
index 8e02d3c..b6c2743 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,8 @@
+2018-04-07  Mark Wielaard  <mark@klomp.org>
+
+	* readelf.c (attr_callback): Handle DW_FORM_loclistx and
+	DW_AT_segment.
+
 2018-04-12  Mark Wielaard  <mark@klomp.org>
 
 	* readelf.c (dwarf_loc_list_encoding_string): New functions.
diff --git a/src/readelf.c b/src/readelf.c
index 311a3ca..0171673 100644
--- a/src/readelf.c
+++ b/src/readelf.c
@@ -6779,6 +6779,7 @@ attr_callback (Dwarf_Attribute *attrp, void *arg)
 
     case DW_FORM_sec_offset:
     case DW_FORM_rnglistx:
+    case DW_FORM_loclistx:
     case DW_FORM_implicit_const:
     case DW_FORM_udata:
     case DW_FORM_sdata:
@@ -6808,7 +6809,7 @@ attr_callback (Dwarf_Attribute *attrp, void *arg)
 	    }
 	  FALLTHROUGH;
 
-	/* These cases always take a loclistptr and no constant. */
+	/* These cases always take a loclist[ptr] and no constant. */
 	case DW_AT_location:
 	case DW_AT_data_location:
 	case DW_AT_vtable_elem_location:
@@ -6817,6 +6818,7 @@ attr_callback (Dwarf_Attribute *attrp, void *arg)
 	case DW_AT_frame_base:
 	case DW_AT_return_addr:
 	case DW_AT_static_link:
+	case DW_AT_segment:
 	case DW_AT_GNU_call_site_value:
 	case DW_AT_GNU_call_site_data_value:
 	case DW_AT_GNU_call_site_target:
diff --git a/tests/ChangeLog b/tests/ChangeLog
index 6e366eb..fb00f0a 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,3 +1,14 @@
+2018-04-07  Mark Wielaard  <mark@klomp.org>
+
+	* testfile-ranges-hello5.dwo.bz2: Regenerated.
+	* testfile-ranges-world5.dwo.bz2: Likewise.
+	* testsplitfileranges5.debug.bz2: Likewise.
+	* run-varlocs.sh: Run on testfileranges5.debug and
+	testsplitfileranges5.debug.
+	* varlocs.c (is_debug): New bool.
+	(print_expr): Don't fail on missing CFI for is_debug.
+	(main): Parse --debug, set is_debug.
+
 2018-04-12  Mark Wielaard  <mark@klomp.org>
 
 	* run-readelf-loc.sh: Add new testcases.
diff --git a/tests/run-varlocs.sh b/tests/run-varlocs.sh
index 2781fef..0c8dae3 100755
--- a/tests/run-varlocs.sh
+++ b/tests/run-varlocs.sh
@@ -124,6 +124,154 @@ module 'testfile_implicit_pointer'
     frame_base: {call_frame_cfa {bregx(7,8)}}
 EOF
 
+# Multi CU DWARF5. See run-dwarf-ranges.sh.
+testfiles testfileranges5.debug
+testrun_compare ${abs_top_builddir}/tests/varlocs --debug -e testfileranges5.debug <<\EOF
+module 'testfileranges5.debug'
+[c] CU 'hello.c'@0
+  [2a] function 'no_say'@4004f0
+    frame_base: {call_frame_cfa {...}}
+    [4a] parameter 'prefix'
+      [4004f0,4004fa) {reg5}
+      [4004fa,4004ff) {entry_value(1) {reg5}, stack_value}
+    [58] variable 'world'
+      <no value>
+  [89] function 'main'@4003e0
+    frame_base: {call_frame_cfa {...}}
+    [a9] parameter 'argc'
+      [4003e0,4003f2) {reg5}
+      [4003f2,4003f7) {entry_value(1) {reg5}, stack_value}
+    [b7] parameter 'argv'
+      [4003e0,4003f6) {reg4}
+      [4003f6,4003f7) {entry_value(1) {reg4}, stack_value}
+  [c5] inlined function 'subject'@4003e3
+    [e0] parameter 'count'
+      [4003e3,4003ef) {reg5}
+    [e9] parameter 'word'
+      [4003e3,4003ef) {reg0}
+  [12e] function 'subject'@4004e0
+    frame_base: {call_frame_cfa {...}}
+    [149] parameter 'word'
+      [4004e0,4004f0) {reg5}
+    [150] parameter 'count'
+      [4004e0,4004f0) {reg4}
+module 'testfileranges5.debug'
+[170] CU 'world.c'@400500
+  [192] function 'no_main'@400550
+    frame_base: {call_frame_cfa {...}}
+    [1b3] parameter 'argc'
+      [400550,400562) {reg5}
+      [400562,400567) {entry_value(1) {reg5}, stack_value}
+    [1c1] parameter 'argv'
+      [400550,400566) {reg4}
+      [400566,400567) {entry_value(1) {reg4}, stack_value}
+  [1cf] inlined function 'no_subject'@400553
+    [1ea] parameter 'count'
+      [400553,40055f) {reg5}
+    [1f3] parameter 'word'
+      [400553,40055f) {reg0}
+  [24b] function 'say'@400500
+    frame_base: {call_frame_cfa {...}}
+    [26c] parameter 'prefix'
+      [400500,40050e) {reg5}
+      [40050e,40051c) {reg3}
+      [40051c,400527) {entry_value(1) {reg5}, stack_value}
+      [400527,400535) {reg3}
+      [400535,400540) {entry_value(1) {reg5}, stack_value}
+    [27a] variable 'world'
+      [400513,40051b) {reg0}
+      [400527,400534) {reg0}
+  [289] inlined function 'happy'@40051c
+    [2a0] parameter 'w'
+      [400527,400534) {reg0}
+  [2a9] inlined function 'sad'@40051c
+    [2bc] parameter 'c'
+      [40051b,400526) {reg0}
+      [400526,400527) {entry_value(1) {reg5}}
+      [400534,40053f) {reg0}
+  [320] function 'no_subject'@400540
+    frame_base: {call_frame_cfa {...}}
+    [33b] parameter 'word'
+      [400540,400550) {reg5}
+    [342] parameter 'count'
+      [400540,400550) {reg4}
+EOF
+
+# Multi CU Split DWARF5. See run-dwarf-ranges.sh.
+testfiles testfilesplitranges5.debug
+testfiles testfile-ranges-hello5.dwo testfile-ranges-world5.dwo
+testrun_compare ${abs_top_builddir}/tests/varlocs --debug -e testfilesplitranges5.debug <<\EOF
+module 'testfilesplitranges5.debug'
+[14] CU 'hello.c'
+  [1d] function 'no_say'@401160
+    frame_base: {call_frame_cfa {...}}
+    [33] parameter 'prefix'
+      [401160,401169) {reg5}
+      [401169,40116a) {entry_value(1) {reg5}, stack_value}
+      [40116a,401175) {reg5}
+      [401175,40117a) {entry_value(1) {reg5}, stack_value}
+    [3c] variable 'world'
+      [401160,40117a) {addr: 0x402004, stack_value}
+  [7e] function 'main'@401050
+    frame_base: {call_frame_cfa {...}}
+    [94] parameter 'argc'
+      [401050,401062) {reg5}
+      [401062,401067) {entry_value(1) {reg5}, stack_value}
+    [9d] parameter 'argv'
+      [401050,401066) {reg4}
+      [401066,401067) {entry_value(1) {reg4}, stack_value}
+  [a6] inlined function 'subject'@401053
+    [bb] parameter 'count'
+      [401053,40105f) {reg5}
+    [c1] parameter 'word'
+      [401053,40105f) {reg0}
+  [f6] function 'subject'@401150
+    frame_base: {call_frame_cfa {...}}
+    [10a] parameter 'word'
+      [401150,401160) {reg5}
+    [111] parameter 'count'
+      [401150,401160) {reg4}
+module 'testfilesplitranges5.debug'
+[14] CU 'world.c'
+  [1d] function 'no_main'@4011d0
+    frame_base: {call_frame_cfa {...}}
+    [35] parameter 'argc'
+      [4011d0,4011e2) {reg5}
+      [4011e2,4011e7) {entry_value(1) {reg5}, stack_value}
+    [3e] parameter 'argv'
+      [4011d0,4011e6) {reg4}
+      [4011e6,4011e7) {entry_value(1) {reg4}, stack_value}
+  [47] inlined function 'no_subject'@4011d3
+    [5c] parameter 'count'
+      [4011d3,4011df) {reg5}
+    [62] parameter 'word'
+      [4011d3,4011df) {reg0}
+  [a7] function 'say'@401180
+    frame_base: {call_frame_cfa {...}}
+    [c2] parameter 'prefix'
+      [401180,40118e) {reg5}
+      [40118e,40119c) {reg3}
+      [40119c,4011a7) {entry_value(1) {reg5}, stack_value}
+      [4011a7,4011b5) {reg3}
+      [4011b5,4011c0) {entry_value(1) {reg5}, stack_value}
+    [cb] variable 'world'
+      [401193,40119b) {reg0}
+      [4011a7,4011b4) {reg0}
+  [d5] inlined function 'happy'@40119b
+    [e3] parameter 'w'
+      [4011a7,4011b4) {reg0}
+  [e9] inlined function 'sad'@40119b
+    [f3] parameter 'c'
+      [40119b,4011a6) {reg0}
+      [4011a6,4011a7) {entry_value(1) {reg5}}
+      [4011b4,4011bf) {reg0}
+  [147] function 'no_subject'@4011c0
+    frame_base: {call_frame_cfa {...}}
+    [15b] parameter 'word'
+      [4011c0,4011d0) {reg5}
+    [162] parameter 'count'
+      [4011c0,4011d0) {reg4}
+EOF
 
 # DW_OP_addrx and DW_OP_constx testcases.
 #
diff --git a/tests/testfile-ranges-hello5.dwo.bz2 b/tests/testfile-ranges-hello5.dwo.bz2
index 03d252e14d9ffed0a12abad13afedbe5e4e116c6..0f6346e793f2d8ea02e6208e4bb15af243ccae90 100644
GIT binary patch
literal 1261
zcmV<J1QPo~T4*^jL0KkKS&QYRF#rNJfB*mg|NsAg|9}7A|NsC0|NsB*|M&j?{{R1f
z{l5Qu|9`*&`~$aDy1*)fQhJS%Jx!=I4^z=LO;0K14^gM6V2@Ds2c-2h$n_qh)EYfT
zPfbQ4nvX&T)HG;4M%48*^qP4<G(AsK%6e)Cih6@;V<-(Vs63~WQR;e6Nwmrt5NOZ<
z000^Q00000000000Lh>L00001pa1{>00000005~*lTD=YPfZ#c0Lowl#M1_V13(i2
zpo{`!H1wDn001Tc07gsz005YpU;vl^j0u1M(2)tIqtbaJ(KKY!$~_<rskDKosM?J*
z&;ZcUplE5J&>8`zfB*mh13&-)kOM#f0001J8Vm=<7g!(&x|Kf0b{V4Jpbi0<WPwjD
z>+Z|S*z=444cmt529##en3&p>+@!>m^NX3aG6fLr0AyebG{xmYA<7U0W(YTmO2gXo
z=(zbCBP&CROJ>Dz1R;?CLMXu*fFVtHDHvcOmOQ{DIc=H%V89A9g+f4O2n>LF@c{rG
z%$NociK((VYRV{#g4TEROBFU@8pVWUk-!B5Izr1Dh{NU4W|cM-7tZ$S9?l(Nf#y%v
zzYPdW8&f7`MLEhswMKyG)agh-;Zpoz>6h%tVxXiH#ts}C-s0e&odu?8{T3d3D9Vlx
zGdha#4djB$83x0gk>)5nC`=BmHs#)lf60&xL}E~wDKM~7x#|?DBwA#~_DwX$T1c;~
zxF8x8f3{d6A(_;7Czxj#fv0{!83jLtM5TT;f9IZ(Fk(tf<9T9elI*%a!ssMUL1rfL
zv?J;nAXHIb4$?vMOM$SfAE&Eat>#WgcrJ4U(ur*KFkX%F=-Q5wbWj5T0&f;RH3w~o
z5CGugirfM-jfV`%sx{|O*IFi*MQD*~rty)Ok5p&{Rwh8mdSwNFgXustKnkddl+5Yq
zgb<Q-VX_Is4YixC)umNjwCSFq_IL8`Udmh;kZMt2-C>x>UjSAG5QhU?6fmN>f=RfE
z2o>5~bX_DE06~KV@!%oGO+`L|ZYL!^sk2(Wk>5*858mx1*<u^;0O)WvG*sw|*5Rq!
zgw%KdwHO0Q(t{4_lt=&>QwvxTSpW*_BnEH-OO0~{7?YP=NH4Oc09sn42MQOQj3G$V
z&OEUkR^hXtWuim_lR(TVoYn%N2M+Uhgkn2jphQWubse~uX)5`YG>OE;yilPz!wg`Y
zIBWrdjt0Gk#2y5|<Hi6W@5W#W**IOy*|+W(#Sv$8hyo_HC558a5Yytyk;Q*IToMl(
zfbiJS#(-!6!?=#7MRa*(o~+y3*(f($O~xZpGn^*Oe_h9YRzIz=tqYG*Icc&7-Gvzf
zW|IuK+ppGP<b3;Q*LOHXslLcjgp^78?&;2`VkKt0iqoDA!DCf5PEXZ%irfI^pzvdV
zlqFH<NYGMvOd_wMCG~9ml^fne%XO0DCr44cW7&`I8k@d)UU~i$%2t*zbG#yJVlb&+
zIQ*_@QlIJ(o-0{V=SxD2pF06cXu4t${z_Nmom*fXNQN1c6V6GdvMimFYU#9Es1YR`
zg@1`>VtZy&BEH)IWe;m0??6Lu68coVlr#SvT%B$yj8rKLr%3S-t;sD)0~H>#mn2_B
XBrH{6xZ_JA|Ha&qP81{}`Dsi*nierV

literal 1296
zcmV+r1@HPoT4*^jL0KkKStVb6-~a+D|NsC0|NsC0`v3p`@Bjbr|Nr;@|Ns8~|3Ck4
z^|k;1_y52G{0C=U#&oe%Q#~d$p_)w^dLYR3hpFW<48=6{GCfa7(9;5Gnx2rv^#P3&
zMobB`nr4$ns2+)v8AhL~W|>BsY}FVVnh#S=3<T3gWSV*=O+8N(Isgp-82}mp4FCWE
zpay^d01W^D000Jn0000000E!?28MtD8WBj<Jx@{Uct#30sL2>@Q}s-rs%Z5xHm9kY
zhJzE-FluB0wE>z&j7))srcWuR)X>2_Oh6hM8hJEL834e5G#C(IK-xV)rlci3Pf6(0
zQ`7@Y36YRA4F-TcLm}!tO$`750Lb+;XfkP_dVmIjrhotd15E%l28MtD05mkvP+CY~
zaHLZUEjsa@>H(`D147a84A@E4{gfFT3zw{b4jcyy0;a9(8A~KqYC8Xo=TtAH_<)dg
zg(4(=4MGMPK@bBcDOQ=#KxyWt_OE~k@`w-#LJ0r{=Jy7w@c~693LsHLLP-RqAqXPt
zYD5VOl^_tIOsK^9IjkUD12#}b8ZrYnR`2rR-14~&1$-?_RiFT{CZ4+GWGJnpW#<@;
zwP#zhL5?izs@Rv(i1*^rWOqtHq!L9TsMLZ#N}$=#*>A>q<5>z8Ktqa2?arZ!<E3B>
zN1KB_y5$5o>nI6w7cXNVsnHt-R8lx4kO;D!q674V49jOTP|W=GL$N7Q<t2bUbdYQq
zsrs1^2*Y@tOxymVHE?~XNaT;5&0wS_jPPuEhOYRF!Vwq0wznlImpD?Wmpxr06%n!(
z6xH#u`}sv*JCO704p6*h8zqwr+JaQs#dZVjPjenhJ8IXg(!`y^odIwRg3xQv4O^@n
z2Pxp#pm0J#9U6QeI<#F})kc1d_7I@Hqyn!k3`ga(aOesIC;`;uNQ)Ntl{4^yugZb4
zjS($&)hjdrtxv3WJW!@Y-V_VeUn=3p`tdlpzX({Gycw;PB1)=$OX*OsiwG5tI^{dt
z@k_@Kz0RhV`k*lv8>^i8y1dXrKl49x{peo@t~%otE(DnpGE^gN6GWt#y1RJ=xJS@&
z86b~BSrihFTA%A??#6%w&_SV!MCJl}d;m15{DM)2mRprMyXPxIRL<diU<tm(^e!O$
z0yjr1m*WOmBt%JP1hGTk5@(QHGC(TDC|TkocWHLsOA9C$pdrxAmOM`Ztsl#TstN}#
z3ABa<5rZRwf#(F{9}I}DsEhVf&kh8dApi(zW6MNfFhXpYGbuzHR4xPcM}RZ&4&(q6
zYUz3-YlmD0%E>o^1Oq`ojE-^~A^6QYoW8~57OaT4jrOLZ%Q=|MBx&*^iocP!e*vmS
z=AP*l<e1`+$SmE_SfO0k@G9vdf|6-=U65JD=0gAg$yfuyDBuZ3SHKmPYb1h4W7qNO
zX8SZ$r7@sBoH}rjuFfo5J|vJW<ip|=Q?Z{h#;oNLJNGk}h8V8#a+yM4d5e(GvO<4M
zW5DU!?D=y#<)f{V@Kd8{BSM;uVvCW-%~Y^8)9(Lboqo%rtZ(+3-g7B6qOcW8g5TyT
z_H5Gbj+vE&vRMt@f5o`ZlK1$+E<TM^H`CzJq16O+0Y=~+vOOm*2#JgwI|!X(USTRU
zGUG-0c{r6hq1mmczkFA{qH|vMQmq!RKdd+|yrW}&QSMl*J9Okh<rrd>jxOYiaG@Yd
GzWcyBflLkn

diff --git a/tests/testfile-ranges-world5.dwo.bz2 b/tests/testfile-ranges-world5.dwo.bz2
index 1ee3b6ac5adc43e475a512e545736ea50e61c1c4..6bde196b34dc92ec7224acfd75d046019609848b 100644
GIT binary patch
literal 1514
zcmV<G1r_>2T4*^jL0KkKS?!*8l>h=r|NsC0|NsC0|NsAg|NsC0|NZ>`@Bjbq{{R2~
z|Nq<n|NqbfUIO=fwz;@CGEF8X$)sVXjV7O}3;{ItFq<P$=$?}%nlcPbnW^aql5I>(
z0WeJ&si4zLjF|_i>KZaV6Himn6ExFF>Ux;T10&OF4MRtvk_V~nQx!?1%_r)bdO_*x
z8lI-q(`p+D8es#}+9uI5ZAYkSngrUOr=-TFPbhkr(mahcModEhX*9twnrO^`Mrkr)
zG{A!=q|?-B8fl53dY*!!O&Vw!Hl)Ur(3?#JX{MSUjZ6&yG@hm!nmsi#VrVj8A%KjS
z8VQY0K$>D`z$PP1hE1RdF$M(DkieQ?m<i}rH5f*T<YXF6JqCaP1i>(9011hafB*=<
znrV@M01<$gCIA2lfC++N34jpMgkVenX{4r;Q`BjZ<uo+VWN6T600SdHG|*@RMt}eh
zQIG%!r~^P60000005kyg000JtfB*#rWQLk)fr?ni+7}xbNB1wt15+?EAsNd*DNBrY
zVW0!2OE(2o)BLs`A~vazzex39qznN8C-g-`NIRm4NL2v<G*zWkVxueVM@P^kE_=q{
z2Sfx2FhvOfJ1!wsm_SmP;)oQYAtZuQ7=#qL(trSlct9aQniQ3TT70sw40??D0sAK?
z!0f=pg6GuP#A|x6bWk)2cHN@HD7%Oj+{t}}1DThiNx}>1bB1`p;G{tqQZHHsNcwUG
zK_p}!EKkA-h$YH1<0i=)Y{SOYvX-~d_bG;h*;R?+s+17oGAW22mW-TUdl_|l+*YJ<
zF>}^{78;tMihQO%^2jGUo%Cp`<_p#V0iDt|0X883Q5|&qreaJCAY)TRXi1MYfXJRC
z+Hw%2q=K6uBTvps0K241EKwgVugda(n-7UmojTaH^WY`>GgV$($W}hMjRWtug9P(~
zTL5a~N3|~R>KJhiAzaj4zgmSClMy#(zD*Sl#w8@X!`5j(kYz4|pl@D#wte}Rjm-d{
z1cQK9<Ue94JdnMUt_ab#<4aRInZ7AW<`*zRN7C2aBxI2iHfb1!vlzKC-y`$>GAUIS
zPYO#7rMH7J!U99X7+!^$8wT;hQyFlM68cU!iHb_C#jVv#DD2UXtVy+QnlH3?hLa(a
zD;&_NKKyrJ(I1G`#?m776<K0*9pgs@2j@B}Ps0+%mC~>=$)v<W%VS;xWzZqzC!bdq
zKSl_t=BuN|dOcx<9QZ1x%mx$)U@mj;veLDuSBepnt)Kv#W8e@SCq|7;hzYebV#e9I
zCs=+um@2Ro761s#-wi?m3HB)l5*dqhE>LY#v_8l{3^9;k(xcF+CZ31?2HT-Z2m%>l
zz*?7unnTS|eX6U>LclnlxC1Q|nipz_0UG%-X*@!{WPo&Tq(A|{I3rG>MIanKAWcDt
z1_wDHP}dB01fgq#fDqlcpW$L;KoEmGe10)t1X$<X!|>n${5YWvbo&49Bm$w`i3cI%
z1ONj$=PHQ-%xc4}rn<ving6yb1v_fk;nc?%zePOH;Qc5FT!6q=K4ts?yC_WdL%%M7
zFu1K#LS2@tB=ViUv&qr<<=`elX+e92%y0mzYNGlhZhKsgGp|i(`j-Qt`Gcnpj2bm%
zWKx_SuU`e*D$CMqZlxx$Dwb`Z)&}gyzWedFq>99*`y{XTau>IbYjqp7$zGFS&}e~u
z?*Bm!I^DI=n_7?C%OS=6S%KCzOvO0SDu46BkO765qhsa0fT(lutn7yQO8lwUbU_pF
zM~#tW1WE9_|L(xPX)M6kIRbvjyicZVWH~=EWF-}ki!7;c(Bz@Ah}d;0bK;*BPt1hQ
zw7J$L6?p5T7WAf2A~VMq$s~_dOr+^JV-+mqC8<H}eMo@=l=I{fTBK-IoDUAX@PGOu
zH63h))?&G=&L9Y~E(vsjJ?ReYiH25XPr7{<Pjenig?JeGhV0sqw!~D^kN&2uwm9mL
QQEf4IBvXY64%z2<P>iLsp8x;=

literal 1466
zcmV;r1x5NoT4*^jL0KkKS>RD1s{jH?fB*mg|M~a-|KI=r|KGp=zyJUL-~HG2_kaKY
z|Nj5~|NYPdUIVq;UN#P~!k(e!Jx@gSJwfU{Pe>VxJdk>g9+1iDJtwKAo~M-4Pauy`
zqd}&JspSmPH1t6A8&erg9;VY%)I6g@!i_ya`jcu6rj1WX^i4dY#Sc@{Nc5koXwx!?
z00000G|&J6pa2aT0077Vpc()G001-q88iSi000dD000000Z~Du^h^<iz|k?J+5s~{
zFab82G-Ln(22Cae(+xCC044;$j7DezU<6`d0MH4hm<fOg$VDV+q`{$(GzowKpqOYA
z0GeW800E>h0T=-o08d28fC#_<000T5n3*)uff{J^&;SiIkw&MfwHiG^rk<em(gV^1
zN2nSAXaE3Y27mw$NE!eEpa2Gd00000dVm8!05kvv1c42<+XED_n!d!t$1a@1pbVRV
zED@ZuH7_S)&9(q`?Pp-ByLHUPQe<FcFVbCE^~lah2}GnSB1PTQJbIxJ2iS-**^KPI
zlT)vl+w<K3Cxiq*AdpG`C#FgA$B-1JSfT|eh)E!njUfblTA~Dvl^_tY2UzhyAQYe!
zK-OnO!46^r@e9<`iz{zLNkG^pbqv{J6kX5qC5^>HdF5I`gE-e1wg*Kd$QS)GqzZBc
zK?K4-KXQOCOqzn!bjrvSjHtq*%(f*pOOd8onM)`m0k9N~GKI5=fscI9sl`p4Gyr}^
zxYo!VNgB7)JodEzzs_?w9MEBQ`?chTn}h-c7DT7V-xSJzK71nNIJEv?p>PVg4%@jD
zigZS%ks~GfE~FTJ^s*f#QaalL$cL7EM9c=S2Fz8E(PIdWx3;R9y<#0ezeHJ;KFA9%
zDV6Ts0J{I$lCIW7rk8mc^03Yv@We|J&*Ctxas|Kzf>mSe9pShtoSfws1S8;yw;)tz
z$OS0jc*7WG=K^GnG;Iz%|KKPKRcIkHK!hFdic<$6ghxm^>Hx1ukv!j4l#4V>A9zkT
zIF<!wED&p24hI1_sAg5w!Vc0P#k!NI>XAHN0G`W*NxY4^Yc8+ISc=0gPXc11S$Lw8
zg2As*r@^QBIDnRNH$d>o$|_I!owp6ReG=%Chw)#p0@N8{+eRV>-`bt5zA|=)QR=pg
zc{l;tSMDEvyb2595h*x!o*-bU!vsMmc>pW@{YMH=DNT5BnNvU{*6!|bd58OyQ*40{
z!~jeGu_L)a67+#VzJg>*j(;^f9Dy)fOa%M;2OR2hJ-}U_jY$+*0GuArf;9~FJ*1eh
zQ5#Sx@_?ZPY{p;Bi;<8LSOE<OpbeWa2wTJ&iRpzTa7;rYd;-KF*f6{fM=cD&Is>78
z6XNfp3MefZsvCfYMM(Nj01^1X0~A;nfD%*9cL4FGSkHh6F(uG#yENlpYoA9;V;La@
z94h&J5gh~o57uokj0fnA6Q_Tj72|+@S4bU9eaPe1NNG8dvCrEhy%$C^k6{X=@gN^(
zg$T(-IWppg3DHPy(Cofy@P7&_X-W?mVmJ!$X^lDUFo-UKNG%X-6|VfVV1j9W`P_8(
zSJsNqT8>Fv(|Pg`6J}t_i3a3t!+HlH2d(eu-54v07#Ys9dW3BKr6`9yDxHYTCL0OU
zd0&sE0MN-_RZ0P9TOo)^4JyfEn6GjBMqckVor#8@)kXWc`t1mYbJyI6V}81H5)%g5
z{E#E@E}BaBR}U=YszdXl&M}t5KN37|I_|oVchD42w);5IY}p(U&Y*xcAH*nda<v(N
z9(_#4QAy%~{HmIE=`Rd~lhui28OX%AEwHPBV}c!kjYl;IO+5SA7_##1d^;8Ek|dk8
za4ei{U=m$^UAw6^)>lExnpO}s!&*0ehRzh$o+PgRrPAo#a7tu41#dS5SD;>B2{)am
Ui?rcoB0u8pNT&)C910{AU^N7V=>Px#

diff --git a/tests/testfilesplitranges5.debug.bz2 b/tests/testfilesplitranges5.debug.bz2
index 7e43492f80d7aa930da386a9edd7efbffee5436c..838a2fabd5af4a45531069ace327d121b3ad6dcf 100755
GIT binary patch
literal 2246
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
UR#Bt>IDf_5kxmpOEL0XF0I1maz5oCK

literal 2235
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
J5(aqcw?Lj>;Vb|E

diff --git a/tests/varlocs.c b/tests/varlocs.c
index 859068d..31a1069 100644
--- a/tests/varlocs.c
+++ b/tests/varlocs.c
@@ -1,5 +1,5 @@
 /* Test program for dwarf location functions.
-   Copyright (C) 2013, 2015, 2017 Red Hat, Inc.
+   Copyright (C) 2013, 2015, 2017, 2018 Red Hat, Inc.
    This file is part of elfutils.
 
    This file is free software; you can redistribute it and/or modify
@@ -44,6 +44,7 @@ Dwarf_CFI *cfi_eh;
 Dwarf_Addr cfi_eh_bias;
 
 bool is_ET_REL;
+bool is_debug;
 
 // Whether the current function has a DW_AT_frame_base defined.
 // Needed for DW_OP_fbreg.
@@ -257,7 +258,7 @@ print_expr (Dwarf_Attribute *attr, Dwarf_Op *expr, Dwarf_Addr addr)
 	error (EXIT_FAILURE, 0, "%s used in CFI", opname);
 
       printf ("%s ", opname);
-      if (cfi_eh == NULL && cfi_debug == NULL)
+      if (cfi_eh == NULL && cfi_debug == NULL && !is_debug)
 	error (EXIT_FAILURE, 0, "DW_OP_call_frame_cfa used but no cfi found.");
 
       Dwarf_Frame *frame;
@@ -275,11 +276,11 @@ print_expr (Dwarf_Attribute *attr, Dwarf_Op *expr, Dwarf_Addr addr)
 	  print_expr_block (NULL, cfa_ops, cfa_nops, 0);
 	  free (frame);
 	}
-      else if (is_ET_REL)
+      else if (is_ET_REL || is_debug)
 	{
 	  /* XXX In ET_REL files there might be an .eh_frame with relocations
 	     we don't handle (e.g. X86_64_PC32). Maybe we should?  */
-	  printf ("{...}\n");
+	  printf ("{...}");
 	}
       else
 	error (EXIT_FAILURE, 0, "dwarf_cfi_addrframe 0x%" PRIx64 ": %s",
@@ -1033,12 +1034,34 @@ main (int argc, char *argv[])
      which contains an DWARF expression (but not location lists) and
      print those.  Otherwise we process all function DIEs and print
      all DWARF expressions and location lists associated with
-     parameters and variables). */
+     parameters and variables). It must be the first argument,
+     or the second, after --debug.  */
   bool exprlocs = false;
-  if (argc > 1 && strcmp ("--exprlocs", argv[1]) == 0)
+
+  /* With --debug we ignore not being able to find .eh_frame.
+     It must come as first argument.  */
+  is_debug = false;
+  if (argc > 1)
+    {
+      if (strcmp ("--exprlocs", argv[1]) == 0)
+	{
+	  exprlocs = true;
+	  argv[1] = "";
+	}
+      else if (strcmp ("--debug", argv[1]) == 0)
+	{
+	  is_debug = true;
+	  argv[1] = "";
+	}
+    }
+
+  if (argc > 2)
     {
-      exprlocs = true;
-      argv[1] = "";
+      if (strcmp ("--exprlocs", argv[2]) == 0)
+	{
+	  exprlocs = true;
+	  argv[2] = "";
+	}
     }
 
   int remaining;
-- 
1.8.3.1


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