Mail Archives: djgpp-workers/2001/03/18/11:14:56
SYMIFY crashes and burns (or prints garbled symbol names) if you run
it on a program that overflows the COFF 64K limit on line number
entries in the debug info. (GDB is an example of such a program.)
The bug is actually in syms.c, which doesn't guard itself against
this, and starts poking other data structures when the offset into the
string table becomes greater than 0xffff. (Thank God for watchpoints
in GDB, otherwise I could have no hope to ever find this bug!) So
this affects edebug32 and fsdb as well.
The following changes make SYMIFY cope gracefully with this problem.
While at that, I also changed symify.c to print "??" instead of a zero
when the line number info for a call frame is not found, due to this
overflow.
Comments?
Index: src/debug/common/syms.c
===================================================================
RCS file: /cvs/djgpp/djgpp/src/debug/common/syms.c,v
retrieving revision 1.6
diff -u -p -r1.6 syms.c
--- syms.c 2000/09/03 08:07:33 1.6
+++ syms.c 2001/03/18 16:04:40
@@ -333,12 +333,21 @@ static void process_coff(FILE *fd, long
crash. */
if (f_aux[i+1].x_sym.x_fcnary.x_fcn.x_lnnoptr >= f_sh[scn].s_lnnoptr)
{
- l = f_lnno[scn]
- + ((f_aux[i+1].x_sym.x_fcnary.x_fcn.x_lnnoptr
- - f_sh[scn].s_lnnoptr)/LINESZ);
- l_pending = 1;
- i2_max = f_sh[scn].s_nlnno - (l - f_lnno[scn]);
- l->l_addr.l_paddr = f_symtab[i].e_value;
+ size_t l_idx = (f_aux[i+1].x_sym.x_fcnary.x_fcn.x_lnnoptr
+ - f_sh[scn].s_lnnoptr) / LINESZ;
+
+ /* No line number info can be at offset larger than 0xffff
+ from f_lnno[scn], because COFF is limited to 64K
+ line-number entries. If they have more line entries
+ than that, they had line number overflow at link
+ time. */
+ if (l_idx < 0xffffU)
+ {
+ l = f_lnno[scn] + l_idx;
+ l_pending = 1;
+ i2_max = f_sh[scn].s_nlnno - l_idx;
+ l->l_addr.l_paddr = f_symtab[i].e_value;
+ }
}
}
@@ -350,7 +359,7 @@ static void process_coff(FILE *fd, long
syms[s].name = symndup(f_symtab[i].e.e_name, 8);
else
syms[s].name = f_string_table + f_symtab[i].e.e.e_offset;
-
+
switch (f_symtab[i].e_scnum)
{
case 1 ... 10:
Index: src/debug/common/symify.c
===================================================================
RCS file: /cvs/djgpp/djgpp/src/debug/common/symify.c,v
retrieving revision 1.4
diff -u -p -r1.4 symify.c
--- symify.c 1999/12/24 20:45:18 1.4
+++ symify.c 2001/03/18 16:05:33
@@ -1,3 +1,4 @@
+/* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
/* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
#include <stdio.h>
@@ -82,7 +83,10 @@ int main(int argc, char **argv)
{
if (func)
fprintf(ofile, ", ");
- fprintf(ofile, "line %d of %s", lineno, file);
+ if (lineno)
+ fprintf(ofile, "line %d of %s", lineno, file);
+ else
+ fprintf(ofile, "line ?? of %s", file);
}
fputc('\n', ofile);
}
@@ -144,7 +148,10 @@ int main(int argc, char **argv)
strcat(buf, ", ");
l_left -= 2;
}
- sprintf(buf+strlen(buf), "line %d of %s", lineno, file);
+ if (lineno)
+ sprintf(buf+strlen(buf), "line %d of %s", lineno, file);
+ else
+ sprintf(buf+strlen(buf), "line ?? of %s", file);
l_file = strlen(buf);
}
if (buf[0])
- Raw text -