* objcopy.c (redefine_list_append): Add an argument that
authorJason Thorpe <thorpej@netbsd.org>
Mon, 2 Jun 2003 14:45:13 +0000 (14:45 +0000)
committerJason Thorpe <thorpej@netbsd.org>
Mon, 2 Jun 2003 14:45:13 +0000 (14:45 +0000)
indicates the context from which this function is being
called.  Change all callers.
(copy_options): Add a new option, --redefine-syms.
(copy_usage): Document new option.
(copy_main): Handle the --redefine-syms option.
* doc/binutils.text (objcopy): Document new option.

binutils/ChangeLog
binutils/doc/binutils.texi
binutils/objcopy.c

index 85d4f9790118e9ecb05afb793da5b7f08fdc4f02..536d761ca42ce80673b210227e33bd7a478613f2 100644 (file)
@@ -1,3 +1,14 @@
+2003-06-02  Chris Demetriou  <cgd@broadcom.com>
+            Jason Thorpe  <thorpej@wasabisystems.com>
+
+       * objcopy.c (redefine_list_append): Add an argument that
+       indicates the context from which this function is being
+       called.  Change all callers.
+       (copy_options): Add a new option, --redefine-syms.
+       (copy_usage): Document new option.
+       (copy_main): Handle the --redefine-syms option.
+       * doc/binutils.text (objcopy): Document new option.
+
 2003-05-31  Richard Henderson  <rth@redhat.com>
 
        * readelf.c (byte_get_signed): New.
index f5f06e3e1e4ed24bfa6db3aa8d197d3c54bd4a44..9c12f780364ae9e9a6583deb498df0d0925774f3 100644 (file)
@@ -958,6 +958,7 @@ objcopy [@option{-F} @var{bfdname}|@option{--target=}@var{bfdname}]
         [@option{--change-leading-char} ] [@option{--remove-leading-char}]
         [@option{--srec-len=}@var{ival} ] [@option{--srec-forceS3}]
         [@option{--redefine-sym} @var{old}=@var{new} ]
+        [@option{--redefine-syms=}@var{filename} ]
         [@option{--weaken}]
         [@option{--keep-symbols=}@var{filename}]
         [@option{--strip-symbols=}@var{filename}]
@@ -1284,6 +1285,12 @@ Change the name of a symbol @var{old}, to @var{new}.  This can be useful
 when one is trying link two things together for which you have no
 source, and there are name collisions.
 
+@item --redefine-syms=@var{filename}
+Apply @option{--redefine-sym} to each symbol pair "@var{old} @var{new}"
+listed in the file @var{filename}.  @var{filename} is simply a flat file,
+with one symbol pair per line.  Line comments may be introduced by the hash
+character.  This option may be given more than once.
+
 @item --weaken
 Change all global symbols in the file to be weak.  This can be useful
 when building an object which will be linked against other objects using
index 27c844fbb75fdd15e42ccc055a1637406c4a02f3..68402e86bfba0e05849612f7753298a484bc72ad 100644 (file)
@@ -105,7 +105,7 @@ static int copy_main
 static const char *lookup_sym_redefinition
   PARAMS((const char *));
 static void redefine_list_append
-  PARAMS ((const char *, const char *));
+  PARAMS ((const char *, const char *, const char *));
 static const char * find_section_rename
   PARAMS ((bfd *, sec_ptr, flagword *));
 static void add_section_rename
@@ -263,7 +263,8 @@ static char *prefix_alloc_sections_string = 0;
 #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 (OPTION_REDEFINE_SYM + 1)
+#define OPTION_SREC_LEN (OPTION_REDEFINE_SYMS + 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)
@@ -350,6 +351,7 @@ static struct option copy_options[] =
   {"prefix-alloc-sections", required_argument, 0, OPTION_PREFIX_ALLOC_SECTIONS},
   {"preserve-dates", no_argument, 0, 'p'},
   {"redefine-sym", required_argument, 0, OPTION_REDEFINE_SYM},
+  {"redefine-syms", required_argument, 0, OPTION_REDEFINE_SYMS},
   {"remove-leading-char", no_argument, 0, OPTION_REMOVE_LEADING_CHAR},
   {"remove-section", required_argument, 0, 'R'},
   {"rename-section", required_argument, 0, OPTION_RENAME_SECTION},
@@ -444,6 +446,8 @@ 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>        --redefine-sym for all symbol pairs \n\
+                                     listed in <file>\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\
@@ -940,7 +944,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;
 {
@@ -952,13 +957,11 @@ 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);
     }
 
   new_node = (struct redefine_node *) xmalloc (sizeof (struct redefine_node));
@@ -970,6 +973,116 @@ redefine_list_append (source, target)
   *p = new_node;
 }
 
+/* Handle the --redefine-syms option.  Read lines containing "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;
+  outsym_off = 0;
+  while (c != EOF)
+    {
+      /* Collect the input symbol name.  */
+      while (! IS_WHITESPACE (c) && ! IS_LINE_TERMINATOR (c) && c != EOF)
+       {
+         if (c == '#')
+           goto comment;
+         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 (IS_WHITESPACE (c))
+       c = getc (file);
+      if (c == '#' || IS_LINE_TERMINATOR (c))
+       goto comment;
+      if (c == EOF)
+       break;
+
+      /* Collect the output symbol name.  */
+      outsym_off = len;
+      while (! IS_WHITESPACE (c) && ! IS_LINE_TERMINATOR (c) && c != EOF)
+       {
+         if (c == '#')
+           goto comment;
+         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 (! IS_LINE_TERMINATOR(c) && c != EOF && IS_WHITESPACE (c))
+       c = getc (file);
+      if (c == '#')
+       goto comment;
+      /* Handle \r\n.  */
+      if ((c == '\r' && (c = getc (file)) == '\n')
+         || c == '\n' || c == EOF)
+       {
+ end_of_line:
+         /* Append the redefinition to the list.  */
+         if (buf[0] != '\0')
+           redefine_list_append (filename, &buf[0], &buf[outsym_off]);
+
+         lineno++;     
+         len = 0;
+         outsym_off = 0;
+         if (c == EOF)
+           break;
+         c = getc (file);
+         continue;
+       }
+      else
+       fatal (_("%s: garbage at end of line %d"), filename, lineno);
+ comment:
+      if (len != 0 && (outsym_off == 0 || outsym_off == len))
+       fatal (_("%s: missing new symbol name at line %d"), filename, lineno);
+      buf[len++] = '\0';
+
+      /* Eat the rest of the line and finish it.  */
+      while (c != '\n' && c != EOF)
+       c = getc (file);
+      goto end_of_line;
+    }
+
+  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.  */
 
@@ -2547,13 +2660,17 @@ 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:
+         add_redefine_syms_file (optarg);
+         break;
+
        case OPTION_SET_SECTION_FLAGS:
          {
            const char *s;