From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 70420 invoked by alias); 6 Apr 2018 12:27:49 -0000 Mailing-List: contact elfutils-devel-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Post: List-Help: List-Subscribe: Sender: elfutils-devel-owner@sourceware.org Received: (qmail 70406 invoked by uid 89); 6 Apr 2018 12:27:48 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Checked: by ClamAV 0.99.4 on sourceware.org X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,SPF_PASS autolearn=ham version=3.3.2 spammy=xtm, je, gps, amo X-Spam-Status: No, score=-26.9 required=5.0 tests=BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,SPF_PASS autolearn=ham version=3.3.2 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on sourceware.org X-Spam-Level: X-HELO: gnu.wildebeest.org Received: from wildebeest.demon.nl (HELO gnu.wildebeest.org) (212.238.236.112) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 06 Apr 2018 12:27:44 +0000 Received: from tarox.wildebeest.org (tarox.wildebeest.org [172.31.17.39]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by gnu.wildebeest.org (Postfix) with ESMTPSA id D4D7C302AB3A; Fri, 6 Apr 2018 14:27:39 +0200 (CEST) Received: by tarox.wildebeest.org (Postfix, from userid 1000) id 49EAA413CAAC; Fri, 6 Apr 2018 14:27:39 +0200 (CEST) From: Mark Wielaard To: elfutils-devel@sourceware.org Cc: Mark Wielaard Subject: [PATCH] libdw: Restructure address range reading for .debug_loc and .debug_ranges. Date: Fri, 06 Apr 2018 12:27:00 -0000 Message-Id: <1523017653-7103-1-git-send-email-mark@klomp.org> X-Mailer: git-send-email 1.8.3.1 X-Spam-Flag: NO X-IsSubscribed: yes X-SW-Source: 2018-q2/txt/msg00004.txt.bz2 This caches the CU base address, makes error checking slight more relaxed and restructures the code so it will be easier to add different forms of ranges. Adds a new test for the new CU base address code. Signed-off-by: Mark Wielaard --- libdw/ChangeLog | 30 +++++++++ libdw/dwarf_formudata.c | 4 +- libdw/dwarf_getlocation.c | 143 +++++++++++++++++++++------------------- libdw/dwarf_ranges.c | 113 ++++++++++++++----------------- libdw/libdwP.h | 22 +++++-- libdw/libdw_findcu.c | 1 + tests/ChangeLog | 6 ++ tests/Makefile.am | 1 + tests/run-dwarf-ranges.sh | 80 +++++++++++++++++++++- tests/testfileranges4.debug.bz2 | Bin 0 -> 3038 bytes 10 files changed, 261 insertions(+), 139 deletions(-) create mode 100755 tests/testfileranges4.debug.bz2 diff --git a/libdw/ChangeLog b/libdw/ChangeLog index ad62771..276f3a4 100644 --- a/libdw/ChangeLog +++ b/libdw/ChangeLog @@ -1,3 +1,33 @@ +2018-04-03 Mark Wielaard + + * dwarf_formudata.c (__libdw_formptr): Take and return const + unsigned char pointers. + * dwarf_getlocation.c (attr_base_address): Rename to... + (__libdw_cu_base_address): this. Take Dwarf_CU, check and set + base_address. + (initial_offset_base): Renamed to... + (initial_offset): this. Only provide offset. + (getlocations_addr): Move data size check and + address base addition into __libdw_read_begin_end_pair_inc. Use + __libdw_cu_base_address and initial_offset. Drop Elf_Data NULL + check (already done by initial_offset, through __libdw_formptr). + (dwarf_getlocations): Use __libdw_cu_base_address and initial_offset. + Drop Elf_Data NULL check. + * dwarf_ranges.c (__libdw_read_begin_end_pair_inc): Change argument + type of readp to Add readend argument. Check data size. Include base + in begin and end result. + (initial_offset): New static function. + (dwarf_ranges): Don't check Elf_Data being NULL (already done by + initial_offset, through __libdw_formptr). Use __libdw_cu_base_address + and initial_offset. Remove base check and addition (already done by + __libdw_read_begin_end_pair_inc. + * libdwP.h (Dwarf_CU): Add base_address field. + (__libdw_read_begin_end_pair_inc): Change argument type of readp to + const. Add readend argument. + (__libdw_formptr): Take and return const unsigned char pointers. + * libdw_findcu.c (__libdw_intern_next_unit): Initialize Dwarf_CU + base_address. + 2018-04-04 Mark Wielaard * libdw_findcu.c (__libdw_intern_next_unit): Initialize Dwarf_CU diff --git a/libdw/dwarf_formudata.c b/libdw/dwarf_formudata.c index 0aaea24..02c1694 100644 --- a/libdw/dwarf_formudata.c +++ b/libdw/dwarf_formudata.c @@ -34,9 +34,9 @@ #include #include "libdwP.h" -internal_function unsigned char * +internal_function const unsigned char * __libdw_formptr (Dwarf_Attribute *attr, int sec_index, - int err_nodata, unsigned char **endpp, + int err_nodata, const unsigned char **endpp, Dwarf_Off *offsetp) { if (attr == NULL) diff --git a/libdw/dwarf_getlocation.c b/libdw/dwarf_getlocation.c index 0fcf950..f577675 100644 --- a/libdw/dwarf_getlocation.c +++ b/libdw/dwarf_getlocation.c @@ -1,7 +1,6 @@ /* Return location expression list. - Copyright (C) 2000-2010, 2013-2015, 2017 Red Hat, Inc. + Copyright (C) 2000-2010, 2013-2015, 2017, 2018 Red Hat, Inc. This file is part of elfutils. - Written by Ulrich Drepper , 2000. This file is free software; you can redistribute it and/or modify it under the terms of either @@ -659,44 +658,55 @@ dwarf_getlocation (Dwarf_Attribute *attr, Dwarf_Op **llbuf, size_t *listlen) return getlocation (attr->cu, &block, llbuf, listlen, cu_sec_idx (attr->cu)); } -static int -attr_base_address (Dwarf_Attribute *attr, Dwarf_Addr *basep) +Dwarf_Addr +__libdw_cu_base_address (Dwarf_CU *cu) { - /* Fetch the CU's base address. */ - Dwarf_Die cudie = CUDIE (attr->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. */ - Dwarf_Attribute attr_mem; - if (unlikely (INTUSE(dwarf_lowpc) (&cudie, basep) != 0) - && INTUSE(dwarf_formaddr) (INTUSE(dwarf_attr) (&cudie, - DW_AT_entry_pc, - &attr_mem), - basep) != 0) + if (cu->base_address == (Dwarf_Addr) -1) { - if (INTUSE(dwarf_errno) () != 0) - return -1; - - /* The compiler provided no base address when it should - have. Buggy GCC does this when it used absolute - addresses in the location list and no DW_AT_ranges. */ - *basep = 0; + Dwarf_Addr base; + + /* Fetch the CU's base address. */ + Dwarf_Die cudie = CUDIE (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. */ + Dwarf_Attribute attr_mem; + if (INTUSE(dwarf_lowpc) (&cudie, &base) != 0 + && INTUSE(dwarf_formaddr) (INTUSE(dwarf_attr) (&cudie, + DW_AT_entry_pc, + &attr_mem), + &base) != 0) + { + int err = INTUSE(dwarf_errno) (); + if (err != 0) + { + __libdw_seterrno (err); + base = (Dwarf_Addr) -1; + } + else + { + /* The compiler provided no base address when it should + have. Buggy GCC does this when it used absolute + addresses in the location list and no DW_AT_ranges. */ + base = 0; + } + } + cu->base_address = base; } - return 0; + + return cu->base_address; } static int -initial_offset_base (Dwarf_Attribute *attr, ptrdiff_t *offset, - Dwarf_Addr *basep) +initial_offset (Dwarf_Attribute *attr, ptrdiff_t *offset) { - if (attr_base_address (attr, basep) != 0) - return -1; + size_t secidx = IDX_debug_loc; Dwarf_Word start_offset; - if (__libdw_formptr (attr, IDX_debug_loc, + if (__libdw_formptr (attr, secidx, DWARF_E_NO_LOCLIST, NULL, &start_offset) == NULL) return -1; @@ -711,22 +721,19 @@ getlocations_addr (Dwarf_Attribute *attr, ptrdiff_t offset, Dwarf_Addr address, const Elf_Data *locs, Dwarf_Op **expr, size_t *exprlen) { - unsigned char *readp = locs->d_buf + offset; - unsigned char *readendp = locs->d_buf + locs->d_size; - - next: - if (readendp - readp < attr->cu->address_size * 2) - { - invalid: - __libdw_seterrno (DWARF_E_INVALID_DWARF); - return -1; - } + Dwarf_CU *cu = attr->cu; + Dwarf *dbg = cu->dbg; + size_t secidx = IDX_debug_loc; + const unsigned char *readp = locs->d_buf + offset; + const unsigned char *readendp = locs->d_buf + locs->d_size; Dwarf_Addr begin; Dwarf_Addr end; - switch (__libdw_read_begin_end_pair_inc (attr->cu->dbg, IDX_debug_loc, - &readp, attr->cu->address_size, + next: + switch (__libdw_read_begin_end_pair_inc (dbg, secidx, + &readp, readendp, + cu->address_size, &begin, &end, basep)) { case 0: /* got location range. */ @@ -739,25 +746,29 @@ getlocations_addr (Dwarf_Attribute *attr, ptrdiff_t offset, return -1; } - if (readendp - readp < 2) - goto invalid; - /* We have a location expression. */ Dwarf_Block block; - block.length = read_2ubyte_unaligned_inc (attr->cu->dbg, readp); - block.data = readp; + if (readendp - readp < 2) + { + invalid: + __libdw_seterrno (DWARF_E_INVALID_DWARF); + return -1; + } + block.length = read_2ubyte_unaligned_inc (dbg, readp); + block.data = (unsigned char *) readp; if (readendp - readp < (ptrdiff_t) block.length) goto invalid; readp += block.length; - *startp = *basep + begin; - *endp = *basep + end; + /* Note these addresses include any base (if necessary) already. */ + *startp = begin; + *endp = end; /* If address is minus one we want them all, otherwise only matching. */ if (address != (Dwarf_Word) -1 && (address < *startp || address >= *endp)) goto next; - if (getlocation (attr->cu, &block, expr, exprlen, IDX_debug_loc) != 0) + if (getlocation (cu, &block, expr, exprlen, secidx) != 0) return -1; return readp - (unsigned char *) locs->d_buf; @@ -804,19 +815,19 @@ dwarf_getlocation_addr (Dwarf_Attribute *attr, Dwarf_Addr address, size_t got = 0; /* This is a true loclistptr, fetch the initial base address and offset. */ - if (initial_offset_base (attr, &off, &base) != 0) + base = __libdw_cu_base_address (attr->cu); + if (base == (Dwarf_Addr) -1) return -1; - const Elf_Data *d = attr->cu->dbg->sectiondata[IDX_debug_loc]; - if (d == NULL) - { - __libdw_seterrno (DWARF_E_NO_LOCLIST); - return -1; - } + if (initial_offset (attr, &off) != 0) + return -1; + + size_t secidx = IDX_debug_loc; + const Elf_Data *d = attr->cu->dbg->sectiondata[secidx]; while (got < maxlocs && (off = getlocations_addr (attr, off, &base, &start, &end, - address, d, &expr, &expr_len)) > 0) + address, d, &expr, &expr_len)) > 0) { /* This one matches the address. */ if (llbufs != NULL) @@ -884,17 +895,17 @@ dwarf_getlocations (Dwarf_Attribute *attr, ptrdiff_t offset, Dwarf_Addr *basep, /* We must be looking at a true loclistptr, fetch the initial base address and offset. */ - if (initial_offset_base (attr, &offset, basep) != 0) + *basep = __libdw_cu_base_address (attr->cu); + if (*basep == (Dwarf_Addr) -1) return -1; - } - const Elf_Data *d = attr->cu->dbg->sectiondata[IDX_debug_loc]; - if (d == NULL) - { - __libdw_seterrno (DWARF_E_NO_LOCLIST); - return -1; + if (initial_offset (attr, &offset) != 0) + return -1; } + size_t secidx = IDX_debug_loc; + const Elf_Data *d = attr->cu->dbg->sectiondata[secidx]; + return getlocations_addr (attr, offset, basep, startp, endp, (Dwarf_Word) -1, d, expr, exprlen); } diff --git a/libdw/dwarf_ranges.c b/libdw/dwarf_ranges.c index 4b6853d..dbcfa2d 100644 --- a/libdw/dwarf_ranges.c +++ b/libdw/dwarf_ranges.c @@ -1,5 +1,5 @@ /* Enumerate the PC ranges covered by a DIE. - Copyright (C) 2005, 2007, 2009 Red Hat, Inc. + Copyright (C) 2005, 2007, 2009, 2018 Red Hat, Inc. This file is part of elfutils. This file is free software; you can redistribute it and/or modify @@ -41,7 +41,9 @@ - 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, - unsigned char **addrp, int width, + const unsigned char **addrp, + const unsigned char *addrend, + int width, Dwarf_Addr *beginp, Dwarf_Addr *endp, Dwarf_Addr *basep) { @@ -50,7 +52,14 @@ __libdw_read_begin_end_pair_inc (Dwarf *dbg, int sec_index, Dwarf_Addr begin; Dwarf_Addr end; - unsigned char *addr = *addrp; + const unsigned char *addr = *addrp; + if (addrend - addr < width * 2) + { + invalid: + __libdw_seterrno (DWARF_E_INVALID_DWARF); + return -1; + } + bool begin_relocated = READ_AND_RELOCATE (__libdw_relocate_address, begin); bool end_relocated = READ_AND_RELOCATE (__libdw_relocate_address, end); *addrp = addr; @@ -59,13 +68,9 @@ __libdw_read_begin_end_pair_inc (Dwarf *dbg, int sec_index, if (begin == escape && !begin_relocated) { if (unlikely (end == escape)) - { - __libdw_seterrno (DWARF_E_INVALID_DWARF); - return -1; - } + goto invalid; - if (basep != NULL) - *basep = end; + *basep = end; return 1; } @@ -75,12 +80,27 @@ __libdw_read_begin_end_pair_inc (Dwarf *dbg, int sec_index, /* Don't check for begin_relocated == end_relocated. Serve the data to the client even though it may be buggy. */ - *beginp = begin; - *endp = end; + *beginp = begin + *basep; + *endp = end + *basep; return 0; } +static int +initial_offset (Dwarf_Attribute *attr, ptrdiff_t *offset) +{ + size_t secidx = IDX_debug_ranges; + + Dwarf_Word start_offset; + if (__libdw_formptr (attr, secidx, + DWARF_E_NO_DEBUG_RANGES, + NULL, &start_offset) == NULL) + return -1; + + *offset = start_offset; + return 0; +} + ptrdiff_t dwarf_ranges (Dwarf_Die *die, ptrdiff_t offset, Dwarf_Addr *basep, Dwarf_Addr *startp, Dwarf_Addr *endp) @@ -101,16 +121,11 @@ 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; + const Elf_Data *d = die->cu->dbg->sectiondata[secidx]; - const Elf_Data *d = die->cu->dbg->sectiondata[IDX_debug_ranges]; - if (d == NULL && offset != 0) - { - __libdw_seterrno (DWARF_E_NO_DEBUG_RANGES); - return -1; - } - - unsigned char *readp; - unsigned char *readendp; + const unsigned char *readp; + const unsigned char *readendp; if (offset == 0) { Dwarf_Attribute attr_mem; @@ -120,49 +135,30 @@ dwarf_ranges (Dwarf_Die *die, ptrdiff_t offset, Dwarf_Addr *basep, /* No PC attributes in this DIE at all, so an empty range list. */ return 0; - Dwarf_Word start_offset; - if ((readp = __libdw_formptr (attr, IDX_debug_ranges, - DWARF_E_NO_DEBUG_RANGES, - &readendp, &start_offset)) == NULL) + *basep = __libdw_cu_base_address (attr->cu); + if (*basep == (Dwarf_Addr) -1) return -1; - offset = start_offset; - assert ((Dwarf_Word) offset == start_offset); - - /* Fetch the CU's base address. */ - Dwarf_Die cudie = CUDIE (attr->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 (INTUSE(dwarf_lowpc) (&cudie, basep) != 0) - && INTUSE(dwarf_formaddr) (INTUSE(dwarf_attr) (&cudie, - DW_AT_entry_pc, - &attr_mem), - basep) != 0) - *basep = (Dwarf_Addr) -1; + if (initial_offset (attr, &offset) != 0) + return -1; } else { if (__libdw_offset_in_section (die->cu->dbg, - IDX_debug_ranges, offset, 1)) - return -1l; - - readp = d->d_buf + offset; - readendp = d->d_buf + d->d_size; + secidx, offset, 1)) + return -1; } - next: - if (readendp - readp < die->cu->address_size * 2) - goto invalid; + readp = d->d_buf + offset; + readendp = d->d_buf + d->d_size; Dwarf_Addr begin; Dwarf_Addr end; - switch (__libdw_read_begin_end_pair_inc (die->cu->dbg, IDX_debug_ranges, - &readp, die->cu->address_size, + next: + switch (__libdw_read_begin_end_pair_inc (die->cu->dbg, secidx, + &readp, readendp, + die->cu->address_size, &begin, &end, basep)) { case 0: @@ -172,22 +168,11 @@ dwarf_ranges (Dwarf_Die *die, ptrdiff_t offset, Dwarf_Addr *basep, case 2: return 0; default: - return -1l; - } - - /* We have an address range entry. Check that we have a base. */ - if (*basep == (Dwarf_Addr) -1) - { - if (INTUSE(dwarf_errno) () == 0) - { - invalid: - __libdw_seterrno (DWARF_E_INVALID_DWARF); - } return -1; } - *startp = *basep + begin; - *endp = *basep + end; + *startp = begin; + *endp = end; return readp - (unsigned char *) d->d_buf; } INTDEF (dwarf_ranges) diff --git a/libdw/libdwP.h b/libdw/libdwP.h index 9413705..594486f 100644 --- a/libdw/libdwP.h +++ b/libdw/libdwP.h @@ -1,7 +1,6 @@ -/* Internal definitions for libdwarf. +/* Internal definitions for libdw. Copyright (C) 2002-2011, 2013-2018 Red Hat, Inc. This file is part of elfutils. - Written by Ulrich Drepper , 2002. This file is free software; you can redistribute it and/or modify it under the terms of either @@ -328,6 +327,10 @@ struct Dwarf_CU /* Known location lists. */ void *locs; + /* Base address for use with ranges and locs. + Don't access directly, call __libdw_cu_base_address. */ + Dwarf_Addr base_address; + /* The offset into the .debug_addr section where index zero begins. Don't access directly, call __libdw_cu_addr_base. */ Dwarf_Off addr_base; @@ -849,14 +852,17 @@ is_cudie (Dwarf_Die *cudie) - 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, - unsigned char **addr, int width, + const unsigned char **readp, + const unsigned char *readend, + int width, Dwarf_Addr *beginp, Dwarf_Addr *endp, Dwarf_Addr *basep) internal_function; -unsigned char * __libdw_formptr (Dwarf_Attribute *attr, int sec_index, - int err_nodata, unsigned char **endpp, - Dwarf_Off *offsetp) +const unsigned char * __libdw_formptr (Dwarf_Attribute *attr, int sec_index, + int err_nodata, + const unsigned char **endpp, + Dwarf_Off *offsetp) internal_function; /* Fills in the given attribute to point at an empty location expression. */ @@ -877,6 +883,10 @@ int __libdw_getsrclines (Dwarf *dbg, Dwarf_Off debug_line_offset, /* Load and return value of DW_AT_comp_dir from CUDIE. */ const char *__libdw_getcompdir (Dwarf_Die *cudie); +/* Get the base address for the CU, fetches it when not yet set. + This is used as initial base address for ranges and loclists. */ +Dwarf_Addr __libdw_cu_base_address (Dwarf_CU *cu); + /* Get the address base for the CU, fetches it when not yet set. */ Dwarf_Off __libdw_cu_addr_base (Dwarf_CU *cu); diff --git a/libdw/libdw_findcu.c b/libdw/libdw_findcu.c index 04390b4..3899c08 100644 --- a/libdw/libdw_findcu.c +++ b/libdw/libdw_findcu.c @@ -116,6 +116,7 @@ __libdw_intern_next_unit (Dwarf *dbg, bool debug_types) newp->orig_abbrev_offset = newp->last_abbrev_offset = abbrev_offset; newp->lines = NULL; newp->locs = NULL; + newp->base_address = (Dwarf_Addr) -1; newp->addr_base = (Dwarf_Off) -1; newp->str_off_base = (Dwarf_Off) -1; diff --git a/tests/ChangeLog b/tests/ChangeLog index fea1d17..bcb24dc 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,9 @@ +2018-04-03 Mark Wielaard + + * testfileranges4.debug.bz2: New testfile. + * run-dwarf-ranges.sh: Run on testfileranges4.debug. + * tests/Makefile.am (EXTRA_DIST): Add testfileranges4.debug.bz2. + 2018-03-06 Mark Wielaard * varlocs.c (print_expr): Handle DW_OP_implicit_pointer, diff --git a/tests/Makefile.am b/tests/Makefile.am index fe6c8ec..a8cc2df 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -198,6 +198,7 @@ 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 \ 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-dwarf-ranges.sh b/tests/run-dwarf-ranges.sh index d202ed3..f935eaf 100755 --- a/tests/run-dwarf-ranges.sh +++ b/tests/run-dwarf-ranges.sh @@ -1,5 +1,5 @@ #! /bin/sh -# Copyright (C) 2015 Red Hat, Inc. +# Copyright (C) 2015, 2018 Red Hat, Inc. # This file is part of elfutils. # # This file is free software; you can redistribute it and/or modify @@ -24,4 +24,82 @@ testrun_compare ${abs_builddir}/dwarf-ranges debug-ranges-no-lowpc.o 0xb <<\EOF 3..4 (base 0) EOF +# - hello.c +# int say (const char *prefix); +# +# char * +# subject (char *word, int count) +# { +# return count > 0 ? word : (word + count); +# } +# +# int +# main (int argc, char **argv) +# { +# return say (subject (argv[0], argc)); +# } +# +# int +# no_say (const char *prefix) +# { +# const char *world = subject ("World", 42); +# return prefix ? say (prefix) : say (world); +# } +# +# - world.c +# char * subject (char *word, int count); +# int no_say (const char *prefix); +# +# static int +# sad (char c) +# { +# return c > 0 ? c : c + 1; +# } +# +# static int +# happy (const char *w) +# { +# return sad (w[1]); +# } +# +# int +# say (const char *prefix) +# { +# const char *world = subject ("World", 42);; +# return prefix ? sad (prefix[0]) : happy (world); +# } +# +# char * +# no_subject (char *word, int count) +# { +# return count > 0 ? word : (word + count); +# } +# +# int +# no_main (int argc, char **argv) +# { +# return no_say (no_subject (argv[0], argc)); +# } +# +# - gcc -c -O2 -gdwarf-4 hello.c +# - gcc -c -O2 -gdwarf-4 world.c +# - gcc -o testfileranges4 -O2 -gdwarf-4 hello.o world.o +# - eu-strip -f testfileranges4.debug testfileranges4 + +testfiles testfileranges4.debug +testrun_compare ${abs_builddir}/dwarf-ranges testfileranges4.debug 0xb <<\EOF +400500..40053a (base 0) +400400..400415 (base 0) +EOF + +testrun_compare ${abs_builddir}/dwarf-ranges testfileranges4.debug 0xcd <<\EOF +400400..400402 (base 0) +400405..40040d (base 0) +EOF + +testrun_compare ${abs_builddir}/dwarf-ranges testfileranges4.debug 0x374 <<\EOF +4005a0..4005a2 (base 400540) +4005a5..4005ad (base 400540) +EOF + exit 0 diff --git a/tests/testfileranges4.debug.bz2 b/tests/testfileranges4.debug.bz2 new file mode 100755 index 0000000000000000000000000000000000000000..67ba573d6448b63201322ad9599ef6ea9798699a GIT binary patch literal 3038 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