This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
a patch for coff_find_nearest_line()
- From: Jaka Močnik <jaka at xlab dot si>
- To: binutils at sourceware dot org
- Cc: "Novak, Marko" <marko dot novak at xlab dot si>, Erich Focht <efocht at hpce dot nec dot com>
- Date: Wed, 13 Aug 2008 16:48:16 +0200
- Subject: a patch for coff_find_nearest_line()
hello!
there is a bug in coff_find_nearest_line() (binutils 2.18), that
sometimes returns no line number information when this info in fact
exists ... it can be reproduced by using addr2line tool on a coff file
(any coff will do, I believe ...) to look up the same address twice in a
row.
the bug is due to faulty priming of the look-up loop, which works like
this:
when an appropriate line number info for address A is found at index I
in the section's lineno array, this information is returned (via the
line_ptr out parameter to coff_find_nearest_line()), and the lookup loop
breaks with the loop counter having the value I+1. this value I+1 is
then remembered as the starting point for further lookups of addresses
>= A.
now consider the following lineno array entries:
...
lineno[i]: offset X
lineno[i+1]: offset X+10
...
looking up line number for address X+2, we end up with the info from
lineno[i]. furthermore, i+1 is remembered as the starting index for
priming further lookups.
now try to lookup line number for address X+2 once again (or any address
A, X+2 <= A < X+10). since the address is larger or equal than the
previously looked up one, the lookup loop starts at index i+1.
naturally, no info for any address < X+10 is found, and
coff_find_nearest_line() returns wrong information.
the attached simple patch (against binutils 2.18) remedies the problem.
regards,
jaKa
--
email: jaka@xlab.si
w3: http://www.gmajna.net/svojat/jaka/
--- binutils-2.18/bfd/coffgen.c 2007-08-13 03:43:34.000000000 +0200
+++ binutils-2.18-sx/bfd/coffgen.c 2008-08-13 16:30:45.000000000 +0200
@@ -2231,7 +2231,7 @@
if (sec_data != NULL)
{
sec_data->offset = offset;
- sec_data->i = i;
+ sec_data->i = i - 1;
sec_data->function = *functionname_ptr;
sec_data->line_base = line_base;
}