This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

N_SLINE fix for _bfd_stab_section_find_nearest_address() is broken


Hi Daniel,

  Your patch to work around a bug in 2.95.3 emitting N_SLINE data late
  is causing the arm-coff port to failed the linker's undefined line
  test when operating in Thumb mode.

    2002-03-20  Daniel Jacobowitz  <drow@mvista.com>

	* syms.c (_bfd_stab_section_find_nearest_line): Use the first
	N_SLINE encountered if we see an N_FUN before any N_SLINE.

  I have tracked it down to this code in  _bfd_stab_section_find_nearest_address():

	case N_SLINE:
	case N_DSLINE:
	case N_BSLINE:
	  /* A line number.  The value is relative to the start of the
             current function.  */
	  val = indexentry->val + bfd_get_32 (abfd, stab + VALOFF);
	  /* If this line starts before our desired offset, or if it's
	     the first line we've been able to find, use it.  The
	     !saw_line check works around a bug in GCC 2.95.3, which emits
	     the first N_SLINE late.  */
	  if (!saw_line || val <= offset)
	    {
	      *pline = bfd_get_16 (abfd, stab + DESCOFF);
     [snip]
            }
	  if (val > offset)
	    done = true;
	  saw_line = true;

  The problem is that 'saw_line' is reset every time around the for
  loop so *pline will be set to the last N_SLINE directive
  encountered, even if it is *greater* than the target address.

  For the thumb the stabs generated look this:

	.thumb_func
    _function:
    .stabn 68,0,8,.LM1-_function
    .LM1:
	push	{lr}
    .stabn 68,0,9,.LM2-_function
    .LM2:
	bl	_this_function_is_not_defined
    .stabn 68,0,10,.LM3-_function
    .LM3:
	pop	{pc}

  which means that the code will select the stab for line 10 as being
  the address of the branch to _this_function_is_not_defined, instead
  of the correct line (9).

  It seems to me that the problems would be fixed if 'saw_line' and
  'saw_func' were not reset each time around the loop, so how about
  this patch ?  It certainly fixes the problems with the arm-coff port
  and it does not appear to introduce any new failures in the x86
  native.

Cheers
        Nick

2002-05-28  Nick Clifton  <nickc@cambridge.redhat.com>

	* syms.c (_bfd_stab_section_find_nearest_line): Move
	declaration and initialisation of saw_line and saw_func out of
	for loop.

Index: bfd/syms.c
===================================================================
RCS file: /cvs/src/src/bfd/syms.c,v
retrieving revision 1.21
diff -c -3 -p -w -r1.21 syms.c
*** bfd/syms.c	23 May 2002 13:12:47 -0000	1.21
--- bfd/syms.c	28 May 2002 08:58:57 -0000
*************** _bfd_stab_section_find_nearest_line (abf
*** 883,888 ****
--- 883,889 ----
    char *file_name;
    char *directory_name;
    int saw_fun;
+   boolean saw_line, saw_func;
  
    *pfound = false;
    *pfilename = bfd_get_filename (abfd);
*************** _bfd_stab_section_find_nearest_line (abf
*** 1239,1251 ****
    directory_name = indexentry->directory_name;
    str = indexentry->str;
  
    for (; stab < (indexentry+1)->stab; stab += STABSIZE)
      {
!       boolean done, saw_line, saw_func;
        bfd_vma val;
  
-       saw_line = false;
-       saw_func = false;
        done = false;
  
        switch (stab[TYPEOFF])
--- 1240,1252 ----
    directory_name = indexentry->directory_name;
    str = indexentry->str;
  
+   saw_line = false;
+   saw_func = false;
    for (; stab < (indexentry+1)->stab; stab += STABSIZE)
      {
!       boolean done;
        bfd_vma val;
  
        done = false;
  
        switch (stab[TYPEOFF])


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]