Date: Sun, 18 Mar 2001 18:13:41 +0200 From: "Eli Zaretskii" Sender: halo1 AT zahav DOT net DOT il To: djgpp-workers AT delorie DOT com Message-Id: <7458-Sun18Mar2001181340+0200-eliz@is.elta.co.il> X-Mailer: Emacs 20.6 (via feedmail 8.3.emacs20_6 I) and Blat ver 1.8.6 Subject: Handle executables with more than 0xffff line entries in SYMIFY Reply-To: djgpp-workers AT delorie DOT com 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 @@ -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])