delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/2001/03/18/11:14:56

Date: Sun, 18 Mar 2001 18:13:41 +0200
From: "Eli Zaretskii" <eliz AT is DOT elta DOT co DOT il>
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 <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 -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019