From: Mark Wielaard Date: Fri, 6 Apr 2018 16:53:34 +0000 (+0200) Subject: libdw: Handle .debug_rnglists in dwarf_ranges. X-Git-Tag: elfutils-0.171~19 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=879f3a4f99df;p=thirdparty%2Felfutils.git libdw: Handle .debug_rnglists in dwarf_ranges. 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 --- diff --git a/libdw/ChangeLog b/libdw/ChangeLog index b2fc3d9ea..fef78eeaa 100644 --- a/libdw/ChangeLog +++ b/libdw/ChangeLog @@ -1,3 +1,18 @@ +2018-04-06 Mark Wielaard + + * 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 * dwarf.h: Add DWARF5 range list entry DW_RLE encodings. diff --git a/libdw/dwarf_formaddr.c b/libdw/dwarf_formaddr.c index 3c89a5d21..9cd3d2009 100644 --- a/libdw/dwarf_formaddr.c +++ b/libdw/dwarf_formaddr.c @@ -34,6 +34,48 @@ #include "libdwP.h" +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) { @@ -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) diff --git a/libdw/dwarf_getlocation.c b/libdw/dwarf_getlocation.c index ade3e6c54..0e7115f83 100644 --- a/libdw/dwarf_getlocation.c +++ b/libdw/dwarf_getlocation.c @@ -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)) diff --git a/libdw/dwarf_ranges.c b/libdw/dwarf_ranges.c index 52a61eea7..fa65e5c6d 100644 --- a/libdw/dwarf_ranges.c +++ b/libdw/dwarf_ranges.c @@ -40,62 +40,244 @@ - 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)) diff --git a/libdw/libdwP.h b/libdw/libdwP.h index 3cfcc557e..c419e37ad 100644 --- a/libdw/libdwP.h +++ b/libdw/libdwP.h @@ -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); diff --git a/src/ChangeLog b/src/ChangeLog index d28d89af6..4772448c3 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -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. diff --git a/src/readelf.c b/src/readelf.c index ce0ecc242..e7a9605cc 100644 --- a/src/readelf.c +++ b/src/readelf.c @@ -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) diff --git a/tests/ChangeLog b/tests/ChangeLog index 13d168dee..5eb1e77f9 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,15 @@ +2018-04-06 Mark Wielaard + + * 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 * run-readelf-ranges.sh: New test. diff --git a/tests/Makefile.am b/tests/Makefile.am index 54a3d1d5e..63f077c4f 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -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 \ diff --git a/tests/run-all-dwarf-ranges.sh b/tests/run-all-dwarf-ranges.sh index ad5e634fb..cefb42313 100755 --- a/tests/run-all-dwarf-ranges.sh +++ b/tests/run-all-dwarf-ranges.sh @@ -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 diff --git a/tests/run-dwarf-ranges.sh b/tests/run-dwarf-ranges.sh index f935eaf44..ae25d6efd 100755 --- a/tests/run-dwarf-ranges.sh +++ b/tests/run-dwarf-ranges.sh @@ -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 index 000000000..5e6e9e21b 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 index 000000000..6bde196b3 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 index 000000000..ef28efc1a 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 index 000000000..5796cbf03 Binary files /dev/null and b/tests/testfilesplitranges5.debug.bz2 differ