libdw: Handle .debug_rnglists in dwarf_ranges.
authorMark Wielaard <mark@klomp.org>
Fri, 6 Apr 2018 16:53:34 +0000 (18:53 +0200)
committerMark Wielaard <mark@klomp.org>
Mon, 28 May 2018 12:51:26 +0000 (14:51 +0200)
Handle all new DW_RLE opcodes in .debug_rnglists in dwarf_ranges. Extract
code for reading .debug_addr indexes from dwarf_formaddr as __libdw_addrx
to reuse in __libdw_read_begin_end_pair_inc. And add new testcase for
"plain" DWARF5 and add a new test all-dwarf-ranges to test split DWARF5.

Signed-off-by: Mark Wielaard <mark@klomp.org>
15 files changed:
libdw/ChangeLog
libdw/dwarf_formaddr.c
libdw/dwarf_getlocation.c
libdw/dwarf_ranges.c
libdw/libdwP.h
src/ChangeLog
src/readelf.c
tests/ChangeLog
tests/Makefile.am
tests/run-all-dwarf-ranges.sh
tests/run-dwarf-ranges.sh
tests/testfile-ranges-hello5.dwo.bz2 [new file with mode: 0644]
tests/testfile-ranges-world5.dwo.bz2 [new file with mode: 0644]
tests/testfileranges5.debug.bz2 [new file with mode: 0755]
tests/testfilesplitranges5.debug.bz2 [new file with mode: 0755]

index b2fc3d9..fef78ee 100644 (file)
@@ -1,3 +1,18 @@
+2018-04-06  Mark Wielaard  <mark@klomp.org>
+
+       * dwarf_formaddr.c (__libdw_addrx): New function, extracted from...
+       (dwarf_formaddr): here. Use __libdw_addrx.
+       * dwarf_getlocation.c (getlocations_addr): Pass cu to
+       __libdw_read_begin_end_pair_inc.
+       * dwarf_ranges.c (__libdw_read_begin_end_pair_inc): Take cu as
+       argument. Handle .debug_rnglists.
+       (initial_offset): Handle .debug_rnglists and DW_FORM_rnglistx.
+       (dwarf_ranges): Likewise. Check cu isn't NULL before use. Pass cu to
+       __libdw_read_begin_end_pair_inc.
+       * libdwP.h (__libdw_read_begin_end_pair_inc): Take cu as argument.
+       (__libdw_cu_ranges_base): Handle DW_AT_rnglists_base.
+       (__libdw_addrx): New function definition.
+
 2018-04-11  Mark Wielaard  <mark@klomp.org>
 
        * dwarf.h: Add DWARF5 range list entry DW_RLE encodings.
index 3c89a5d..9cd3d20 100644 (file)
 
 
 int
+__libdw_addrx (Dwarf_CU *cu, Dwarf_Word idx, Dwarf_Addr *addr)
+{
+  Dwarf_Off addr_off = __libdw_cu_addr_base (cu);
+  if (addr_off == (Dwarf_Off) -1)
+    return -1;
+
+  Dwarf *dbg = cu->dbg;
+  if (dbg->sectiondata[IDX_debug_addr] == NULL)
+    {
+      __libdw_seterrno (DWARF_E_NO_DEBUG_ADDR);
+      return -1;
+    }
+
+  /* The section should at least contain room for one address.  */
+  int address_size = cu->address_size;
+  if (cu->address_size > dbg->sectiondata[IDX_debug_addr]->d_size)
+    {
+    invalid_offset:
+      __libdw_seterrno (DWARF_E_INVALID_OFFSET);
+      return -1;
+    }
+
+  if (addr_off > (dbg->sectiondata[IDX_debug_addr]->d_size
+                 - address_size))
+    goto invalid_offset;
+
+  idx *= address_size;
+  if (idx > (dbg->sectiondata[IDX_debug_addr]->d_size
+            - address_size - addr_off))
+    goto invalid_offset;
+
+  const unsigned char *datap;
+  datap = dbg->sectiondata[IDX_debug_addr]->d_buf + addr_off + idx;
+  if (address_size == 4)
+    *addr = read_4ubyte_unaligned (dbg, datap);
+  else
+    *addr = read_8ubyte_unaligned (dbg, datap);
+
+  return 0;
+}
+
+int
 dwarf_formaddr (Dwarf_Attribute *attr, Dwarf_Addr *return_addr)
 {
   if (attr == NULL)
@@ -98,41 +140,9 @@ dwarf_formaddr (Dwarf_Attribute *attr, Dwarf_Addr *return_addr)
 
   /* So we got an index.  Lets see if it is valid and we can get the actual
      address.  */
-
-  Dwarf_Off addr_off = __libdw_cu_addr_base (cu);
-  if (addr_off == (Dwarf_Off) -1)
+  if (__libdw_addrx (cu, idx, return_addr) != 0)
     return -1;
 
-  if (dbg->sectiondata[IDX_debug_addr] == NULL)
-    {
-      __libdw_seterrno (DWARF_E_NO_DEBUG_ADDR);
-      return -1;
-    }
-
-  /* The section should at least contain room for one address.  */
-  int address_size = cu->address_size;
-  if (cu->address_size > dbg->sectiondata[IDX_debug_addr]->d_size)
-    {
-    invalid_offset:
-      __libdw_seterrno (DWARF_E_INVALID_OFFSET);
-      return -1;
-    }
-
-  if (addr_off > (dbg->sectiondata[IDX_debug_addr]->d_size
-                 - address_size))
-    goto invalid_offset;
-
-  idx *= address_size;
-  if (idx > (dbg->sectiondata[IDX_debug_addr]->d_size
-            - address_size - addr_off))
-    goto invalid_offset;
-
-  datap = dbg->sectiondata[IDX_debug_addr]->d_buf + addr_off + idx;
-  if (address_size == 4)
-    *return_addr = read_4ubyte_unaligned (dbg, datap);
-  else
-    *return_addr = read_8ubyte_unaligned (dbg, datap);
-
   return 0;
 }
 INTDEF(dwarf_formaddr)
index ade3e6c..0e7115f 100644 (file)
@@ -724,7 +724,7 @@ getlocations_addr (Dwarf_Attribute *attr, ptrdiff_t offset,
   Dwarf_Addr end;
 
  next:
-  switch (__libdw_read_begin_end_pair_inc (dbg, secidx,
+  switch (__libdw_read_begin_end_pair_inc (cu, secidx,
                                           &readp, readendp,
                                           cu->address_size,
                                           &begin, &end, basep))
index 52a61ee..fa65e5c 100644 (file)
     - If it's end of rangelist, don't set anything and return 2
     - If an error occurs, don't set anything and return -1.  */
 internal_function int
-__libdw_read_begin_end_pair_inc (Dwarf *dbg, int sec_index,
+__libdw_read_begin_end_pair_inc (Dwarf_CU *cu, int sec_index,
                                 const unsigned char **addrp,
                                 const unsigned char *addrend,
                                 int width,
                                 Dwarf_Addr *beginp, Dwarf_Addr *endp,
                                 Dwarf_Addr *basep)
 {
-  Dwarf_Addr escape = (width == 8 ? (Elf64_Addr) -1
-                      : (Elf64_Addr) (Elf32_Addr) -1);
-  Dwarf_Addr begin;
-  Dwarf_Addr end;
-
-  const unsigned char *addr = *addrp;
-  if (addrend - addr < width * 2)
+  Dwarf *dbg = cu->dbg;
+  if (sec_index == IDX_debug_ranges || sec_index == IDX_debug_loc)
     {
-    invalid:
-      __libdw_seterrno (DWARF_E_INVALID_DWARF);
-      return -1;
-    }
+      Dwarf_Addr escape = (width == 8 ? (Elf64_Addr) -1
+                          : (Elf64_Addr) (Elf32_Addr) -1);
+      Dwarf_Addr begin;
+      Dwarf_Addr end;
 
-  bool begin_relocated = READ_AND_RELOCATE (__libdw_relocate_address, begin);
-  bool end_relocated = READ_AND_RELOCATE (__libdw_relocate_address, end);
-  *addrp = addr;
+      const unsigned char *addr = *addrp;
+      if (addrend - addr < width * 2)
+       {
+       invalid:
+         __libdw_seterrno (DWARF_E_INVALID_DWARF);
+         return -1;
+       }
 
-  /* Unrelocated escape for begin means base address selection.  */
-  if (begin == escape && !begin_relocated)
-    {
-      if (unlikely (end == escape))
-       goto invalid;
+      bool begin_relocated = READ_AND_RELOCATE (__libdw_relocate_address,
+                                               begin);
+      bool end_relocated = READ_AND_RELOCATE (__libdw_relocate_address,
+                                             end);
+      *addrp = addr;
 
-      *basep = end;
-      return 1;
-    }
+      /* Unrelocated escape for begin means base address selection.  */
+      if (begin == escape && !begin_relocated)
+       {
+         if (unlikely (end == escape))
+           goto invalid;
+
+         *basep = end;
+         return 1;
+       }
 
-  /* Unrelocated pair of zeroes means end of range list.  */
-  if (begin == 0 && end == 0 && !begin_relocated && !end_relocated)
-    return 2;
+      /* Unrelocated pair of zeroes means end of range list.  */
+      if (begin == 0 && end == 0 && !begin_relocated && !end_relocated)
+       return 2;
 
-  /* Don't check for begin_relocated == end_relocated.  Serve the data
-     to the client even though it may be buggy.  */
-  *beginp = begin + *basep;
-  *endp = end + *basep;
+      /* Don't check for begin_relocated == end_relocated.  Serve the data
+        to the client even though it may be buggy.  */
+      *beginp = begin + *basep;
+      *endp = end + *basep;
 
-  return 0;
+      return 0;
+    }
+  else if (sec_index == IDX_debug_rnglists)
+    {
+      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_RLE_end_of_list:
+         *addrp = addr;
+         return 2;
+
+       case DW_RLE_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_RLE_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_RLE_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_RLE_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_RLE_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_RLE_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_RLE_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);
+      return -1;
+    }
 }
 
 static int
 initial_offset (Dwarf_Attribute *attr, ptrdiff_t *offset)
 {
-  size_t secidx = IDX_debug_ranges;
+  size_t secidx = (attr->cu->version < 5
+                  ? IDX_debug_ranges : IDX_debug_rnglists);
 
   Dwarf_Word start_offset;
-  if (__libdw_formptr (attr, secidx,
-                      DWARF_E_NO_DEBUG_RANGES,
-                      NULL, &start_offset) == NULL)
-    return -1;
+  if (attr->form == DW_FORM_rnglistx)
+    {
+      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_ranges
+                            ? DWARF_E_NO_DEBUG_RANGES
+                            : DWARF_E_NO_DEBUG_RNGLISTS);
+         return -1;
+       }
+
+      Dwarf_Off range_base_off = __libdw_cu_ranges_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 (range_base_off > (sec_size - offset_size))
+       goto invalid_offset;
+
+      size_t max_idx = (sec_size - offset_size - range_base_off) / offset_size;
+      if (idx > max_idx)
+       goto invalid_offset;
+
+      datap = (cu->dbg->sectiondata[secidx]->d_buf
+              + range_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 += range_base_off;
+    }
+  else
+    {
+      if (__libdw_formptr (attr, secidx,
+                          (secidx == IDX_debug_ranges
+                           ? DWARF_E_NO_DEBUG_RANGES
+                           : DWARF_E_NO_DEBUG_RNGLISTS),
+                          NULL, &start_offset) == NULL)
+       return -1;
+    }
 
   *offset = start_offset;
   return 0;
@@ -121,7 +303,6 @@ dwarf_ranges (Dwarf_Die *die, ptrdiff_t offset, Dwarf_Addr *basep,
     return 0;
 
   /* We have to look for a noncontiguous range.  */
-  size_t secidx = IDX_debug_ranges;
   Dwarf_CU *cu = die->cu;
   if (cu == NULL)
     {
@@ -129,6 +310,7 @@ dwarf_ranges (Dwarf_Die *die, ptrdiff_t offset, Dwarf_Addr *basep,
       return -1;
     }
 
+  size_t secidx = (cu->version < 5 ? IDX_debug_ranges : IDX_debug_rnglists);
   const Elf_Data *d = cu->dbg->sectiondata[secidx];
   if (d == NULL && cu->unit_type == DW_UT_split_compile)
     {
@@ -176,7 +358,7 @@ dwarf_ranges (Dwarf_Die *die, ptrdiff_t offset, Dwarf_Addr *basep,
   Dwarf_Addr end;
 
  next:
-  switch (__libdw_read_begin_end_pair_inc (cu->dbg, secidx,
+  switch (__libdw_read_begin_end_pair_inc (cu, secidx,
                                           &readp, readendp,
                                           cu->address_size,
                                           &begin, &end, basep))
index 3cfcc55..c419e37 100644 (file)
@@ -915,7 +915,7 @@ is_cudie (Dwarf_Die *cudie)
     - 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 <0.  */
-int __libdw_read_begin_end_pair_inc (Dwarf *dbg, int sec_index,
+int __libdw_read_begin_end_pair_inc (Dwarf_CU *cu, int sec_index,
                                     const unsigned char **readp,
                                     const unsigned char *readend,
                                     int width,
@@ -1084,6 +1084,8 @@ static inline Dwarf_Off __libdw_cu_str_off_base (Dwarf_CU *cu)
 }
 
 
+/* Either a direct offset into .debug_ranges for version < 5, or the
+   start of the offset table in .debug_rnglists for version > 5.  */
 static inline Dwarf_Off
 __libdw_cu_ranges_base (Dwarf_CU *cu)
 {
@@ -1092,12 +1094,79 @@ __libdw_cu_ranges_base (Dwarf_CU *cu)
       Dwarf_Off offset = 0;
       Dwarf_Die cu_die = CUDIE(cu);
       Dwarf_Attribute attr;
-      if (dwarf_attr (&cu_die, DW_AT_GNU_ranges_base, &attr) != NULL)
+      if (cu->version < 5)
        {
-         Dwarf_Word off;
-         if (dwarf_formudata (&attr, &off) == 0)
-           offset = off;
+         if (dwarf_attr (&cu_die, DW_AT_GNU_ranges_base, &attr) != NULL)
+           {
+             Dwarf_Word off;
+             if (dwarf_formudata (&attr, &off) == 0)
+               offset = off;
+           }
+       }
+      else
+       {
+         if (dwarf_attr (&cu_die, DW_AT_rnglists_base, &attr) != NULL)
+           {
+             Dwarf_Word off;
+             if (dwarf_formudata (&attr, &off) == 0)
+               offset = off;
+           }
+
+         /* There wasn't an rnglists_base, if the Dwarf does have a
+            .debug_rnglists section, then it might be we need the
+            base after the first header. */
+         Elf_Data *data = cu->dbg->sectiondata[IDX_debug_rnglists];
+         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->ranges_base = offset;
     }
 
@@ -1105,6 +1174,11 @@ __libdw_cu_ranges_base (Dwarf_CU *cu)
 }
 
 
+/* Given an address index for a CU return the address.
+   Returns -1 and sets libdw_errno if an error occurs.  */
+int __libdw_addrx (Dwarf_CU *cu, Dwarf_Word idx, Dwarf_Addr *addr);
+
+
 /* Helper function to set debugdir field in Dwarf, used from dwarf_begin_elf
    and libdwfl process_file.  */
 char * __libdw_debugdir (int fd);
index d28d89a..4772448 100644 (file)
@@ -6,7 +6,8 @@
        (listptr_cu): New function.
        (print_debug_rnglists_section): Likewise.
        (attr_callback): Call notice_listptr for DW_AT_ranges. Handle
-       DW_AT_rnglists_base.
+       DW_AT_rnglists_base. Handle DW_FORM_rnglistx. DW_AT_start_scope
+       can also have a rnglist.
        (print_debug_units): Do (silently) scan split DWARF also for
        debug_ranges before DWARF5 to catch all rangelistptrs.
        (print_debug): Recognize .debug_rnglists. Reset known_rnglistptr.
index ce0ecc2..e7a9605 100644 (file)
@@ -6699,6 +6699,7 @@ attr_callback (Dwarf_Attribute *attrp, void *arg)
       break;
 
     case DW_FORM_sec_offset:
+    case DW_FORM_rnglistx:
     case DW_FORM_implicit_const:
     case DW_FORM_udata:
     case DW_FORM_sdata:
@@ -6755,6 +6756,7 @@ attr_callback (Dwarf_Attribute *attrp, void *arg)
          return DWARF_CB_OK;
 
        case DW_AT_ranges:
+       case DW_AT_start_scope:
          {
            bool nlpt;
            if (cbargs->cu->version < 5)
index 13d168d..5eb1e77 100644 (file)
@@ -1,3 +1,15 @@
+2018-04-06  Mark Wielaard  <mark@klomp.org>
+
+       * testfileranges5.debug.bz2: New testfile.
+       * testfilesplitranges5.debug.bz2: Likewise.
+       * testfile-ranges-hello5.dwo.bz2: Likewise.
+       * testfile-ranges-world5.dwo.bz2: Likewise.
+       * run-dwarf-ranges.sh: Run on testfileranges5.debug.
+       * run-all-dwarf-ranges.sh: Run on testfilesplitranges5.debug.
+       * tests/Makefile.am (EXTRA_DIST): Add testfileranges5.debug.bz2,
+       testfilesplitranges5.debug.bz2, testfile-ranges-hello5.dwo.bz2 and
+       testfile-ranges-world5.dwo.bz2.
+
 2018-04-11  Mark Wielaard  <mark@klomp.org>
 
        * run-readelf-ranges.sh: New test.
index 54a3d1d..63f077c 100644 (file)
@@ -203,7 +203,9 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh run-ar.sh \
             run-dwfl-addr-sect.sh run-early-offscn.sh \
             run-dwarf-getmacros.sh \
             run-dwarf-ranges.sh debug-ranges-no-lowpc.o.bz2 \
-            testfileranges4.debug.bz2 \
+            testfileranges4.debug.bz2 testfileranges5.debug.bz2 \
+            testfilesplitranges5.debug.bz2 \
+            testfile-ranges-hello5.dwo.bz2 testfile-ranges-world5.dwo.bz2 \
             run-test-flag-nobits.sh \
             run-dwarf-getstring.sh run-rerequest_tag.sh run-alldts.sh \
             testfile15.bz2 testfile15.debug.bz2 \
index ad5e634..cefb423 100755 (executable)
@@ -71,4 +71,59 @@ die: no_subject (2e)
 
 EOF
 
+# Same with -gdwarf-5
+# gcc -c -O2 -o testfile-ranges-hello5.o -gsplit-dwarf -gdwarf-5 hello.c
+# gcc -c -O2 -o testfile-ranges-world5.o -gsplit-dwarf -gdwarf-5 world.c
+# gcc -o testfilesplitranges5 -O2 testfile-ranges-hello5.o testfile-ranges-world5.o
+# eu-strip -f testfilesplitranges5.debug testfilesplitranges5
+
+testfiles testfilesplitranges5.debug
+testfiles testfile-ranges-hello5.dwo testfile-ranges-world5.dwo
+
+testrun_compare ${abs_builddir}/all-dwarf-ranges testfilesplitranges5.debug <<\EOF
+die: hello.c (11)
+ 401150..40117a
+ 401050..401067
+
+die: no_say (2e)
+ 401160..40117a
+
+die: main (2e)
+ 401050..401067
+
+die: subject (1d)
+ 401053..40105f
+
+die: subject (2e)
+ 401150..401160
+
+die: world.c (11)
+ 401180..4011e7
+
+die: no_main (2e)
+ 4011d0..4011e7
+
+die: no_subject (1d)
+ 4011d3..4011df
+
+die: say (2e)
+ 401180..4011c0
+
+die: happy (1d)
+ 40119b..40119b
+ 40119c..4011a6
+ 4011b0..4011b4
+ 4011b5..4011bf
+
+die: sad (1d)
+ 40119b..40119b
+ 40119c..4011a6
+ 4011b4..4011b4
+ 4011b5..4011bf
+
+die: no_subject (2e)
+ 4011c0..4011d0
+
+EOF
+
 exit 0
index f935eaf..ae25d6e 100755 (executable)
@@ -102,4 +102,25 @@ testrun_compare ${abs_builddir}/dwarf-ranges testfileranges4.debug 0x374 <<\EOF
 4005a5..4005ad (base 400540)
 EOF
 
+# Like above, but with -gdwarf-5.
+testfiles testfileranges5.debug
+testrun_compare ${abs_builddir}/dwarf-ranges testfileranges5.debug 0xc <<\EOF
+401150..40117a (base 0)
+401050..401067 (base 0)
+EOF
+
+testrun_compare ${abs_builddir}/dwarf-ranges testfileranges5.debug 0x2ce <<\EOF
+40119b..40119b (base 401180)
+40119c..4011a6 (base 401180)
+4011b0..4011b4 (base 401180)
+4011b5..4011bf (base 401180)
+EOF
+
+testrun_compare ${abs_builddir}/dwarf-ranges testfileranges5.debug 0x2ef <<\EOF
+40119b..40119b (base 401180)
+40119c..4011a6 (base 401180)
+4011b4..4011b4 (base 401180)
+4011b5..4011bf (base 401180)
+EOF
+
 exit 0
diff --git a/tests/testfile-ranges-hello5.dwo.bz2 b/tests/testfile-ranges-hello5.dwo.bz2
new file mode 100644 (file)
index 0000000..5e6e9e2
Binary files /dev/null and b/tests/testfile-ranges-hello5.dwo.bz2 differ
diff --git a/tests/testfile-ranges-world5.dwo.bz2 b/tests/testfile-ranges-world5.dwo.bz2
new file mode 100644 (file)
index 0000000..6bde196
Binary files /dev/null and b/tests/testfile-ranges-world5.dwo.bz2 differ
diff --git a/tests/testfileranges5.debug.bz2 b/tests/testfileranges5.debug.bz2
new file mode 100755 (executable)
index 0000000..ef28efc
Binary files /dev/null and b/tests/testfileranges5.debug.bz2 differ
diff --git a/tests/testfilesplitranges5.debug.bz2 b/tests/testfilesplitranges5.debug.bz2
new file mode 100755 (executable)
index 0000000..5796cbf
Binary files /dev/null and b/tests/testfilesplitranges5.debug.bz2 differ