From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 32749 invoked by alias); 25 Apr 2005 23:31:07 -0000 Mailing-List: contact binutils-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: binutils-owner@sources.redhat.com Received: (qmail 32492 invoked from network); 25 Apr 2005 23:30:54 -0000 Received: from unknown (HELO exchfe1.cs.cornell.edu) (128.84.97.27) by sourceware.org with SMTP; 25 Apr 2005 23:30:54 -0000 Received: from exchfe2.cs.cornell.edu ([128.84.97.28]) by exchfe1.cs.cornell.edu with Microsoft SMTPSVC(6.0.3790.211); Mon, 25 Apr 2005 19:30:52 -0400 Received: from [128.84.99.47] ([128.84.99.47]) by exchfe2.cs.cornell.edu over TLS secured channel with Microsoft SMTPSVC(6.0.3790.211); Mon, 25 Apr 2005 19:30:45 -0400 Message-ID: <426D7DB3.3080304@cs.cornell.edu> Date: Mon, 25 Apr 2005 23:31:00 -0000 From: Daniel Marques User-Agent: Mozilla Thunderbird 0.8 (Windows/20040913) MIME-Version: 1.0 To: binutils@sources.redhat.com Subject: PATCH: objcopy.c: redefine-sym-specific for archive files Content-Type: multipart/mixed; boundary="------------050507010603050807060009" X-OriginalArrivalTime: 25 Apr 2005 23:30:45.0973 (UTC) FILETIME=[CE287850:01C549EE] X-SW-Source: 2005-04/txt/msg00690.txt.bz2 This is a multi-part message in MIME format. --------------050507010603050807060009 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Content-length: 1929 If an archive file (e.g. libc.a) consists of more than one object file (e.g, a.o & b.o) each containing a definition for a symbol named 'foo', objcopy --redefine-sym foo=bar libc.a will redefine both symbols. Example 1: [marques@c3linux objectdumps]$ nm libc.a a.o: 00000000 b foo b.o: 00000000 b foo [marques@c3linux objectdumps]$ objcopy --redefine-sym foo=bar libc.a [marques@c3linux objectdumps]$ nm libc.a a.o: 00000000 b bar b.o: 00000000 b bar This might not always be the desired behavior. The attached patch adds the --redefine-sym-specific option to object copy. Its usage is --redefine-sym-specific := Redefine symbol name to , only for specific component of input archive file This flag allows the user to specify that the redefinition should only affect the symbol in the specified 'component' (object file) of the archive. Example 2: [marques@c3linux objectdumps]$ nm libc.a a.o: 00000000 b foo b.o: 00000000 b foo [marques@c3linux objectdumps]$ objcopy --redefine-sym-specific a.o:foo=bar libc.a [marques@c3linux objectdumps]$ nm libc.a a.o: 00000000 b bar b.o: 00000000 b foo Notice that a specify redefine will always override a general override for the same symbol name Example 3: [marques@c3linux objectdumps]$ nm libc.a a.o: 00000000 b foo b.o: 00000000 b foo [marques@c3linux objectdumps]$ objcopy --redefine-sym foo=gnu --redefine-sym-specific a.o:foo=bar libc.a [marques@c3linux objectdumps]$ nm libc.a a.o: 00000000 b bar b.o: 00000000 b gnu I did not include a version for reading these from a file, as that would require either 'generalizing' add_redefine_syms_file() or 'cloning' that function, and I though such a decision should be left to the maintainers. Thanks. Dan P.S. Please cc me on reply, as I am not a subscriber to this list. --------------050507010603050807060009 Content-Type: text/plain; name="newest_patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="newest_patch" Content-length: 7163 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; --------------050507010603050807060009--