This is the mail archive of the binutils@sourceware.cygnus.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]

Re: objcopy --redefine-sym


On Tue, 15 Feb 2000, Doug Evans wrote:

> [I didn't see any reference to it in the mailing list archives
> so I'm guessing it hasn't been submitted (recently at least).]

Attached is a version I've sanitized and rewritten in places.

-- 
Linuxcare.  Support for the Revolution.
binutils/ChangeLog
	from Matthew Benjamin <matt@linuxbox.nu>
	* objcopy.c (struct redefine_node): New.
	(redefine_sym_list): New.
	(redefine_list_append): New.
	(lookup_sym_redefinition): New.
	(OPTION_REDEFINE_SYM): New.
	(copy_options): Add --redefine-sym option.
	(copy_usage): Mention it.
	(filter_symbols): Rename symbols on redefine_sym_list.
	(copy_object): Call filter_symbols if redefine_sym_list != NULL.
	(copy_main): Add some white space.  Handle OPTION_REDEFINE_SYM.

--- binutils/objcopy.c.orig	Tue Apr  4 22:27:47 2000
+++ binutils/objcopy.c	Tue Apr  4 22:27:47 2000
@@ -38,6 +38,14 @@ struct symlist
   struct symlist *next;
 };
 
+/* A list to support redefine_sym.  */
+struct redefine_node
+{
+  char *source;
+  char *target;
+  struct redefine_node *next;
+};
+
 static void copy_usage PARAMS ((FILE *, int));
 static void strip_usage PARAMS ((FILE *, int));
 static flagword parse_flags PARAMS ((const char *));
@@ -60,6 +68,8 @@ static void copy_file
   PARAMS ((const char *, const char *, const char *, const char *));
 static int strip_main PARAMS ((int, char **));
 static int copy_main PARAMS ((int, char **));
+static const char *lookup_sym_redefinition PARAMS((const char *));
+static void redefine_list_append PARAMS ((const char *, const char *));
 
 #define RETURN_NONFATAL(s) {bfd_nonfatal (s); status = 1; return;}
 
@@ -172,12 +182,13 @@ static boolean change_leading_char = fal
 
 static boolean remove_leading_char = false;
 
-/* List of symbols to strip, keep, localize, and weaken.  */
+/* List of symbols to strip, keep, localize, weaken, or redefine.  */
 
 static struct symlist *strip_specific_list = NULL;
 static struct symlist *keep_specific_list = NULL;
 static struct symlist *localize_specific_list = NULL;
 static struct symlist *weaken_specific_list = NULL;
+static struct redefine_node *redefine_sym_list = NULL;
 
 /* If this is true, we weaken global symbols (set BSF_WEAK).  */
 
@@ -202,6 +213,7 @@ static boolean weaken = false;
 #define OPTION_SET_START (OPTION_SET_SECTION_FLAGS + 1)
 #define OPTION_STRIP_UNNEEDED (OPTION_SET_START + 1)
 #define OPTION_WEAKEN (OPTION_STRIP_UNNEEDED + 1)
+#define OPTION_REDEFINE_SYM (OPTION_WEAKEN + 1) 
 
 /* Options to handle if running as "strip".  */
 
@@ -276,6 +288,7 @@ static struct option copy_options[] =
   {"version", no_argument, 0, 'V'},
   {"weaken", no_argument, 0, OPTION_WEAKEN},
   {"weaken-symbol", required_argument, 0, 'W'},
+  {"redefine-sym", required_argument, 0, OPTION_REDEFINE_SYM},
   {0, no_argument, 0, 0}
 };
 
@@ -335,6 +348,7 @@ copy_usage (stream, exit_status)
      --add-section <name>=<file>   Add section <name> found in <file> to output\n\
      --change-leading-char         Force output format's leading character style\n\
      --remove-leading-char         Remove leading character from global symbols\n\
+     --redefine-sym <old>=<new>    Redefine symbol name <old> to <new>\n\
   -v --verbose                     List all object files modified\n\
   -V --version                     Display this program's version number\n\
   -h --help                        Display this output\n\
@@ -549,6 +563,15 @@ filter_symbols (abfd, obfd, osyms, isyms
       const char *name = bfd_asymbol_name (sym);
       int keep;
 
+      if (redefine_sym_list)
+	{
+	  const char *old_name, *new_name;
+
+	  old_name = bfd_asymbol_name (sym);
+	  new_name = lookup_sym_redefinition (old_name);
+	  name = bfd_asymbol_name (sym) = new_name;
+	}
+
       if (change_leading_char
 	  && (bfd_get_symbol_leading_char (abfd)
 	      != bfd_get_symbol_leading_char (obfd))
@@ -630,6 +653,66 @@ filter_symbols (abfd, obfd, osyms, isyms
   return dst_count;
 }
 
+static const char *
+lookup_sym_redefinition (source)
+     const char *source;
+{
+  const char *result;
+  struct redefine_node *list;
+
+  result = source;
+
+  for (list = redefine_sym_list; list != NULL; list = list->next)
+    {
+      if (strcmp (source, list->source) == 0)
+	{
+	  result = list->target;
+	  break;
+	}
+    }
+  return result;
+}
+
+/* Add a node to a symbol redefine list */
+
+static void
+redefine_list_append (source, target)
+     const char *source;
+     const char *target;
+{
+  struct redefine_node **p;
+  struct redefine_node *list;
+  struct redefine_node *new_node;
+
+  for (p = &redefine_sym_list; (list = *p) != NULL; p = &list->next)
+    {
+      if (strcmp (source, list->source) == 0)
+	{
+	  fprintf(stderr,
+		  "redefine-sym:  Multiple redefinition of symbol \"%s\"\n",
+		  source);
+	  exit (1);
+	}
+
+      if (strcmp (target, list->target) == 0)
+	{
+	  fprintf(stderr,
+		  "redefine-sym: Symbol \"%s\" is target of more than one redefinition",
+		  target);
+	  exit (1);
+	}
+    }
+
+  new_node = (struct redefine_node *) xmalloc (sizeof (struct redefine_node));
+
+  new_node->source = strdup (source);
+  new_node->target = strdup (target);
+  new_node->next = NULL;
+
+  *p = new_node;
+}
+
+
 /* Keep only every `copy_byte'th byte in MEMHUNK, which is *SIZE bytes long.
    Adjust *SIZE.  */
 
@@ -868,6 +951,7 @@ copy_object (ibfd, obfd)
       || convert_debugging
       || change_leading_char
       || remove_leading_char
+      || redefine_sym_list
       || weaken)
     {
       /* Mark symbols used in output relocations so that they
@@ -1720,22 +1804,27 @@ copy_main (argc, argv)
 	  if (copy_byte < 0)
 	    fatal (_("byte number must be non-negative"));
 	  break;
+
 	case 'i':
 	  interleave = atoi (optarg);
 	  if (interleave < 1)
 	    fatal (_("interleave must be positive"));
 	  break;
+
 	case 'I':
 	case 's':		/* "source" - 'I' is preferred */
 	  input_target = optarg;
 	  break;
+
 	case 'O':
 	case 'd':		/* "destination" - 'O' is preferred */
 	  output_target = optarg;
 	  break;
+
 	case 'F':
 	  input_target = output_target = optarg;
 	  break;
+
 	case 'j':
 	  p = find_section_list (optarg, true);
 	  if (p->remove)
@@ -1743,6 +1832,7 @@ copy_main (argc, argv)
 	  p->copy = true;
 	  sections_copied = true;
 	  break;
+
 	case 'R':
 	  p = find_section_list (optarg, true);
 	  if (p->copy)
@@ -1750,45 +1840,59 @@ copy_main (argc, argv)
 	  p->remove = true;
 	  sections_removed = true;
 	  break;
+
 	case 'S':
 	  strip_symbols = STRIP_ALL;
 	  break;
+
 	case 'g':
 	  strip_symbols = STRIP_DEBUG;
 	  break;
+
 	case OPTION_STRIP_UNNEEDED:
 	  strip_symbols = STRIP_UNNEEDED;
 	  break;
+
 	case 'K':
 	  add_specific_symbol (optarg, &keep_specific_list);
 	  break;
+
 	case 'N':
 	  add_specific_symbol (optarg, &strip_specific_list);
 	  break;
+
 	case 'L':
 	  add_specific_symbol (optarg, &localize_specific_list);
 	  break;
+
 	case 'W':
 	  add_specific_symbol (optarg, &weaken_specific_list);
 	  break;
+
 	case 'p':
 	  preserve_dates = true;
 	  break;
+
 	case 'x':
 	  discard_locals = LOCALS_ALL;
 	  break;
+
 	case 'X':
 	  discard_locals = LOCALS_START_L;
 	  break;
+
 	case 'v':
 	  verbose = true;
 	  break;
+
 	case 'V':
 	  show_version = true;
 	  break;
+
 	case OPTION_WEAKEN:
 	  weaken = true;
 	  break;
+
 	case OPTION_ADD_SECTION:
 	  {
 	    const char *s;
@@ -1834,9 +1938,11 @@ copy_main (argc, argv)
 	    add_sections = pa;
 	  }
 	  break;
+
 	case OPTION_CHANGE_START:
 	  change_start = parse_vma (optarg, "--change-start");
 	  break;
+
 	case OPTION_CHANGE_SECTION_ADDRESS:
 	case OPTION_CHANGE_SECTION_LMA:
 	case OPTION_CHANGE_SECTION_VMA:
@@ -1908,19 +2014,24 @@ copy_main (argc, argv)
 	      }
 	  }
 	  break;
+
 	case OPTION_CHANGE_ADDRESSES:
 	  change_section_address = parse_vma (optarg, "--change-addresses");
 	  change_start = change_section_address;
 	  break;
+
 	case OPTION_CHANGE_WARNINGS:
 	  change_warn = true;
 	  break;
+
 	case OPTION_CHANGE_LEADING_CHAR:
 	  change_leading_char = true;
 	  break;
+
 	case OPTION_DEBUGGING:
 	  convert_debugging = true;
 	  break;
+
 	case OPTION_GAP_FILL:
 	  {
 	    bfd_vma gap_fill_vma;
@@ -1939,16 +2050,54 @@ copy_main (argc, argv)
 	    gap_fill_set = true;
 	  }
 	  break;
+
 	case OPTION_NO_CHANGE_WARNINGS:
 	  change_warn = false;
 	  break;
+
 	case OPTION_PAD_TO:
 	  pad_to = parse_vma (optarg, "--pad-to");
 	  pad_to_set = true;
 	  break;
+
 	case OPTION_REMOVE_LEADING_CHAR:
 	  remove_leading_char = true;
 	  break;
+
+	case OPTION_REDEFINE_SYM:
+	  {
+	    /* Push this redefinition onto redefine_symbol_list.  */
+
+	    int len;
+	    const char *s;
+	    const char *nextarg;
+	    char *source, *target;
+
+	    s = strchr (optarg, '=');
+	    if (s == NULL)
+	      {
+		fprintf (stderr, "%s: bad format for --redefine-sym\n",
+			 program_name);
+		exit (1);
+	      }
+
+	    len = s - optarg;
+	    source = (char *) xmalloc (len + 1);
+	    strncpy (source, optarg, len);
+	    source[len] = '\0';
+
+	    nextarg = s + 1;
+	    len = strlen (nextarg);
+	    target = (char *) xmalloc (len + 1);
+	    strcpy (target, nextarg);
+
+	    redefine_list_append (source, target);
+
+	    free (source);
+	    free (target);
+	  }
+	  break;
+
 	case OPTION_SET_SECTION_FLAGS:
 	  {
 	    const char *s;
@@ -1970,14 +2119,18 @@ copy_main (argc, argv)
 	    p->flags = parse_flags (s + 1);
 	  }
 	  break;
+
 	case OPTION_SET_START:
 	  set_start = parse_vma (optarg, "--set-start");
 	  set_start_set = true;
 	  break;
+
 	case 0:
 	  break;		/* we've been given a long option */
+
 	case 'h':
 	  copy_usage (stdout, 0);
+
 	default:
 	  copy_usage (stderr, 1);
 	}

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