This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: N_SLINE fix for _bfd_stab_section_find_nearest_address() is broken
- From: Daniel Jacobowitz <drow at mvista dot com>
- To: Nick Clifton <nickc at cambridge dot redhat dot com>
- Cc: binutils at sources dot redhat dot com
- Date: Tue, 28 May 2002 14:09:49 -0400
- Subject: Re: N_SLINE fix for _bfd_stab_section_find_nearest_address() is broken
- References: <m34rgsd4r9.fsf@north-pole.nickc.cambridge.redhat.com>
On Tue, May 28, 2002 at 10:02:34AM +0100, Nick Clifton wrote:
> 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.
Yes, your analysis makes sense to me; the way it's currently written
a great deal of the switch statement is actually dead code. Please
check in your fix.
> 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])
>
--
Daniel Jacobowitz Carnegie Mellon University
MontaVista Software Debian GNU/Linux Developer