public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
From: Daniel Marques <marques@cs.cornell.edu>
To: binutils@sources.redhat.com
Subject: PATCH: objcopy.c: redefine-sym-specific for archive files
Date: Mon, 25 Apr 2005 23:31:00 -0000	[thread overview]
Message-ID: <426D7DB3.3080304@cs.cornell.edu> (raw)

[-- Attachment #1: Type: text/plain, Size: 1929 bytes --]

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.


[-- Attachment #2: newest_patch --]
[-- Type: text/plain, Size: 7163 bytes --]

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 *);
+
 \f
 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;

             reply	other threads:[~2005-04-25 23:31 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-04-25 23:31 Daniel Marques [this message]
2005-04-26 17:12 ` Nick Clifton
2005-04-26 19:11   ` Daniel Marques
2005-04-27  9:29     ` Nick Clifton
2005-04-27  9:37       ` Nick Clifton

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=426D7DB3.3080304@cs.cornell.edu \
    --to=marques@cs.cornell.edu \
    --cc=binutils@sources.redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).