This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

PATCH for static DWARF2 buffers



Here's a patch to eliminate some static buffers in the DWARF2 code.
These buffers were overflowing because of symbol names in excess of
1000 characters.  (Sounds crazy until you remember the long names
generated by templates.)

Since the functions involved were already using xmalloc to allocate
memory, rather than obstacks, I chose not to use obstacks.  Instead,
since there were rumors that gcc will eventually head away from
obstacks, I wrote (for the umpteenth time) a small dynamically
allocated string ADT, and used that.

May I check this in?  Should it also go on the 1.1 branch?

-- 
Mark Mitchell 			mark@markmitchell.com
Mark Mitchell Consulting	http://www.markmitchell.com

Sun Jul 19 18:09:00 1998  Mark Mitchell  <mark@markmitchell.com>

	* dyn-string.h: New file.
	* dyn-string.c: Likewise.
	* Makefile.in (OBJS): Add dyn-string.o.
	(dwarf2out.o): Add dyn-string.h dependency.
	(dyn-string.o): List dependencies.
	* dwarf2out.c: Include dyn-string.h.
	(ASM_NAME_TO_STRING): Use dyn_string_append, rather than strcpy.
	(addr_const_to_string): Take a dyn_string_t, not a char* as a
	prototype.  Use dyn_string_append rather than strcat, throughout.
	(addr_to_string): Use dyn_string_t.

Index: Makefile.in
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/Makefile.in,v
retrieving revision 1.151
diff -c -p -r1.151 Makefile.in
*** Makefile.in	1998/07/09 22:55:40	1.151
--- Makefile.in	1998/07/20 01:15:46
*************** OBJS = toplev.o version.o tree.o print-t
*** 641,647 ****
   regclass.o local-alloc.o global.o reload.o reload1.o caller-save.o gcse.o \
   insn-peep.o reorg.o $(SCHED_PREFIX)sched.o final.o recog.o reg-stack.o \
   insn-opinit.o insn-recog.o insn-extract.o insn-output.o insn-emit.o \
!  profile.o insn-attrtab.o $(out_object_file) getpwd.o $(EXTRA_OBJS) convert.o
  
  # GEN files are listed separately, so they can be built before doing parallel
  #  makes for cc1 or cc1plus.  Otherwise sequent parallel make attempts to load
--- 641,648 ----
   regclass.o local-alloc.o global.o reload.o reload1.o caller-save.o gcse.o \
   insn-peep.o reorg.o $(SCHED_PREFIX)sched.o final.o recog.o reg-stack.o \
   insn-opinit.o insn-recog.o insn-extract.o insn-output.o insn-emit.o \
!  profile.o insn-attrtab.o $(out_object_file) getpwd.o $(EXTRA_OBJS) convert.o \
!  dyn-string.o
  
  # GEN files are listed separately, so they can be built before doing parallel
  #  makes for cc1 or cc1plus.  Otherwise sequent parallel make attempts to load
*************** dwarfout.o : dwarfout.c $(CONFIG_H) syst
*** 1413,1419 ****
     flags.h insn-config.h reload.h output.h defaults.h toplev.h dwarfout.h
  dwarf2out.o : dwarf2out.c $(CONFIG_H) system.h $(TREE_H) $(RTL_H) dwarf2.h \
     flags.h insn-config.h reload.h output.h defaults.h \
!    hard-reg-set.h $(REGS_H) $(EXPR_H) toplev.h dwarf2out.h
  xcoffout.o : xcoffout.c $(CONFIG_H) system.h $(TREE_H) $(RTL_H) xcoffout.h \
     flags.h toplev.h output.h dbxout.h
  emit-rtl.o : emit-rtl.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) flags.h \
--- 1414,1420 ----
     flags.h insn-config.h reload.h output.h defaults.h toplev.h dwarfout.h
  dwarf2out.o : dwarf2out.c $(CONFIG_H) system.h $(TREE_H) $(RTL_H) dwarf2.h \
     flags.h insn-config.h reload.h output.h defaults.h \
!    hard-reg-set.h $(REGS_H) $(EXPR_H) toplev.h dwarf2out.h dyn-string.h
  xcoffout.o : xcoffout.c $(CONFIG_H) system.h $(TREE_H) $(RTL_H) xcoffout.h \
     flags.h toplev.h output.h dbxout.h
  emit-rtl.o : emit-rtl.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) flags.h \
*************** recog.o : recog.c $(CONFIG_H) system.h $
*** 1489,1494 ****
--- 1490,1496 ----
     insn-flags.h insn-codes.h real.h
  reg-stack.o : reg-stack.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) \
     $(REGS_H) hard-reg-set.h flags.h insn-config.h insn-flags.h toplev.h
+ dyn-string.o: dyn-string.c dyn-string.h $(CONFIG_H) system.h gansidecl.h
  
  $(out_object_file): $(out_file) $(CONFIG_H) $(TREE_H) \
     $(RTL_H) $(REGS_H) hard-reg-set.h real.h insn-config.h conditions.h \
Index: dyn-string.h
===================================================================
RCS file: dyn-string.h
diff -N dyn-string.h
*** /dev/null	Mon Dec 31 20:00:00 1979
--- dyn-string.h	Sun Jul 19 18:15:46 1998
***************
*** 0 ****
--- 1,31 ----
+ /* An abstract string datatype.
+    Copyright (C) 1998 Free Software Foundation, Inc.
+    Contributed by Mark Mitchell (mark@markmitchell.com).
+ 
+    This file is part of GNU CC.
+    
+    GNU CC is free software; you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2, or (at your option)
+    any later version.
+ 
+    GNU CC is distributed in the hope that it will be useful, but
+    WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    General Public License for more details.
+ 
+    You should have received a copy of the GNU General Public License
+    along with GNU CC; see the file COPYING.  If not, write to the Free
+    Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+ 
+ typedef struct dyn_string
+ {
+   int allocated; /* The amount of space allocated for the string.  */
+   int length; /* The actual length of the string.  */
+   char *s; /* The string itself, NUL-terminated.  */
+ }* dyn_string_t;
+ 
+ extern dyn_string_t dyn_string_new      PROTO((int));
+ extern void dyn_string_delete           PROTO((dyn_string_t));
+ extern dyn_string_t dyn_string_append   PROTO((dyn_string_t, char*));
+ extern dyn_string_t dyn_string_resize   PROTO((dyn_string_t, int));
Index: dyn-string.c
===================================================================
RCS file: dyn-string.c
diff -N dyn-string.c
*** /dev/null	Mon Dec 31 20:00:00 1979
--- dyn-string.c	Sun Jul 19 18:27:36 1998
***************
*** 0 ****
--- 1,86 ----
+ /* An abstract string datatype.
+    Copyright (C) 1998 Free Software Foundation, Inc.
+    Contributed by Mark Mitchell (mark@markmitchell.com).
+ 
+    This file is part of GNU CC.
+    
+    GNU CC is free software; you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2, or (at your option)
+    any later version.
+ 
+    GNU CC is distributed in the hope that it will be useful, but
+    WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    General Public License for more details.
+ 
+    You should have received a copy of the GNU General Public License
+    along with GNU CC; see the file COPYING.  If not, write to the Free
+    Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+ 
+ #include "config.h"
+ #include "system.h"
+ #include "gansidecl.h"
+ #include "dyn-string.h"
+ 
+ extern char* xmalloc ();
+ extern char* xrealloc ();
+ 
+ dyn_string_t dyn_string_new (space)
+      int space;
+ {
+   dyn_string_t result = (dyn_string_t) xmalloc (sizeof (struct dyn_string));
+  
+   if (space == 0)
+     /* We need at least one byte in which to store the terminating
+        NUL.  */
+     space = 1;
+ 
+   result->allocated = space;
+   result->s = (char*) xmalloc (space);
+   result->length = 0;
+   result->s[0] = '\0';
+ 
+   return result;
+ }
+ 
+ 
+ void dyn_string_delete (ds)
+      dyn_string_t ds;
+ {
+   free (ds->s);
+   free (ds);
+ }
+ 
+ 
+ dyn_string_t dyn_string_append (ds, s)
+      dyn_string_t ds;
+      char *s;
+ {
+   int len = strlen (s);
+   dyn_string_resize (ds, ds->length + len + 1 /* '\0' */);
+   strcpy (ds->s + ds->length, s);
+   ds->length += len;
+ 
+   return ds;
+ }
+ 
+ 
+ dyn_string_t dyn_string_resize (ds, space)
+      dyn_string_t ds;
+      int space;
+ {
+   int new_allocated = ds->allocated;
+ 
+   while (space > new_allocated)
+     new_allocated *= 2;
+     
+   if (new_allocated != ds->allocated)
+     {
+       /* We actually need more space.  */
+       ds->allocated = new_allocated;
+       ds->s = xrealloc (ds->s, ds->allocated);
+     }
+ 
+   return ds;
+ }
Index: dwarf2out.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/dwarf2out.c,v
retrieving revision 1.62
diff -c -p -r1.62 dwarf2out.c
*** dwarf2out.c	1998/06/29 21:39:39	1.62
--- dwarf2out.c	1998/07/20 01:16:34
*************** the Free Software Foundation, 675 Mass A
*** 42,47 ****
--- 42,48 ----
  #include "dwarf2.h"
  #include "dwarf2out.h"
  #include "toplev.h"
+ #include "dyn-string.h"
  
  /* We cannot use <assert.h> in GCC source, since that would include
     GCC's assert.h, which may not be compatible with the host compiler.  */
*************** static tree dwarf_last_decl;
*** 2374,2380 ****
  
  /* Forward declarations for functions defined in this file.  */
  
! static void addr_const_to_string	PROTO((char *, rtx));
  static char *addr_to_string		PROTO((rtx));
  static int is_pseudo_reg		PROTO((rtx));
  static tree type_main_variant		PROTO((tree));
--- 2375,2381 ----
  
  /* Forward declarations for functions defined in this file.  */
  
! static void addr_const_to_string	PROTO((dyn_string_t, rtx));
  static char *addr_to_string		PROTO((rtx));
  static int is_pseudo_reg		PROTO((rtx));
  static tree type_main_variant		PROTO((tree));
*************** static char text_end_label[MAX_ARTIFICIA
*** 2639,2647 ****
  #define ASM_NAME_TO_STRING(STR, NAME) \
    do {									      \
        if ((NAME)[0] == '*')						      \
! 	strcpy (STR, NAME+1);						      \
        else								      \
! 	strcpy (STR, NAME);                                                   \
    }                                                                           \
    while (0)
  #endif
--- 2640,2648 ----
  #define ASM_NAME_TO_STRING(STR, NAME) \
    do {									      \
        if ((NAME)[0] == '*')						      \
! 	dyn_string_append (STR, NAME + 1);				      \
        else								      \
! 	dyn_string_append (STR, NAME);                                        \
    }                                                                           \
    while (0)
  #endif
*************** static char text_end_label[MAX_ARTIFICIA
*** 2654,2703 ****
  
  static void
  addr_const_to_string (str, x)
!      char *str;
       rtx x;
  {
    char buf1[256];
-   char buf2[256];
  
  restart:
-   str[0] = '\0';
    switch (GET_CODE (x))
      {
      case PC:
        if (flag_pic)
! 	strcat (str, ",");
        else
  	abort ();
        break;
  
      case SYMBOL_REF:
!       ASM_NAME_TO_STRING (buf1, XSTR (x, 0));
!       strcat (str, buf1);
        break;
  
      case LABEL_REF:
        ASM_GENERATE_INTERNAL_LABEL (buf1, "L", CODE_LABEL_NUMBER (XEXP (x, 0)));
!       ASM_NAME_TO_STRING (buf2, buf1);
!       strcat (str, buf2);
        break;
  
      case CODE_LABEL:
        ASM_GENERATE_INTERNAL_LABEL (buf1, "L", CODE_LABEL_NUMBER (x));
!       ASM_NAME_TO_STRING (buf2, buf1);
!       strcat (str, buf2);
        break;
  
      case CONST_INT:
        sprintf (buf1, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
!       strcat (str, buf1);
        break;
  
      case CONST:
        /* This used to output parentheses around the expression, but that does 
           not work on the 386 (either ATT or BSD assembler).  */
!       addr_const_to_string (buf1, XEXP (x, 0));
!       strcat (str, buf1);
        break;
  
      case CONST_DOUBLE:
--- 2655,2698 ----
  
  static void
  addr_const_to_string (str, x)
!      dyn_string_t str;
       rtx x;
  {
    char buf1[256];
  
  restart:
    switch (GET_CODE (x))
      {
      case PC:
        if (flag_pic)
! 	dyn_string_append (str, ",");
        else
  	abort ();
        break;
  
      case SYMBOL_REF:
!       ASM_NAME_TO_STRING (str, XSTR (x, 0));
        break;
  
      case LABEL_REF:
        ASM_GENERATE_INTERNAL_LABEL (buf1, "L", CODE_LABEL_NUMBER (XEXP (x, 0)));
!       ASM_NAME_TO_STRING (str, buf1);
        break;
  
      case CODE_LABEL:
        ASM_GENERATE_INTERNAL_LABEL (buf1, "L", CODE_LABEL_NUMBER (x));
!       ASM_NAME_TO_STRING (str, buf1);
        break;
  
      case CONST_INT:
        sprintf (buf1, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
!       dyn_string_append (str, buf1);
        break;
  
      case CONST:
        /* This used to output parentheses around the expression, but that does 
           not work on the 386 (either ATT or BSD assembler).  */
!       addr_const_to_string (str, XEXP (x, 0));
        break;
  
      case CONST_DOUBLE:
*************** restart:
*** 2712,2718 ****
  	  else
  	    sprintf (buf1, HOST_WIDE_INT_PRINT_DEC,
  		     CONST_DOUBLE_LOW (x));
! 	  strcat (str, buf1);
  	}
        else
  	/* We can't handle floating point constants; PRINT_OPERAND must
--- 2707,2713 ----
  	  else
  	    sprintf (buf1, HOST_WIDE_INT_PRINT_DEC,
  		     CONST_DOUBLE_LOW (x));
! 	  dyn_string_append (str, buf1);
  	}
        else
  	/* We can't handle floating point constants; PRINT_OPERAND must
*************** restart:
*** 2724,2746 ****
        /* Some assemblers need integer constants to appear last (eg masm).  */
        if (GET_CODE (XEXP (x, 0)) == CONST_INT)
  	{
! 	  addr_const_to_string (buf1, XEXP (x, 1));
! 	  strcat (str, buf1);
  	  if (INTVAL (XEXP (x, 0)) >= 0)
! 	    strcat (str, "+");
  
! 	  addr_const_to_string (buf1, XEXP (x, 0));
! 	  strcat (str, buf1);
  	}
        else
  	{
! 	  addr_const_to_string (buf1, XEXP (x, 0));
! 	  strcat (str, buf1);
  	  if (INTVAL (XEXP (x, 1)) >= 0)
! 	    strcat (str, "+");
  
! 	  addr_const_to_string (buf1, XEXP (x, 1));
! 	  strcat (str, buf1);
  	}
        break;
  
--- 2719,2737 ----
        /* Some assemblers need integer constants to appear last (eg masm).  */
        if (GET_CODE (XEXP (x, 0)) == CONST_INT)
  	{
! 	  addr_const_to_string (str, XEXP (x, 1));
  	  if (INTVAL (XEXP (x, 0)) >= 0)
! 	    dyn_string_append (str, "+");
  
! 	  addr_const_to_string (str, XEXP (x, 0));
  	}
        else
  	{
! 	  addr_const_to_string (str, XEXP (x, 0));
  	  if (INTVAL (XEXP (x, 1)) >= 0)
! 	    dyn_string_append (str, "+");
  
! 	  addr_const_to_string (str, XEXP (x, 1));
  	}
        break;
  
*************** restart:
*** 2751,2778 ****
        if (GET_CODE (x) != MINUS)
  	goto restart;
  
!       addr_const_to_string (buf1, XEXP (x, 0));
!       strcat (str, buf1);
!       strcat (str, "-");
        if (GET_CODE (XEXP (x, 1)) == CONST_INT
  	  && INTVAL (XEXP (x, 1)) < 0)
  	{
! 	  strcat (str, ASM_OPEN_PAREN);
! 	  addr_const_to_string (buf1, XEXP (x, 1));
! 	  strcat (str, buf1);
! 	  strcat (str, ASM_CLOSE_PAREN);
  	}
        else
! 	{
! 	  addr_const_to_string (buf1, XEXP (x, 1));
! 	  strcat (str, buf1);
! 	}
        break;
  
      case ZERO_EXTEND:
      case SIGN_EXTEND:
!       addr_const_to_string (buf1, XEXP (x, 0));
!       strcat (str, buf1);
        break;
  
      default:
--- 2742,2763 ----
        if (GET_CODE (x) != MINUS)
  	goto restart;
  
!       addr_const_to_string (str, XEXP (x, 0));
!       dyn_string_append (str, "-");
        if (GET_CODE (XEXP (x, 1)) == CONST_INT
  	  && INTVAL (XEXP (x, 1)) < 0)
  	{
! 	  dyn_string_append (str, ASM_OPEN_PAREN);
! 	  addr_const_to_string (str, XEXP (x, 1));
! 	  dyn_string_append (str, ASM_CLOSE_PAREN);
  	}
        else
! 	addr_const_to_string (str, XEXP (x, 1));
        break;
  
      case ZERO_EXTEND:
      case SIGN_EXTEND:
!       addr_const_to_string (str, XEXP (x, 0));
        break;
  
      default:
*************** static char *
*** 2787,2795 ****
  addr_to_string (x)
       rtx x;
  {
!   char buf[1024];
!   addr_const_to_string (buf, x);
!   return xstrdup (buf);
  }
  
  /* Test if rtl node points to a pseudo register.  */
--- 2772,2787 ----
  addr_to_string (x)
       rtx x;
  {
!   dyn_string_t ds = dyn_string_new (256);
!   char* s;
! 
!   addr_const_to_string (ds, x);
!   
!   /* Return the dynamically allocated string, but free the
!      dyn_string_t itself.  */
!   s = ds->s;
!   free (ds);
!   return s;
  }
  
  /* Test if rtl node points to a pseudo register.  */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]