This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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;

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]