aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--binutils/ChangeLog11
-rw-r--r--binutils/doc/binutils.texi7
-rw-r--r--binutils/objcopy.c133
3 files changed, 143 insertions, 8 deletions
diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index 85d4f97..536d761 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -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.
diff --git a/binutils/doc/binutils.texi b/binutils/doc/binutils.texi
index f5f06e3..9c12f78 100644
--- a/binutils/doc/binutils.texi
+++ b/binutils/doc/binutils.texi
@@ -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
diff --git a/binutils/objcopy.c b/binutils/objcopy.c
index 27c844f..68402e8 100644
--- a/binutils/objcopy.c
+++ b/binutils/objcopy.c
@@ -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;