Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Daniel Jacobowitz <drow@mvista.com>
To: Elena Zannoni <ezannoni@redhat.com>, Jim Blandy <jimb@redhat.com>
Cc: Richard Henderson <rth@redhat.com>, gdb-patches@sources.redhat.com
Subject: Re: [RFC] Partial support for dwarf3 DW_AT_ranges
Date: Wed, 29 Jan 2003 15:53:00 -0000	[thread overview]
Message-ID: <20030129155346.GA13172@nevyn.them.org> (raw)
In-Reply-To: <15413.57239.249007.204757@localhost.localdomain>

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.

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.

> 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


  reply	other threads:[~2003-01-29 15:53 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2001-12-31  0:34 Richard Henderson
2002-01-04  7:20 ` Daniel Berlin
2002-01-04  9:13   ` Daniel Jacobowitz
2002-01-04  9:48     ` Richard Henderson
2002-01-04  9:47 ` Elena Zannoni
2003-01-29 15:53   ` Daniel Jacobowitz [this message]
2003-01-29 18:09     ` Elena Zannoni
2003-01-29 21:27       ` Daniel Jacobowitz
2003-01-29 22:44         ` Daniel Jacobowitz
2003-02-04 14:59           ` Elena Zannoni
2003-02-04 15:05             ` Daniel Jacobowitz
2003-01-30  0:51       ` Daniel Jacobowitz
2003-01-30  1:02         ` Elena Zannoni
2003-01-30  1:52           ` Daniel Jacobowitz

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20030129155346.GA13172@nevyn.them.org \
    --to=drow@mvista.com \
    --cc=ezannoni@redhat.com \
    --cc=gdb-patches@sources.redhat.com \
    --cc=jimb@redhat.com \
    --cc=rth@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox