From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 1243 invoked by alias); 29 Jan 2003 18:09:24 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 1229 invoked from network); 29 Jan 2003 18:09:24 -0000 Received: from unknown (HELO mx1.redhat.com) (172.16.49.200) by 172.16.49.205 with SMTP; 29 Jan 2003 18:09:24 -0000 Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.11.6/8.11.6) with ESMTP id h0THe1f26394 for ; Wed, 29 Jan 2003 12:40:01 -0500 Received: from pobox.corp.redhat.com (pobox.corp.redhat.com [172.16.52.156]) by int-mx1.corp.redhat.com (8.11.6/8.11.6) with ESMTP id h0TI9Oa31495; Wed, 29 Jan 2003 13:09:24 -0500 Received: from localhost.redhat.com (romulus-int.sfbay.redhat.com [172.16.27.46]) by pobox.corp.redhat.com (8.11.6/8.11.6) with ESMTP id h0TI9MC09920; Wed, 29 Jan 2003 13:09:22 -0500 Received: by localhost.redhat.com (Postfix, from userid 469) id 189F0FF79; Wed, 29 Jan 2003 13:13:36 -0500 (EST) From: Elena Zannoni MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Message-ID: <15928.6608.942581.500183@localhost.redhat.com> Date: Wed, 29 Jan 2003 18:09:00 -0000 To: Daniel Jacobowitz Cc: Elena Zannoni , Jim Blandy , Richard Henderson , gdb-patches@sources.redhat.com Subject: Re: [RFC] Partial support for dwarf3 DW_AT_ranges In-Reply-To: <20030129155346.GA13172@nevyn.them.org> References: <20011231003448.A3399@redhat.com> <15413.57239.249007.204757@localhost.localdomain> <20030129155346.GA13172@nevyn.them.org> X-SW-Source: 2003-01/txt/msg00780.txt.bz2 Daniel Jacobowitz writes: > On Fri, Jan 04, 2002 at 12:00:07PM -0500, Elena Zannoni wrote: > > Richard Henderson writes: > > > GCC began emitting DW_AT_ranges back in September to deal with > > > lexical scopes made discontiguous by basic block reordering. > > > > > > As of today, it may also create discontiguous lexical scopes > > > due to scheduling. (Before today under the same circumstances > > > we'd lose track of which instructions belonged to which scope > > > and fail to emit any debug information whatsoever.) > > > > > > > Richard, there was some initial effort to deal with this problem > > in gdb's symbol tables structures back in October. > > See the thread at: > > http://sources.redhat.com/ml/gdb-patches/2001-10/msg00304.html > > However, no real changes have been made to the symbol tables yet. > > > > > However, GDB doesn't recognize DW_AT_ranges as a valid way of > > > marking a lexical scope, which causes it to discard the scope > > > entirely. Which is probably the least useful thing that could > > > be done. > > > > > > The following does not add proper support for discontiguous > > > address ranges. I couldn't figure out how to do that in any > > > way that wasn't horribly invasive. I'm willing to expend a > > > significant amount of effort on this if someone is willing to > > > provide some direction. > > > > > > > The thread mentioned above has some initial implementation of an > > address set for partial symbol tables which would be used in case of > > non contiguous addr ranges. You should coordinate with Jim. > > > > > What this does do is find the "bounding box" of the discontiguous > > > range and use that. Yes, that will do the wrong thing in some > > > circumstances, but the current behaviour is wrong under all > > > circumstances, so it may be a net improvement. > > > > > > > I am OK with committing some initial support. At least now gdb can > > read the info. > > > > I have a few comments on your changes. Maybe I am missing it, but is > > the -1 value returned by dwarf2_get_pc_bounds used anywhere yet? If > > not, I would suggest we don't bother with it right now, given that the > > final solution will probably have to restructure that function again. > > Also, I would not want to introduce more goto's in gdb. I think that > > that sequence can be rewritten w/o goto's pretty easily. Also there > > is some formatting problem (white spaces around operators, full names > > for variables). Adding some comments on how the .debug_ranges list is > > organized would be helpful too. > > > > I think JimB is the one which has the last say on this however, since > > he has a patch in the works. > > > > Ping out there, folks. > > This lack of support for DW_AT_ranges is responsible for at least one, > probably two or more of the current PRs about "missing local > variables". Affected GCC versions have been shipping for some time; at > least 3.2 generates DW_AT_ranges, maybe earlier. Yes, I am looking at this patch at the moment, too. The lack of this feature is creating lots of troubles. > > Since nothing ever came of the grand plans to support ranges in the > symbol table directly, can we at least move forwards on this year-old > patch? If so, I'll update it for current GDB. > If you have time, I'd appreciate it. I have adapted the patch to the current sources, but even with it, I wasn't able to make Jakub's example work. The example is in PR 833. I can send you the diffs I have, if it helps. Elena > > thanks > > Elena > > > > > > > My test case for this was > > > > > > static int foo(int *); > > > static void bar(int *); > > > > > > int main() > > > { > > > { > > > int x = 0, r; > > > r = foo(&x); > > > if (__builtin_expect (r, 1)) > > > return 0; > > > bar (&x); > > > return 1; > > > } > > > } > > > > > > static int foo(int *p) > > > { > > > *p = 1; > > > return 0; > > > } > > > > > > static void bar(int *p) > > > { > > > *p = 2; > > > } > > > > > > For any GCC target that can emit epilogues as rtl, we will > > > arrange the code here as > > > > > > x = 0 > > > call foo > > > if r == 0 goto L1 > > > ret = 0 > > > L0: > > > return ret > > > L1: > > > call bar > > > ret = 1 > > > goto L0 > > > > > > The lexical scope created by the extra set of braces doesn't > > > cover the epilogue, so the scope's range is the block before > > > L0, plus the block after L1. > > > > > > > > > r~ > > > > > -/* Get low and high pc attributes from a die. > > > - Return 1 if the attributes are present and valid, otherwise, return 0. */ > > > +/* Get low and high pc attributes from a die. Return 1 if the attributes > > > + are present and valid, otherwise, return 0. Return -1 if the range is > > > + discontinuous, i.e. derived from DW_AT_ranges information. */ > > > > > > static int > > > -dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc, CORE_ADDR *highpc, > > > - struct objfile *objfile) > > > +dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc, > > > + CORE_ADDR *highpc, struct objfile *objfile, > > > + const struct comp_unit_head *cu_header) > > > { > > > + bfd *obfd = objfile->obfd; > > > struct attribute *attr; > > > CORE_ADDR low; > > > CORE_ADDR high; > > > + int ret; > > > > > > - attr = dwarf_attr (die, DW_AT_low_pc); > > > - if (attr) > > > - low = DW_ADDR (attr); > > > - else > > > - return 0; > > > attr = dwarf_attr (die, DW_AT_high_pc); > > > if (attr) > > > - high = DW_ADDR (attr); > > > - else > > > - return 0; > > > + { > > > + high = DW_ADDR (attr); > > > + attr = dwarf_attr (die, DW_AT_low_pc); > > > + if (attr) > > > + low = DW_ADDR (attr); > > > + else > > > + return 0; > > > + ret = 1; > > > + } > > > + else if ((attr = dwarf_attr (die, DW_AT_ranges)) != NULL) > > > + { > > > + unsigned int addr_size = cu_header->addr_size; > > > + CORE_ADDR mask = ~(~(CORE_ADDR)1 << (addr_size * 8 - 1)); > > > + unsigned int offset = DW_UNSND (attr); > > > + CORE_ADDR base; > > > + int dummy; > > > + unsigned int i; > > > + char *buffer; > > > > > > + /* The applicable base address is determined by (1) the closest > > > + preceding base address selection entry in the range list or > > > + (2) the DW_AT_low_pc of the compilation unit. */ > > > + /* ??? We definitely need some sort of indexed data structure here. > > > + At minimum we should recognize the common case of there being > > > + no base address selection entries. */ > > > + > > > + buffer = dwarf_ranges_buffer + offset; > > > + for (i = offset; i > 2 * addr_size; ) > > > + { > > > + CORE_ADDR marker; > > > + > > > + i -= 2 * addr_size; > > > + buffer -= 2 * addr_size; > > > + > > > + marker = read_address (obfd, buffer, cu_header, &dummy); > > > + if ((marker & mask) == mask) > > > + { > > > + base = read_address (obfd, buffer+addr_size, cu_header, &dummy); > > > + goto found_base; > > > + } > > > + } > > > + > > > + /* ??? Was in dwarf3 draft4, and has since been removed. > > > + GCC still uses it though. */ > > > + attr = dwarf_attr (cu_header->die, DW_AT_entry_pc); > > > + if (attr) > > > + { > > > + base = DW_ADDR (attr); > > > + goto found_base; > > > + } > > > + > > > + attr = dwarf_attr (cu_header->die, DW_AT_low_pc); > > > + if (attr) > > > + { > > > + base = DW_ADDR (attr); > > > + goto found_base; > > > + } > > > + > > > + /* We have no valid base address for the ranges data. */ > > > + return 0; > > > + > > > + found_base: > > > + buffer = dwarf_ranges_buffer + offset; > > > + low = read_address (obfd, buffer, cu_header, &dummy); > > > + buffer += addr_size; > > > + high = read_address (obfd, buffer, cu_header, &dummy); > > > + buffer += addr_size; > > > + if (low == 0 && high == 0) > > > + /* If the first entry is an end-of-list marker, the range > > > + describes an empty scope, i.e. no instructions. */ > > > + return 0; > > > + > > > + while (1) > > > + { > > > + CORE_ADDR b, e; > > > + offset += 2 * addr_size; > > > + > > > + b = read_address (obfd, buffer, cu_header, &dummy); > > > + buffer += addr_size; > > > + e = read_address (obfd, buffer, cu_header, &dummy); > > > + buffer += addr_size; > > > + if (b == 0 && e == 0) > > > + break; > > > + if (b < low) > > > + low = b; > > > + if (e > high) > > > + high = e; > > > + } > > > + > > > + low += base; > > > + high += base; > > > + ret = -1; > > > + } > > > + > > > if (high < low) > > > return 0; > > > > > > @@ -1800,12 +1908,12 @@ dwarf2_get_pc_bounds (struct die_info *d > > > labels are not in the output, so the relocs get a value of 0. > > > If this is a discarded function, mark the pc bounds as invalid, > > > so that GDB will ignore it. */ > > > - if (low == 0 && (bfd_get_file_flags (objfile->obfd) & HAS_RELOC) == 0) > > > + if (low == 0 && (bfd_get_file_flags (obfd) & HAS_RELOC) == 0) > > > return 0; > > > > > > *lowpc = low; > > > *highpc = high; > > > - return 1; > > > + return ret; > > > } > > > > > > /* Add an aggregate field to the field list. */ > > > > -- > Daniel Jacobowitz > MontaVista Software Debian GNU/Linux Developer