diff options
-rw-r--r-- | binutils/ChangeLog | 11 | ||||
-rw-r--r-- | binutils/doc/binutils.texi | 7 | ||||
-rw-r--r-- | binutils/objcopy.c | 133 |
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; |