This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
N_SLINE fix for _bfd_stab_section_find_nearest_address() is broken
- From: Nick Clifton <nickc at cambridge dot redhat dot com>
- To: drow at mvista dot com
- Cc: binutils at sources dot redhat dot com
- Date: 28 May 2002 10:02:34 +0100
- Subject: 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])