Index: objcopy.c =================================================================== RCS file: /cvs/src/src/binutils/objcopy.c,v retrieving revision 1.81 diff -u -r1.81 objcopy.c --- objcopy.c 25 Apr 2005 14:27:00 -0000 1.81 +++ objcopy.c 25 Apr 2005 23:27:41 -0000 @@ -50,6 +50,16 @@ struct redefine_node *next; }; +/* A list to support specific_redefine_sym */ +struct specific_redefine_node +{ + char *source; + char *target; + char *ofilename; + struct specific_redefine_node *next; +}; + + typedef struct section_rename { const char * old_name; @@ -199,6 +209,11 @@ static struct symlist *keepglobal_specific_list = NULL; static struct symlist *weaken_specific_list = NULL; static struct redefine_node *redefine_sym_list = NULL; +static struct specific_redefine_node *specific_redefine_sym_list = NULL; + + + + /* If this is TRUE, we weaken global symbols (set BSF_WEAK). */ static bfd_boolean weaken = FALSE; @@ -229,6 +244,7 @@ OPTION_STRIP_UNNEEDED, OPTION_WEAKEN, OPTION_REDEFINE_SYM, + OPTION_REDEFINE_SYM_SPECIFIC, OPTION_REDEFINE_SYMS, OPTION_SREC_LEN, OPTION_SREC_FORCES3, @@ -337,6 +353,7 @@ {"pure", no_argument, 0, OPTION_PURE}, {"readonly-text", no_argument, 0, OPTION_READONLY_TEXT}, {"redefine-sym", required_argument, 0, OPTION_REDEFINE_SYM}, + {"redefine-sym-specific", required_argument, 0, OPTION_REDEFINE_SYM_SPECIFIC}, {"redefine-syms", required_argument, 0, OPTION_REDEFINE_SYMS}, {"remove-leading-char", no_argument, 0, OPTION_REMOVE_LEADING_CHAR}, {"remove-section", required_argument, 0, 'R'}, @@ -394,6 +411,8 @@ static void mark_symbols_used_in_relocations (bfd *, asection *, void *); static bfd_boolean write_debugging_info (bfd *, void *, long *, asymbol ***); static const char *lookup_sym_redefinition (const char *); +static const char *lookup_specific_sym_redefinition (const char *, const char *); + static void copy_usage (FILE *stream, int exit_status) @@ -454,6 +473,9 @@ --redefine-sym = Redefine symbol name to \n\ --redefine-syms --redefine-sym for all symbol pairs \n\ listed in \n\ + --redefine-sym-specific := \n\ + Redefine symbol name to , only for \n\ + specific component of input archive file\n\ --srec-len Restrict the length of generated Srecords\n\ --srec-forceS3 Restrict the type of generated Srecords to S3\n\ --strip-symbols -N for all symbols listed in \n\ @@ -824,12 +846,26 @@ undefined = bfd_is_und_section (bfd_get_section (sym)); - if (redefine_sym_list) + if ( redefine_sym_list || specific_redefine_sym_list ) { - char *old_name, *new_name; + char *old_name, *new_name, *specific_new_name; old_name = (char *) bfd_asymbol_name (sym); new_name = (char *) lookup_sym_redefinition (old_name); + + if(specific_redefine_sym_list) + { + specific_new_name = (char *) lookup_specific_sym_redefinition + (old_name, bfd_get_filename(abfd)); + + if (strcmp(specific_new_name, old_name) != 0) + { + /* If there was a specific redefine for this .o file, */ + /* it will override the more general one. */ + new_name = specific_new_name; + } + } + bfd_asymbol_name (sym) = new_name; name = new_name; } @@ -1009,6 +1045,62 @@ *p = new_node; } + + +/* For specific redefinitions, find the redefined name of symbol SOURCE */ +/* for the specified ofile. */ + +static const char * +lookup_specific_sym_redefinition (const char *source, const char *ofilename) +{ + struct specific_redefine_node *list; + + for (list = specific_redefine_sym_list; list != NULL; list = list->next) + if (strcmp (source, list->source) == 0) + if (strcmp (ofilename, list->ofilename) == 0) + return list->target; + + return source; +} + + + + + +/* Add a node to a symbol specific redefine list. */ + +static void +specific_redefine_list_append (const char *cause, const char *source, const char *target, const char *ofilename) +{ + struct specific_redefine_node **p; + struct specific_redefine_node *list; + struct specific_redefine_node *new_node; + + + for (p = &specific_redefine_sym_list; (list = *p) != NULL; p = &list->next) + { + if (strcmp (source, list->source) == 0) + if (strcmp (ofilename, list->ofilename) == 0) + fatal (_("%s: Multiple redefinition of symbol \"%s\" for component \"%s\""), + cause, source, ofilename); + + if (strcmp (target, list->target) == 0) + if (strcmp (ofilename, list->ofilename) == 0) + fatal (_("%s: Symbol \"%s\" is target of more than one redefinition for component \"%s\""), + cause, source, ofilename); + } + + new_node = xmalloc (sizeof (struct specific_redefine_node)); + + new_node->source = strdup (source); + new_node->target = strdup (target); + new_node->ofilename = strdup (ofilename); + new_node->next = NULL; + + *p = new_node; +} + + /* Handle the --redefine-syms option. Read lines containing "old new" from the file, and add them to the symbol redefine list. */ @@ -1418,6 +1510,7 @@ || change_leading_char || remove_leading_char || redefine_sym_list + || specific_redefine_sym_list || weaken) { /* Mark symbols used in output relocations so that they @@ -1734,6 +1827,12 @@ bfd_boolean delete; do_copy: + if(specific_redefine_sym_list) + { + non_fatal(_("warning: --redefine-sym-specific used but input file '%s' is not an archive"), + input_filename); + } + /* bfd_get_target does not return the correct value until bfd_check_format succeeds. */ if (output_target == NULL) @@ -2820,6 +2919,53 @@ add_redefine_syms_file (optarg); break; + + case OPTION_REDEFINE_SYM_SPECIFIC: + { + /* Push this redefinition onto specific_redefine_symbol_list. */ + + int len; + const char *s; + const char *pair; + const char *nextarg; + char *source, *target; + char *ofilename; + + + pair = strchr(optarg, ':'); + if (pair == NULL) + fatal (_("bad format for %s"), "--redefine-sym-specific"); + + s = strchr (optarg, '='); + if (s == NULL) + fatal (_("bad format for %s"), "--redefine-sym-specific"); + + + len = pair - optarg; + ofilename = xmalloc (len + 1); + strncpy (ofilename, optarg, len); + ofilename[len] = '\0'; + + len = s - pair - 1; + source = xmalloc (len + 1); + strncpy (source, pair + 1, len); + source[len] = '\0'; + + nextarg = s + 1; + len = strlen (nextarg); + target = xmalloc (len + 1); + strcpy (target, nextarg); + + + specific_redefine_list_append ("--redefine-sym-specific", + source, target, ofilename); + + free (source); + free (target); + free (ofilename); + } + break; + case OPTION_SET_SECTION_FLAGS: { const char *s;