public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
From: Jim Wilson <wilson@cygnus.com>
To: binutils@sourceware.cygnus.com
Cc: wilson@cygnus.com, rth@cygnus.com
Subject: patch for gas/dwarf2dbg.c, can fail when new frags are created
Date: Thu, 26 Aug 1999 16:00:00 -0000	[thread overview]
Message-ID: <199908262300.QAA02757@ada.cygnus.com.cygnus.com> (raw)

Addresses are kept track of as offsets within the current frag.  When a new
frag is created, we need to emit an absolute address before we can use offsets
again.  The current code that checks for a new frag does not work.  It assumes
that if the offset decreases then we are in a new frag, but this is not good
enough.

If gcc emits alignment after branches, then it is common to get something like
	.align X
	.loc 0 10 0
	alu insn 1
	branch insn
	.align X
	.loc 0 11 0
	alu insn 2
In this case, we emit an absolute address and set the offset to 0 when we see
alu insn 1.  When we get to alu insn 2, the offset is again 0, and the
	if (addr < ls.sm.addr)
test does not notice the new frag.  This results in linenumber table info that
claims lines 10 and 11 are at the same address.

The following patch fixes this by directly keeping track of frags, so that we
can tell when we are in a new one.

Thu Aug 26 15:44:52 1999  Jim Wilson  <wilson@cygnus.com>

	* dwarf2dbg.c (MAX_SPECIAL_ADDR_DELTA): Correct typo in comment.
	(struct ls): Add frag field.  Initialize it to zero.
	(out_end_sequence): New local text_frag.  Set it while in text section.
	Replace address check with frag check.  Set ls.frag to text_frag if
	out_set_addr called.
	(dwarf2_gen_line_info): Add explanatory comment.  New local saved_frag.
	Set it before switching sections.  Replace address check with frag
	check.  Set ls.frag to saved_frag if out_set_addr called.

Index: dwarf2dbg.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gas/dwarf2dbg.c,v
retrieving revision 1.9
diff -p -r1.9 dwarf2dbg.c
*** dwarf2dbg.c	1999/08/26 05:16:45	1.9
--- dwarf2dbg.c	1999/08/26 22:41:40
***************
*** 86,92 ****
     DWARF2_LINE_MIN_INSN_LENGTH.  */
  #define SPECIAL_ADDR(op) (((op) - DWARF2_LINE_OPCODE_BASE)/DWARF2_LINE_RANGE)
  
! /* The maximum address skip amont that can be encoded with a special op: */
  #define MAX_SPECIAL_ADDR_DELTA		SPECIAL_ADDR(255)
  
  #define INITIAL_STATE						\
--- 86,92 ----
     DWARF2_LINE_MIN_INSN_LENGTH.  */
  #define SPECIAL_ADDR(op) (((op) - DWARF2_LINE_OPCODE_BASE)/DWARF2_LINE_RANGE)
  
! /* The maximum address skip amount that can be encoded with a special op: */
  #define MAX_SPECIAL_ADDR_DELTA		SPECIAL_ADDR(255)
  
  #define INITIAL_STATE						\
*************** static struct
*** 118,123 ****
--- 118,124 ----
      unsigned int
        any_dwarf2_directives : 1;	/* did we emit any DWARF2 line debug directives? */
  
+     fragS *frag;	/* frag that "addr" is relative to */
      segT text_seg;	/* text segment "addr" is relative to */
      subsegT text_subseg;
      segT line_seg;	/* ".debug_line" segment */
*************** ls =
*** 149,154 ****
--- 150,156 ----
      0,
      0,
      0,
+     0,
      NULL,
      { NULL, 0, 0, 0, 0 },
      0,
*************** static void
*** 324,329 ****
--- 326,332 ----
  out_end_sequence ()
  {
    addressT addr, delta;
+   fragS *text_frag;
  
    if (ls.text_seg)
      {
*************** out_end_sequence ()
*** 333,343 ****
  #else
        addr = frag_now_fix ();
  #endif
        subseg_set (ls.line_seg, DL_BODY);
!       if (addr < ls.sm.addr)
  	{
  	  out_set_addr (addr);
  	  ls.sm.addr = addr;
  	}
        else
  	{
--- 336,348 ----
  #else
        addr = frag_now_fix ();
  #endif
+       text_frag = frag_now;
        subseg_set (ls.line_seg, DL_BODY);
!       if (text_frag != ls.frag)
  	{
  	  out_set_addr (addr);
  	  ls.sm.addr = addr;
+ 	  ls.frag = text_frag;
  	}
        else
  	{
*************** get_filenum (filenum, file)
*** 407,412 ****
--- 412,420 ----
    return ++ls.num_filenames;
  }
  
+ /* Emit an entry in the line number table if the address or line has changed.
+    ADDR is relative to the current frag in the text section.  */
+ 
  void
  dwarf2_gen_line_info (addr, l)
       addressT addr;
*************** dwarf2_gen_line_info (addr, l)
*** 416,421 ****
--- 424,430 ----
    unsigned int any_output = 0;
    subsegT saved_subseg;
    segT saved_seg;
+   fragS *saved_frag;
  
    if (flag_debug)
      fprintf (stderr, "line: addr %lx file `%s' line %u col %u flags %x\n",
*************** dwarf2_gen_line_info (addr, l)
*** 438,443 ****
--- 447,453 ----
       them.  */
    saved_seg = now_seg;
    saved_subseg = now_subseg;
+   saved_frag = frag_now;
  
    if (!ls.line_seg)
      {
*************** dwarf2_gen_line_info (addr, l)
*** 473,478 ****
--- 483,489 ----
        ls.text_subseg = saved_subseg;
        out_set_addr (addr);
        ls.sm.addr = addr;
+       ls.frag = saved_frag;
      }
  
    if (ls.sm.filenum != filenum)
*************** dwarf2_gen_line_info (addr, l)
*** 506,523 ****
    if (ls.sm.line != l->line)
      {
        any_output = 1;
!       if (addr < ls.sm.addr)
  	{
! 	  /* This happens when a new frag got allocated (for whatever
! 	     reason).  Deal with it by generating a reference symbol.
! 	     Note: no end_sequence needs to be generated because the
! 	     address did not really decrease (only the reference point
! 	     changed).
! 
! 	     ??? Perhaps we should directly check for a change of
! 	     frag_now instead?  */
  	  out_set_addr (addr);
  	  ls.sm.addr = addr;
  	}
        gen_addr_line (l->line - ls.sm.line,
  		     (addr - ls.sm.addr) / DWARF2_LINE_MIN_INSN_LENGTH);
--- 517,531 ----
    if (ls.sm.line != l->line)
      {
        any_output = 1;
!       if (saved_frag != ls.frag)
  	{
! 	  /* If a new frag got allocated (for whatever reason), then
! 	     deal with it by generating a reference symbol.  Note: no
! 	     end_sequence needs to be generated because the address did
! 	     not really decrease (only the reference point changed).  */
  	  out_set_addr (addr);
  	  ls.sm.addr = addr;
+ 	  ls.frag = saved_frag;
  	}
        gen_addr_line (l->line - ls.sm.line,
  		     (addr - ls.sm.addr) / DWARF2_LINE_MIN_INSN_LENGTH);

             reply	other threads:[~1999-08-26 16:00 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1999-08-26 16:00 Jim Wilson [this message]
1999-08-27  2:08 Nick Clifton

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=199908262300.QAA02757@ada.cygnus.com.cygnus.com \
    --to=wilson@cygnus.com \
    --cc=binutils@sourceware.cygnus.com \
    --cc=rth@cygnus.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;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).