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

Re: Adding options for redefining symbols


Thank you so much for the feedback.

I have adjusted the patch today, it now also supports reading
from files for only redefining already defined and undefined
respectively. The patch also now uses enums, more on that below.
As before, the original behavior when just using --redefine-sym[s]
is preserved, and the patch now adds the following options:

--redefine-defined-sym old=new
--redefine-undefined-sym old=new
--redefine-defined-syms <file>
--redefine-undefined-syms <file>

>    One final point - are you aware that in order to contribute a
>    patch like this you will need an FSF copyright assignment in
>    place ?

I am. Which one should I send? The one for minor changes right?
It should raise no problems since I am unemployed and between
music schools right now.

>    But you could achieve that with a small script inserted before calling
>    objcopy, and then there would be no need to patch anything.

Yes often, but this patch enables reverting symbol changes that results
in undefined and defined symbols in the same object file. I'll attach
some example code in this email which should clarify. The gist of it
is that in a scenario where a symbol is being both undefined and
defined in the same file, it is not possible to change only one of them.

In most cases this shouldn't be a problem as the scenario only exists
for object files which have already been changed, and reverting can
currently be accomplished by saving a backup of the old version or
(if one has access to the source) recompiling. This patch renders such
backups or recompilations unnecessary.

>    I would suggest that you use an enum here, rather than a char
>    and some magic numeric values.  It does make the patch slightly
>    larger, but also easier to read.

I have tried my best to do this and am attaching two versions now.
The first version should be as efficient as the one before; using
fallthroughs that change flags in the redefine_mode (attached
as "[...]_fallthroughs.diff"). The second is a tad slower but probably
more readable version that branches using gotos instead of switch
fallthroughs (attached as "[...]_gotos.diff").

In hope that this will clarify,
Ivan Morén

Onsdagen 26 juni 2019 kl 16:01 skrev Nick Clifton <nickc@redhat.com>:
>
> Hi Ivan,
>
>   First of all thank you for your interest in the binutils, and
>   posting this patch.
>
>
> > I found myself in need of redefining only the symbols that correspond
> > to defined functions, not the ones that are undefined declarations.
>
>   I have to say my immediate thought was "why bother ?".  There are
>   already --redefine-sym and --redefine-syms options, so why not use
>   those.  I can see you might want to have a check that the symbol
>   really is defined (or undefined) before changing it.  But you could
>   achieve that with a small script inserted before calling objcopy,
>   and then there would be no need to patch anything.
>
> >     - Is this kind of feature a feasable candidate?
>
>   Well yes and no.  Yes, it is feasible because you have already
>   written a patch that does it.  But no, because as mentioned above
>   it might be possible to achieve the same goal without needing to
>   patch anything.
>
> >     - Setting redefine_mode uses switch fallthroughs, is this a
> > readability no-no?
>
>   Nope that is fine.
>
> >     - Do I need to find similar alternatives for "--redefine-syms=<filename>"?
>
>   For consistency's sake I would say yes.  There is a limit on
>   the length of a command line, and if the feature needs to be
>   used for lots of symbols, then having this alternative would
>   be really useful.
>
> > Example usage, first redefining for using implementation_a, then
> > changing the same object file to instead use implementation_b:
> >
> >     $ objcopy --redefine-sym implementation_a=do_work
> >     $ objcopy --redefine-defined-sym do_work=implementation_a
> > --redefine-sym implementation_b=do_work
>
>   Now this confuses me.  The first command line makes sense, but
>   the second one appears to say "rename function 'do_work' to be
>   called 'implementation_a' and rename function 'implementation_b'
>   to be called 'do_work'".  But this does not match your description
>   of using implementation_b.
>
>
>   I also have a comment on the patch itself:
>
>     +  char mode;
>
>   I would suggest that you use an enum here, rather than a char
>   and some magic numeric values.  It does make the patch slightly
>   larger, but also easier to read.
>
>   One final point - are you aware that in order to contribute a
>   patch like this you will need an FSF copyright assignment in
>   place ?
>
> Cheers
>   Nick
diff --git a/binutils/objcopy.c b/binutils/objcopy.c
index 28b9d3bf92..08c1674eb6 100644
--- a/binutils/objcopy.c
+++ b/binutils/objcopy.c
@@ -54,11 +54,28 @@ struct is_specified_symbol_predicate_data
   bfd_boolean	found;
 };
 
+#define REDEFINE_FLAGS_COUNT (2)
+enum redefine_mode_flags
+{
+  REDEFINE_FLAGS_DEFINED   = 1 << 0,
+  REDEFINE_FLAGS_UNDEFINED = 1 << 1,
+  REDEFINE_FLAGS_BOTH     = REDEFINE_FLAGS_DEFINED | REDEFINE_FLAGS_UNDEFINED
+};
+enum redefine_mode
+{
+  REDEFINE_DEFINED   = REDEFINE_FLAGS_DEFINED,
+  REDEFINE_UNDEFINED = ((REDEFINE_DEFINED << REDEFINE_FLAGS_COUNT)
+			| REDEFINE_FLAGS_UNDEFINED),
+  REDEFINE_BOTH      = ((REDEFINE_UNDEFINED << REDEFINE_FLAGS_COUNT)
+			| REDEFINE_FLAGS_BOTH)
+};
+
 /* A node includes symbol name mapping to support redefine_sym.  */
 struct redefine_node
 {
   char *source;
   char *target;
+  enum redefine_mode mode;
 };
 
 struct addsym_node
@@ -339,7 +356,11 @@ enum command_line_switch
   OPTION_PURE,
   OPTION_READONLY_TEXT,
   OPTION_REDEFINE_SYM,
+  OPTION_REDEFINE_DEFINED_SYM,
+  OPTION_REDEFINE_UNDEFINED_SYM,
   OPTION_REDEFINE_SYMS,
+  OPTION_REDEFINE_DEFINED_SYMS,
+  OPTION_REDEFINE_UNDEFINED_SYMS,
   OPTION_REMOVE_LEADING_CHAR,
   OPTION_REMOVE_RELOCS,
   OPTION_RENAME_SECTION,
@@ -470,7 +491,11 @@ static struct option copy_options[] =
   {"pure", no_argument, 0, OPTION_PURE},
   {"readonly-text", no_argument, 0, OPTION_READONLY_TEXT},
   {"redefine-sym", required_argument, 0, OPTION_REDEFINE_SYM},
+  {"redefine-defined-sym", required_argument, 0, OPTION_REDEFINE_DEFINED_SYM},
+  {"redefine-undefined-sym", required_argument, 0, OPTION_REDEFINE_UNDEFINED_SYM},
   {"redefine-syms", required_argument, 0, OPTION_REDEFINE_SYMS},
+  {"redefine-defined-syms", required_argument, 0, OPTION_REDEFINE_DEFINED_SYMS},
+  {"redefine-undefined-syms", required_argument, 0, OPTION_REDEFINE_UNDEFINED_SYMS},
   {"remove-leading-char", no_argument, 0, OPTION_REMOVE_LEADING_CHAR},
   {"remove-section", required_argument, 0, 'R'},
   {"remove-relocations", required_argument, 0, OPTION_REMOVE_RELOCS},
@@ -535,7 +560,7 @@ static void get_sections (bfd *, asection *, void *);
 static int compare_section_lma (const void *, const void *);
 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_sym_redefinition (const char *, const enum redefine_mode_flags);
 static const char *find_section_rename (const char *, flagword *);
 
 ATTRIBUTE_NORETURN static void
@@ -1508,9 +1533,11 @@ filter_symbols (bfd *abfd, bfd *obfd, asymbol **osyms,
 
       if (htab_elements (redefine_specific_htab) || section_rename_list)
 	{
+	  enum redefine_mode_flags mode_flags;
 	  char *new_name;
 
-	  new_name = (char *) lookup_sym_redefinition (name);
+	  mode_flags = undefined ? REDEFINE_FLAGS_UNDEFINED : REDEFINE_FLAGS_DEFINED;
+	  new_name = (char *) lookup_sym_redefinition (name, mode_flags);
 	  if (new_name == name
 	      && (flags & BSF_SECTION_SYM) != 0)
 	    new_name = (char *) find_section_rename (name, NULL);
@@ -1690,26 +1717,29 @@ filter_symbols (bfd *abfd, bfd *obfd, asymbol **osyms,
 /* Find the redefined name of symbol SOURCE.  */
 
 static const char *
-lookup_sym_redefinition (const char *source)
+lookup_sym_redefinition (const char *source, const enum redefine_mode_flags flags)
 {
-  struct redefine_node key_node = {(char *) source, NULL};
+  struct redefine_node key_node = {(char *) source, NULL, REDEFINE_BOTH};
   struct redefine_node *redef_node
     = (struct redefine_node *) htab_find (redefine_specific_htab, &key_node);
 
-  return redef_node == NULL ? source : redef_node->target;
+  return ((redef_node != NULL && redef_node->mode & flags)
+	  ? redef_node->target
+	  : source);
 }
 
 /* Insert a node into symbol redefine hash tabel.  */
 
 static void
 add_redefine_and_check (const char *cause, const char *source,
-			const char *target)
+			const char *target, const enum redefine_mode mode)
 {
   struct redefine_node *new_node
     = (struct redefine_node *) xmalloc (sizeof (struct redefine_node));
 
   new_node->source = strdup (source);
   new_node->target = strdup (target);
+  new_node->mode   = mode;
 
   if (htab_find (redefine_specific_htab, new_node) != HTAB_EMPTY_ENTRY)
     fatal (_("%s: Multiple redefinition of symbol \"%s\""),
@@ -1732,7 +1762,7 @@ add_redefine_and_check (const char *cause, const char *source,
    from the file, and add them to the symbol redefine list.  */
 
 static void
-add_redefine_syms_file (const char *filename)
+add_redefine_syms_file (const char *filename, const enum redefine_mode mode)
 {
   FILE *file;
   char *buf;
@@ -1810,7 +1840,7 @@ add_redefine_syms_file (const char *filename)
 	end_of_line:
 	  /* Append the redefinition to the list.  */
 	  if (buf[0] != '\0')
-	    add_redefine_and_check (filename, &buf[0], &buf[outsym_off]);
+	    add_redefine_and_check (filename, &buf[0], &buf[outsym_off], mode);
 
 	  lineno++;
 	  len = 0;
@@ -4805,6 +4835,7 @@ copy_main (int argc, char *argv[])
   int c;
   struct stat statbuf;
   const bfd_arch_info_type *input_arch = NULL;
+  enum redefine_mode redefine_mode = REDEFINE_BOTH;
 
   while ((c = getopt_long (argc, argv, "b:B:i:I:j:K:MN:s:O:d:F:L:G:R:SpgxXHhVvW:wDU",
 			   copy_options, (int *) 0)) != EOF)
@@ -5208,6 +5239,12 @@ copy_main (int argc, char *argv[])
 	  remove_leading_char = TRUE;
 	  break;
 
+	case OPTION_REDEFINE_DEFINED_SYM:
+	  redefine_mode >>= REDEFINE_FLAGS_COUNT;
+	  __attribute__((fallthrough));
+	case OPTION_REDEFINE_UNDEFINED_SYM:
+	  redefine_mode >>= REDEFINE_FLAGS_COUNT;
+	  __attribute__((fallthrough));
 	case OPTION_REDEFINE_SYM:
 	  {
 	    /* Insert this redefinition onto redefine_specific_htab.  */
@@ -5231,15 +5268,25 @@ copy_main (int argc, char *argv[])
 	    target = (char *) xmalloc (len + 1);
 	    strcpy (target, nextarg);
 
-	    add_redefine_and_check ("--redefine-sym", source, target);
+	    add_redefine_and_check ("--redefine-sym", source, target, redefine_mode);
 
+	    redefine_mode = REDEFINE_BOTH;
 	    free (source);
 	    free (target);
 	  }
 	  break;
 
+	case OPTION_REDEFINE_DEFINED_SYMS:
+	  redefine_mode >>= REDEFINE_FLAGS_COUNT;
+	  __attribute__((fallthrough));
+	case OPTION_REDEFINE_UNDEFINED_SYMS:
+	  redefine_mode >>= REDEFINE_FLAGS_COUNT;
+	  __attribute__((fallthrough));
 	case OPTION_REDEFINE_SYMS:
-	  add_redefine_syms_file (optarg);
+	  {
+	    add_redefine_syms_file (optarg, redefine_mode);
+	    redefine_mode = REDEFINE_BOTH;
+	  }
 	  break;
 
 	case OPTION_SET_SECTION_FLAGS:
diff --git a/binutils/objcopy.c b/binutils/objcopy.c
index 28b9d3bf92..3180ed8734 100644
--- a/binutils/objcopy.c
+++ b/binutils/objcopy.c
@@ -54,11 +54,19 @@ struct is_specified_symbol_predicate_data
   bfd_boolean	found;
 };
 
+enum redefine_mode
+{
+  REDEFINE_DEFINED   = 1 << 0,
+  REDEFINE_UNDEFINED = 1 << 1,
+  REDEFINE_BOTH	   = REDEFINE_DEFINED | REDEFINE_UNDEFINED
+};
+
 /* A node includes symbol name mapping to support redefine_sym.  */
 struct redefine_node
 {
   char *source;
   char *target;
+  enum redefine_mode mode;
 };
 
 struct addsym_node
@@ -339,7 +347,11 @@ enum command_line_switch
   OPTION_PURE,
   OPTION_READONLY_TEXT,
   OPTION_REDEFINE_SYM,
+  OPTION_REDEFINE_DEFINED_SYM,
+  OPTION_REDEFINE_UNDEFINED_SYM,
   OPTION_REDEFINE_SYMS,
+  OPTION_REDEFINE_DEFINED_SYMS,
+  OPTION_REDEFINE_UNDEFINED_SYMS,
   OPTION_REMOVE_LEADING_CHAR,
   OPTION_REMOVE_RELOCS,
   OPTION_RENAME_SECTION,
@@ -470,7 +482,11 @@ static struct option copy_options[] =
   {"pure", no_argument, 0, OPTION_PURE},
   {"readonly-text", no_argument, 0, OPTION_READONLY_TEXT},
   {"redefine-sym", required_argument, 0, OPTION_REDEFINE_SYM},
+  {"redefine-defined-sym", required_argument, 0, OPTION_REDEFINE_DEFINED_SYM},
+  {"redefine-undefined-sym", required_argument, 0, OPTION_REDEFINE_UNDEFINED_SYM},
   {"redefine-syms", required_argument, 0, OPTION_REDEFINE_SYMS},
+  {"redefine-defined-syms", required_argument, 0, OPTION_REDEFINE_DEFINED_SYMS},
+  {"redefine-undefined-syms", required_argument, 0, OPTION_REDEFINE_UNDEFINED_SYMS},
   {"remove-leading-char", no_argument, 0, OPTION_REMOVE_LEADING_CHAR},
   {"remove-section", required_argument, 0, 'R'},
   {"remove-relocations", required_argument, 0, OPTION_REMOVE_RELOCS},
@@ -535,7 +551,7 @@ static void get_sections (bfd *, asection *, void *);
 static int compare_section_lma (const void *, const void *);
 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_sym_redefinition (const char *, const enum redefine_mode);
 static const char *find_section_rename (const char *, flagword *);
 
 ATTRIBUTE_NORETURN static void
@@ -1508,9 +1524,11 @@ filter_symbols (bfd *abfd, bfd *obfd, asymbol **osyms,
 
       if (htab_elements (redefine_specific_htab) || section_rename_list)
 	{
+	  enum redefine_mode mode_flags;
 	  char *new_name;
 
-	  new_name = (char *) lookup_sym_redefinition (name);
+	  mode_flags = undefined ? REDEFINE_UNDEFINED : REDEFINE_DEFINED;
+	  new_name = (char *) lookup_sym_redefinition (name, mode_flags);
 	  if (new_name == name
 	      && (flags & BSF_SECTION_SYM) != 0)
 	    new_name = (char *) find_section_rename (name, NULL);
@@ -1690,26 +1708,29 @@ filter_symbols (bfd *abfd, bfd *obfd, asymbol **osyms,
 /* Find the redefined name of symbol SOURCE.  */
 
 static const char *
-lookup_sym_redefinition (const char *source)
+lookup_sym_redefinition (const char *source, const enum redefine_mode flags)
 {
-  struct redefine_node key_node = {(char *) source, NULL};
+  struct redefine_node key_node = {(char *) source, NULL, REDEFINE_BOTH};
   struct redefine_node *redef_node
     = (struct redefine_node *) htab_find (redefine_specific_htab, &key_node);
 
-  return redef_node == NULL ? source : redef_node->target;
+  return ((redef_node != NULL && redef_node->mode & flags)
+	  ? redef_node->target
+	  : source);
 }
 
 /* Insert a node into symbol redefine hash tabel.  */
 
 static void
 add_redefine_and_check (const char *cause, const char *source,
-			const char *target)
+			const char *target, const enum redefine_mode mode)
 {
   struct redefine_node *new_node
     = (struct redefine_node *) xmalloc (sizeof (struct redefine_node));
 
   new_node->source = strdup (source);
   new_node->target = strdup (target);
+  new_node->mode   = mode;
 
   if (htab_find (redefine_specific_htab, new_node) != HTAB_EMPTY_ENTRY)
     fatal (_("%s: Multiple redefinition of symbol \"%s\""),
@@ -1732,7 +1753,7 @@ add_redefine_and_check (const char *cause, const char *source,
    from the file, and add them to the symbol redefine list.  */
 
 static void
-add_redefine_syms_file (const char *filename)
+add_redefine_syms_file (const char *filename, const enum redefine_mode mode)
 {
   FILE *file;
   char *buf;
@@ -1810,7 +1831,7 @@ add_redefine_syms_file (const char *filename)
 	end_of_line:
 	  /* Append the redefinition to the list.  */
 	  if (buf[0] != '\0')
-	    add_redefine_and_check (filename, &buf[0], &buf[outsym_off]);
+	    add_redefine_and_check (filename, &buf[0], &buf[outsym_off], mode);
 
 	  lineno++;
 	  len = 0;
@@ -4805,6 +4826,7 @@ copy_main (int argc, char *argv[])
   int c;
   struct stat statbuf;
   const bfd_arch_info_type *input_arch = NULL;
+  enum redefine_mode redefine_mode;
 
   while ((c = getopt_long (argc, argv, "b:B:i:I:j:K:MN:s:O:d:F:L:G:R:SpgxXHhVvW:wDU",
 			   copy_options, (int *) 0)) != EOF)
@@ -5208,7 +5230,15 @@ copy_main (int argc, char *argv[])
 	  remove_leading_char = TRUE;
 	  break;
 
+	case OPTION_REDEFINE_DEFINED_SYM:
+	  redefine_mode = REDEFINE_DEFINED;
+	  goto add_redefine_sym;
+	case OPTION_REDEFINE_UNDEFINED_SYM:
+	  redefine_mode = REDEFINE_UNDEFINED;
+	  goto add_redefine_sym;
 	case OPTION_REDEFINE_SYM:
+	  redefine_mode = REDEFINE_BOTH;
+	add_redefine_sym:
 	  {
 	    /* Insert this redefinition onto redefine_specific_htab.  */
 
@@ -5231,15 +5261,23 @@ copy_main (int argc, char *argv[])
 	    target = (char *) xmalloc (len + 1);
 	    strcpy (target, nextarg);
 
-	    add_redefine_and_check ("--redefine-sym", source, target);
+	    add_redefine_and_check ("--redefine-sym", source, target, redefine_mode);
 
 	    free (source);
 	    free (target);
 	  }
 	  break;
 
+	case OPTION_REDEFINE_DEFINED_SYMS:
+	  redefine_mode = REDEFINE_DEFINED;
+	  goto add_redefine_syms;
+	case OPTION_REDEFINE_UNDEFINED_SYMS:
+	  redefine_mode = REDEFINE_UNDEFINED;
+	  goto add_redefine_syms;
 	case OPTION_REDEFINE_SYMS:
-	  add_redefine_syms_file (optarg);
+	  redefine_mode = REDEFINE_BOTH;
+	add_redefine_syms:
+	  add_redefine_syms_file (optarg, redefine_mode);
 	  break;
 
 	case OPTION_SET_SECTION_FLAGS:
#include <stdio.h>

void call_symbol(const char *);

int main(int argc, const char *argv[])
{
    while (argc--) call_symbol(argv[argc]);
    return 0;
}

void impl_symbol_1(const char *s)
{
    printf("[[ %s ]]\n", s);
    return;
}

void impl_symbol_2(const char *s)
{
    printf("::    %s\n", s);
    return;
}

 → gcc -c main.c
 → objdump -t main.o | egrep '(call|impl)'
0000000000000000         *UND*  0000000000000000 call_symbol
0000000000000044 g     F .text  0000000000000027 impl_symbol_1
000000000000006b g     F .text  0000000000000027 impl_symbol_2
 → export use_1="impl_symbol_1=call_symbol"\
          use_2="impl_symbol_2=call_symbol"\
          revert_1="call_symbol=impl_symbol_1"\
          revert_2="call_symbol=impl_symbol_2"

 → objcopy --redefine-sym $use_1 main.o
 → objdump -t main.o | egrep '(call|impl)'
0000000000000000         *UND*  0000000000000000 call_symbol
0000000000000044 g     F .text  0000000000000027 call_symbol
000000000000006b g     F .text  0000000000000027 impl_symbol_2
 → gcc main.o
 → ./a.out 1 2
[[ 2 ]]
[[ 1 ]]
[[ ./a.out ]]
 → objcopy --redefine-defined-sym $revert_1 main.o
 → objdump -t main.o | egrep '(call|impl)'
0000000000000000         *UND*  0000000000000000 call_symbol
0000000000000044 g     F .text  0000000000000027 impl_symbol_1
000000000000006b g     F .text  0000000000000027 impl_symbol_2
 → objcopy --redefine-defined-sym $use_2 main.o
 → objdump -t main.o | egrep '(call|impl)'
0000000000000000         *UND*  0000000000000000 call_symbol
0000000000000044 g     F .text  0000000000000027 impl_symbol_1
000000000000006b g     F .text  0000000000000027 call_symbol
 → gcc main.o
 → ./a.out one two
::    two
::    one
::    ./a.out
 →

# Example of objcopy --redefine-defined-sym[s]

This example shows a scenario where the patched
version of objcopy allows the user to revert a
redefined symbol without affecting the undefined
target symbol that got defined during linking.
See the difference when using the patch by 
comparing the following files:

        "session_using_patch.log"
        "session_without_patch.log"

## Steps using the patched objcopy

Compile the source:

        gcc -c main.c

Prepare some shorthands

        export use_1="impl_symbol_1=call_symbol"\
               use_2="impl_symbol_2=call_symbol"\
               revert_1="call_symbol=impl_symbol_1"\
               revert_2="call_symbol=impl_symbol_2"

Link it, altered to use implementation 1:

        objcopy --redefine-sym $use_1 main.o
        gcc main.o
        ./a.out some arguments

Revert the change and instead use implementation 2:

        objcopy --redefine-defined-sym $revert_1\
                --redefine-sym $use_2\
                main.o
        gcc main.o
        ./a.out some arguments

## What happens when not using the patch

When diff:ing the provided sessions against each other,
the differences are small. What happens in the session
that does not make use of the patch is as follows:

1. When trying to revert the use of the first 
   implementation using a normal --redefine-sym, the
   declaration for the calling function also changes.
2. Changing the second implementation routes it to the
   original caller symbol name.
3. This results in the same function being called under
   another symbol name, and the implementation with the
   original caller symbol name to be unused.

Which is why the same implementation is used both times
the program is run.

 → gcc -c main.c
 → objdump -t main.o | egrep '(call|impl)'
0000000000000000         *UND*  0000000000000000 call_symbol
0000000000000044 g     F .text  0000000000000027 impl_symbol_1
000000000000006b g     F .text  0000000000000027 impl_symbol_2
 → export use_1="impl_symbol_1=call_symbol"\
          use_2="impl_symbol_2=call_symbol"\
          revert_1="call_symbol=impl_symbol_1"\
          revert_2="call_symbol=impl_symbol_2"

 → objcopy --redefine-sym $use_1 main.o
 → objdump -t main.o | egrep '(call|impl)'
0000000000000000         *UND*  0000000000000000 call_symbol
0000000000000044 g     F .text  0000000000000027 call_symbol
000000000000006b g     F .text  0000000000000027 impl_symbol_2
 → gcc main.o
 → ./a.out 1 2
[[ 2 ]]
[[ 1 ]]
[[ ./a.out ]]
 → objcopy --redefine-sym $revert_1 main.o
 → objdump -t main.o | egrep '(call|impl)'
0000000000000000         *UND*  0000000000000000 impl_symbol_1
0000000000000044 g     F .text  0000000000000027 impl_symbol_1
000000000000006b g     F .text  0000000000000027 impl_symbol_2
 → objcopy --redefine-sym $use_2 main.o
 → objdump -t main.o | egrep '(call|impl)'
0000000000000000         *UND*  0000000000000000 impl_symbol_1
0000000000000044 g     F .text  0000000000000027 impl_symbol_1
000000000000006b g     F .text  0000000000000027 call_symbol
 → gcc main.o
 → ./a.out one two
[[ two ]]
[[ one ]]
[[ ./a.out ]]
 →


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