This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
PATCH: objcopy.c: redefine-sym-specific for archive files
- From: Daniel Marques <marques at cs dot cornell dot edu>
- To: binutils at sources dot redhat dot com
- Date: Mon, 25 Apr 2005 19:30:59 -0400
- Subject: PATCH: objcopy.c: redefine-sym-specific for archive files
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 <objectfile>:<old>=<new>
Redefine symbol name <old> to <new>, only for
specific <objectfile> 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.
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 <old>=<new> Redefine symbol name <old> to <new>\n\
--redefine-syms <file> --redefine-sym for all symbol pairs \n\
listed in <file>\n\
+ --redefine-sym-specific <objectfile>:<old>=<new> \n\
+ Redefine symbol name <old> to <new>, only for \n\
+ specific <objectfile> component of input archive 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\
@@ -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;