Subject: crunchgen changes to use symbol renaming instead of symbol hiding
To: None <tech-toolchain@netbsd.org>
From: Simon Burge <simonb@wasabisystems.com>
List: tech-toolchain
Date: 01/22/2003 16:04:54
--Q68bSM7Ycu6FN28Q
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

Folks,

I'd like to commit the following patches that change crunchgen
to use symbol renaming instead of symbol hiding.  Symbol hiding
doesn't work on MIPS due to problems with changing the visibily
of certain types of relocations and it doesn't appear that it'll
be fixed anytime soon.

Currently objcopy doesn't support reading lists of symbols
to rename from a file (they way the list of symbols to hide
is currently done) - to do this, I've included a patch from
Chris Demetriou that he posted to the binutils mailling list in
http://sources.redhat.com/ml/binutils/2002-09/msg00505.html

I could have made this change for MIPS only, but didn't think
it was worth the effort/time/etc to differentiate.  This has
been tested on MIPS, i386, powerpc, sparc and sparc64.

Simon.
--
Simon Burge                                   <simonb@wasabisystems.com>
NetBSD Development, Support and Service:   http://www.wasabisystems.com/

--Q68bSM7Ycu6FN28Q
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="crunchgen.diffs"

Index: gnu/dist/toolchain/binutils/objcopy.c
===================================================================
RCS file: /cvsroot/src/gnu/dist/toolchain/binutils/objcopy.c,v
retrieving revision 1.8
diff -d -p -u -r1.8 objcopy.c
--- gnu/dist/toolchain/binutils/objcopy.c	2002/01/08 06:58:32	1.8
+++ gnu/dist/toolchain/binutils/objcopy.c	2003/01/22 03:01:39
@@ -28,6 +28,7 @@
 #include "budbg.h"
 #include "filenames.h"
 #include <sys/stat.h>
+#include <ctype.h>
 
 /* A list of symbols to explicitly strip out, or to keep.  A linked
    list is good enough for a small number from the command line, but
@@ -72,7 +73,10 @@ static void copy_file
 static int strip_main PARAMS ((int, char **));
 static int copy_main PARAMS ((int, char **));
 static const char *lookup_sym_redefinition PARAMS((const char *));
-static void redefine_list_append PARAMS ((const char *, const char *));
+static void redefine_list_append
+  PARAMS ((const char *, const char *, const char *));
+static void add_redefine_syms_file PARAMS ((const char *));
+
 
 #define RETURN_NONFATAL(s) {bfd_nonfatal (s); status = 1; return;}
 
@@ -219,7 +223,8 @@ static boolean weaken = false;
 #define OPTION_STRIP_UNNEEDED (OPTION_SET_START + 1)
 #define OPTION_WEAKEN (OPTION_STRIP_UNNEEDED + 1)
 #define OPTION_REDEFINE_SYM (OPTION_WEAKEN + 1)
-#define OPTION_SREC_LEN (OPTION_REDEFINE_SYM + 1)
+#define OPTION_REDEFINE_SYMS_FILE (OPTION_REDEFINE_SYM + 1)
+#define OPTION_SREC_LEN (OPTION_REDEFINE_SYMS_FILE + 1)
 #define OPTION_SREC_FORCES3 (OPTION_SREC_LEN + 1)
 #define OPTION_STRIP_SYMBOLS (OPTION_SREC_FORCES3 + 1)
 #define OPTION_KEEP_SYMBOLS (OPTION_STRIP_SYMBOLS + 1)
@@ -302,6 +307,7 @@ static struct option copy_options[] =
   {"weaken", no_argument, 0, OPTION_WEAKEN},
   {"weaken-symbol", required_argument, 0, 'W'},
   {"redefine-sym", required_argument, 0, OPTION_REDEFINE_SYM},
+  {"redefine-syms-file", required_argument, 0, OPTION_REDEFINE_SYMS_FILE},
   {"srec-len", required_argument, 0, OPTION_SREC_LEN},
   {"srec-forceS3", no_argument, 0, OPTION_SREC_FORCES3},
   {"keep-symbols", required_argument, 0, OPTION_KEEP_SYMBOLS},
@@ -378,6 +384,7 @@ copy_usage (stream, exit_status)
      --change-leading-char         Force output format's leading character style\n\
      --remove-leading-char         Remove leading character from global symbols\n\
      --redefine-sym <old>=<new>    Redefine symbol name <old> to <new>\n\
+     --redefine-syms-file <file>   Use <file> as a list of symbol redefinitions\n\
      --srec-len <number>           Restrict the length of generated Srecords\n\
      --srec-forceS3                Restrict the type of generated Srecords to S3\n\
      --strip-symbols <file>        -N for all symbols listed in <file>\n\
@@ -842,7 +849,8 @@ lookup_sym_redefinition (source)
 /* Add a node to a symbol redefine list */
 
 static void
-redefine_list_append (source, target)
+redefine_list_append (cause, source, target)
+     const char *cause;
      const char *source;
      const char *target;
 {
@@ -855,15 +863,13 @@ redefine_list_append (source, target)
       if (strcmp (source, list->source) == 0)
 	{
 	  fatal (_("%s: Multiple redefinition of symbol \"%s\""),
-		 "--redefine-sym",
-		  source);
+		 cause, source);
 	}
 
       if (strcmp (target, list->target) == 0)
 	{
 	  fatal (_("%s: Symbol \"%s\" is target of more than one redefinition"),
-		 "--redefine-sym",
-		  target);
+		 cause, target);
 	}
     }
 
@@ -876,6 +882,92 @@ redefine_list_append (source, target)
   *p = new_node;
 }
 
+/* Handle the --redefine-syms-file option.  Read lines conataining "old new"
+   from the file, and add them to the symbol redefine list.  */
+void
+add_redefine_syms_file (filename)
+     const char *filename;
+{
+  FILE *file;
+  char *buf;
+  size_t bufsize, len, outsym_off;
+  int c, lineno;
+
+  file = fopen (filename, "r");
+  if (file == (FILE *) NULL)
+    fatal (_("couldn't open symbol redefinition file %s (error: %s)"),
+	   filename, strerror (errno));
+
+  bufsize = 100;
+  buf = (char *) xmalloc (bufsize);
+
+  lineno = 1;
+  c = getc (file);
+  len = 0;
+  while (c != EOF)
+    {
+      /* Collect the input symbol name.  */
+      while (! isspace (c) && c != EOF)
+	{
+	  buf[len++] = c;
+	  if (len >= bufsize)
+	    {
+	      bufsize *= 2;
+	      buf = xrealloc (buf, bufsize);
+	    }
+	  c = getc (file);
+	}
+      buf[len++] = '\0';
+      if (c == EOF)
+	break;
+
+      /* Eat white space between the symbol names.  */
+      while (isspace (c))
+	c = getc (file);
+      if (c == EOF)
+	break;
+
+      /* Collect the output symbol name.  */
+      outsym_off = len;
+      while (! isspace (c) && c != EOF)
+	{
+	  buf[len++] = c;
+	  if (len >= bufsize)
+	    {
+	      bufsize *= 2;
+	      buf = xrealloc (buf, bufsize);
+	    }
+	  c = getc (file);
+	}
+      buf[len++] = '\0';
+      if (c == EOF)
+	break;
+
+      /* Eat white space at end of line.  */
+      while (c != '\n' && isspace (c))
+	c = getc (file);
+      if (c == EOF)
+	break;
+      else if (c == '\n')
+	{
+	  /* Append the redefinition to the list.  */
+	  redefine_list_append (filename, &buf[0], &buf[outsym_off]);
+
+	  lineno++;	
+	  len = 0;
+	  c = getc (file);
+	  continue;
+	}
+      else
+	fatal (_("%s: garbage at end of line %d"), filename, lineno);
+    }
+
+  if (len != 0)
+    fatal (_("%s: premature end of file at line %d"), filename, lineno);
+
+  free (buf);
+}
+
 
 /* Keep only every `copy_byte'th byte in MEMHUNK, which is *SIZE bytes long.
    Adjust *SIZE.  */
@@ -2266,11 +2358,15 @@ copy_main (argc, argv)
 	    target = (char *) xmalloc (len + 1);
 	    strcpy (target, nextarg);
 
-	    redefine_list_append (source, target);
+	    redefine_list_append ("--redefine-sym", source, target);
 
 	    free (source);
 	    free (target);
 	  }
+	  break;
+
+	case OPTION_REDEFINE_SYMS_FILE:
+	  add_redefine_syms_file (optarg);
 	  break;
 
 	case OPTION_SET_SECTION_FLAGS:
Index: usr.bin/crunch/crunchgen/crunchgen.c
===================================================================
RCS file: /cvsroot/src/usr.bin/crunch/crunchgen/crunchgen.c,v
retrieving revision 1.40
diff -d -p -u -r1.40 crunchgen.c
--- usr.bin/crunch/crunchgen/crunchgen.c	2002/08/20 01:52:58	1.40
+++ usr.bin/crunch/crunchgen/crunchgen.c	2003/01/22 03:01:39
@@ -56,6 +56,11 @@ __RCSID("$NetBSD: crunchgen.c,v 1.40 200
 #define MAXLINELEN	16384
 #define MAXFIELDS 	 2048
 
+/*
+ * Define RENAME_SYMS to rename symbols using objcopy --redefine-syms-file.
+ * Undef RENAME_SYMS to hide globals symbols using objcopy --keep-global-symbol.
+ */
+#define	RENAME_SYMS
 
 /* internal representation of conf file: */
 
@@ -829,6 +834,7 @@ void top_makefile_rules(FILE *outmk)
     fprintf(outmk, "MAKE?=make\n");
 #ifdef NEW_TOOLCHAIN
     fprintf(outmk, "OBJCOPY?=objcopy\n");
+    fprintf(outmk, "NM?=nm\n");
 #else
     fprintf(outmk, "CRUNCHIDE?=crunchide\n");
 #endif
@@ -852,7 +858,7 @@ void top_makefile_rules(FILE *outmk)
     fprintf(outmk, "all: ${PROG}\n\t${STRIP} ${PROG}\n");
     fprintf(outmk, "objs: $(SUBMAKE_TARGETS)\n");
     fprintf(outmk, "exe: %s\n", execfname);
-    fprintf(outmk, "clean:\n\trm -rf %s *.cro *.o *_stub.c ${CRUNCHEDOBJSDIRS}\n",
+    fprintf(outmk, "clean:\n\trm -rf %s *.cro *.cro.syms *.o *_stub.c ${CRUNCHEDOBJSDIRS}\n",
 	    execfname);
 }
 
@@ -903,10 +909,21 @@ void prog_makefile_rules(FILE *outmk, pr
     fprintf(outmk, "\t${LD} -dc -r -o %s.cro %s_stub.o $(%s_OBJPATHS)\n", 
 	    p->name, p->name, p->ident);
 #ifdef NEW_TOOLCHAIN
+#ifdef RENAME_SYMS
+    fprintf(outmk, "\t${NM} -ng %s.cro | grep -wv U | ", p->name);
+    fprintf(outmk, "egrep -vw _crunched_%s_stub | ", p->ident);
+    for (lst = p->keepsymbols; lst != NULL; lst = lst->next)
+	fprintf(outmk, "egrep -vw %s | ", lst->str);
+    fprintf(outmk, "env CRO=%s.cro awk "
+	"'{ print $$3 \" _$$$$hide$$$$\" ENVIRON[\"CRO\"] \"$$$$\" $$3 }' "
+	"> %s.cro.syms\n", p->name, p->name);
+    fprintf(outmk, "\t${OBJCOPY} --redefine-syms-file %s.cro.syms ", p->name);
+#else
     fprintf(outmk, "\t${OBJCOPY} --keep-global-symbol _crunched_%s_stub ",
   	    p->ident);
     for (lst = p->keepsymbols; lst != NULL; lst = lst->next)
 	fprintf(outmk, "--keep-global-symbol %s ", lst->str);
+#endif
 #else
     fprintf(outmk, "\t${CRUNCHIDE} -k _crunched_%s_stub ", p->ident);
     for (lst = p->keepsymbols; lst != NULL; lst = lst->next)

--Q68bSM7Ycu6FN28Q--