[PATCH] new option for objcopy: --keep-global-symbol

hhonda@kobe-catv.ne.jp hhonda@kobe-catv.ne.jp
Sat May 19 07:47:00 GMT 2001


Hi, all.

I propose a new option for `objcopy'.

Existing options:
  -N <name>, --strip-symbol=<name>
    Strip symbol <name>.
  -K <name>, --keep-symbol=<name>
    Strip all symbols except <name>.
  -L <name>, --localize-symbol=<name>
    Localize symbol <name>.
  -W <name>, --weaken-symbol=<name>
    Weaken symbol <name>.

A new option:
  -G <name>, --keep-global-symbol=<name>
    Localize all symbols except <name>.

Furthermore, I propose a series of convenience options.
  --strip-symbols=<file>
    Apply `-N' option to each symbol listed in <file>.
  --keep-symbols=<file>
    Apply `-K' option to each symbol listed in <file>.
  --localize-symbols=<file>
    Apply `-L' option to each symbol listed in <file>.
  --keep-global-symbols=<file>
    Apply `-G' option to each symbol listed in <file>.
  --weaken-symbols=<file>
    Apply `-W' option to each symbol listed in <file>.

================================================================

The motivation of my proposal is as follows.

Suppose a source code directory tree which looks like:
    project --+-- system --+-- main.c
              |            +-- sub.c
              +-- libfoo --+-- foo1.c : foo_init(), foo_doit()
              |            +-- foo2.c : subroutine1(), subroutine2()
              +-- libbar --+-- bar1.c : bar_init(), bar_doit()
                           +-- bar2.c : subroutine1(), subroutine2()
Now look at `libfoo' directory.  It has four global symbols (foo_init,
foo_doit, subroutine1, subroutine2), but we want to export only the
former two (foo_init, foo_doit).  So we write project/libfoo/Makefile
as follows.
  all: all-in-one.o
        @
  all-in-one.o: foo1.o foo2.o
        ld -r -o all-in-one.o foo1.o foo2.o
        objcopy -G foo_init -G foo_doit all-in-one.o
If libfoo has many export symbols, we'd better write a text file
listing those symbols and use `--keep-global-symbols' option in the
Makefile.
  all-in-one.o: foo1.o foo2.o exports.txt
        ld -r -o all-in-one.o foo1.o foo2.o
        objcopy --keep-global-symbols=exports.txt all-in-one.o

If we apply the above convention for all directories (system, libfoo
and libbar), we can write the top makefile (project/Makefile)
concisely.
  DIRS := system libfoo libbar
  OBJS := $(addsuffix /all-in-one.o, $(DIRS))
  FORCEDIRS := $(addprefix force-, $(DIRS))
  a.out: $(FORCEDIRS)
        cc -o a.out $(OBJS)
  $(FORCEDIRS) : force-% : FORCE
        cd $* && $(MAKE) all
  FORCE:

================================================================

Here is a patch to binutils-2.11.

I am using the patched `objcopy' in a "--host=i686-pc-linux-gnu 
--target=mipstx39-elf32" environment, which seems to be correctly
working.

Is there any moderator who will verify and commit this patch?

HONDA Hiroki (hhonda@kobe-catv.ne.jp)

--- binutils-2.11/binutils/objcopy.c.orig	Thu Jan 18 09:17:43 2001
+++ binutils-2.11/binutils/objcopy.c	Sat May 12 16:40:50 2001
@@ -56,6 +56,7 @@ static void copy_section PARAMS ((bfd *,
 static void get_sections PARAMS ((bfd *, asection *, PTR));
 static int compare_section_lma PARAMS ((const PTR, const PTR));
 static void add_specific_symbol PARAMS ((const char *, struct symlist **));
+static void add_specific_symbols PARAMS ((const char *, struct symlist **));
 static boolean is_specified_symbol PARAMS ((const char *, struct symlist *));
 static boolean is_strip_section PARAMS ((bfd *, asection *));
 static unsigned int filter_symbols
@@ -183,11 +184,13 @@ static boolean change_leading_char = fal
 
 static boolean remove_leading_char = false;
 
-/* List of symbols to strip, keep, localize, weaken, or redefine.  */
+/* List of symbols to strip, keep, localize, keep-global, 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 *keepglobal_specific_list = NULL;
 static struct symlist *weaken_specific_list = NULL;
 static struct redefine_node *redefine_sym_list = NULL;
 
@@ -217,6 +220,11 @@ static boolean weaken = false;
 #define OPTION_REDEFINE_SYM (OPTION_WEAKEN + 1)
 #define OPTION_SREC_LEN (OPTION_REDEFINE_SYM + 1)
 #define OPTION_SREC_FORCES3 (OPTION_SREC_LEN + 1)
+#define OPTION_STRIP_SYMBOLS (OPTION_SREC_FORCES3 + 1)
+#define OPTION_KEEP_SYMBOLS (OPTION_STRIP_SYMBOLS + 1)
+#define OPTION_LOCALIZE_SYMBOLS (OPTION_KEEP_SYMBOLS + 1)
+#define OPTION_KEEPGLOBAL_SYMBOLS (OPTION_LOCALIZE_SYMBOLS + 1)
+#define OPTION_WEAKEN_SYMBOLS (OPTION_KEEPGLOBAL_SYMBOLS + 1)
 
 /* Options to handle if running as "strip".  */
 
@@ -278,6 +286,7 @@ static struct option copy_options[] =
   {"pad-to", required_argument, 0, OPTION_PAD_TO},
   {"preserve-dates", no_argument, 0, 'p'},
   {"localize-symbol", required_argument, 0, 'L'},
+  {"keep-global-symbol", required_argument, 0, 'G'},
   {"remove-leading-char", no_argument, 0, OPTION_REMOVE_LEADING_CHAR},
   {"remove-section", required_argument, 0, 'R'},
   {"set-section-flags", required_argument, 0, OPTION_SET_SECTION_FLAGS},
@@ -294,6 +303,11 @@ static struct option copy_options[] =
   {"redefine-sym", required_argument, 0, OPTION_REDEFINE_SYM},
   {"srec-len", required_argument, 0, OPTION_SREC_LEN},
   {"srec-forceS3", no_argument, 0, OPTION_SREC_FORCES3},
+  {"keep-symbols", required_argument, 0, OPTION_KEEP_SYMBOLS},
+  {"strip-symbols", required_argument, 0, OPTION_STRIP_SYMBOLS},
+  {"keep-global-symbols", required_argument, 0, OPTION_KEEPGLOBAL_SYMBOLS},
+  {"localize-symbols", required_argument, 0, OPTION_LOCALIZE_SYMBOLS},
+  {"weaken-symbols", required_argument, 0, OPTION_WEAKEN_SYMBOLS},
   {0, no_argument, 0, 0}
 };
 
@@ -335,6 +349,7 @@ copy_usage (stream, exit_status)
   -N --strip-symbol <name>         Do not copy symbol <name>\n\
   -K --keep-symbol <name>          Only copy symbol <name>\n\
   -L --localize-symbol <name>      Force symbol <name> to be marked as a local\n\
+  -G --keep-global-symbol <name>   Localize all symbols except <name>\n\
   -W --weaken-symbol <name>        Force symbol <name> to be marked as a weak\n\
      --weaken                      Force all global symbols to be marked as weak\n\
   -x --discard-all                 Remove all non-global symbols\n\
@@ -364,6 +379,11 @@ copy_usage (stream, exit_status)
      --redefine-sym <old>=<new>    Redefine symbol name <old> to <new>\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\
+     --keep-symbols <file>         -K for all symbols listed in <file>\n\
+     --localize-symbols <file>     -L for all symbols listed in <file>\n\
+     --keep-global-symbols <file>  -G for all symbols listed in <file>\n\
+     --weaken-symbols <file>       -W for all symbols listed in <file>\n\
   -v --verbose                     List all object files modified\n\
   -V --version                     Display this program's version number\n\
   -h --help                        Display this output\n\
@@ -512,6 +532,43 @@ add_specific_symbol (name, list)
   *list = tmp_list;
 }
 
+/* Add symbols listed in `filename' to strip_specific_list. */
+
+static void
+add_specific_symbols (filename, list)
+     const char *filename;
+     struct symlist **list;
+{
+  struct stat st;
+  FILE *f;
+  char *p;
+  if (stat (filename, &st) < 0)
+    fatal (_("cannot stat: %s: %s"), filename, strerror (errno));
+  if (st.st_size == 0)
+    return;
+  p = (char *) xmalloc (st.st_size + 2);
+  f = fopen (filename, FOPEN_RT);
+  if (f == NULL)
+    fatal (_("cannot open: %s: %s"), filename, strerror (errno));
+  if (fread (p, 1, st.st_size, f) == 0 || ferror (f))
+    fatal (_("%s: fread failed"), filename);
+  fclose (f);
+  p[st.st_size] = '\n';
+  p[st.st_size + 1] = '\0';
+  while (p[0] != '\0')
+    {
+      int i;
+      for (i = 0; p[i] != '\n'; i++)
+	;
+      if (i != 0)
+	{
+	  p[i] = '\0';
+	  add_specific_symbol (p, list);
+	}
+      p += (i + 1);
+    }
+}
+
 /* See whether a symbol should be stripped or kept based on
    strip_specific_list and keep_symbols.  */
 
@@ -659,7 +716,9 @@ filter_symbols (abfd, obfd, osyms, isyms
 	  sym->flags |= BSF_WEAK;
 	}
       if (keep && (flags & (BSF_GLOBAL | BSF_WEAK))
-	  && is_specified_symbol (name, localize_specific_list))
+	  && (is_specified_symbol (name, localize_specific_list)
+	      || (keepglobal_specific_list != NULL
+		  && ! is_specified_symbol (name, keepglobal_specific_list))))
 	{
 	  sym->flags &= ~(BSF_GLOBAL | BSF_WEAK);
 	  sym->flags |= BSF_LOCAL;
@@ -971,6 +1030,7 @@ copy_object (ibfd, obfd)
       || strip_specific_list != NULL
       || keep_specific_list != NULL
       || localize_specific_list != NULL
+      || keepglobal_specific_list != NULL
       || weaken_specific_list != NULL
       || sections_removed
       || sections_copied
@@ -1821,7 +1881,7 @@ copy_main (argc, argv)
   struct section_list *p;
   struct stat statbuf;
 
-  while ((c = getopt_long (argc, argv, "b:i:I:j:K:N:s:O:d:F:L:R:SpgxXVvW:",
+  while ((c = getopt_long (argc, argv, "b:i:I:j:K:N:s:O:d:F:L:G:R:SpgxXVvW:",
 			   copy_options, (int *) 0)) != EOF)
     {
       switch (c)
@@ -1892,6 +1952,10 @@ copy_main (argc, argv)
 	  add_specific_symbol (optarg, &localize_specific_list);
 	  break;
 
+	case 'G':
+	  add_specific_symbol (optarg, &keepglobal_specific_list);
+	  break;
+
 	case 'W':
 	  add_specific_symbol (optarg, &weaken_specific_list);
 	  break;
@@ -2157,6 +2221,26 @@ copy_main (argc, argv)
         case OPTION_SREC_FORCES3:
 	  S3Forced = true;
           break;
+
+	case OPTION_STRIP_SYMBOLS:
+	  add_specific_symbols (optarg, &strip_specific_list);
+	  break;
+
+	case OPTION_KEEP_SYMBOLS:
+	  add_specific_symbols (optarg, &keep_specific_list);
+	  break;
+
+	case OPTION_LOCALIZE_SYMBOLS:
+	  add_specific_symbols (optarg, &localize_specific_list);
+	  break;
+
+	case OPTION_KEEPGLOBAL_SYMBOLS:
+	  add_specific_symbols (optarg, &keepglobal_specific_list);
+	  break;
+
+	case OPTION_WEAKEN_SYMBOLS:
+	  add_specific_symbols (optarg, &weaken_specific_list);
+	  break;
 
 	case 0:
 	  break;		/* we've been given a long option */
--- binutils-2.11/binutils/objcopy.1.orig	Wed Nov 29 05:40:34 2000
+++ binutils-2.11/binutils/objcopy.1	Sat May 12 16:48:20 2001
@@ -25,6 +25,7 @@
 .RB "[\|" \-\-strip\-unneeded\fR "\|]" 
 .RB "[\|" \-K\ \fIsymbolname\fR\ |\ \fB\-\-keep\-symbol=\fIsymbolname\fR "\|]" 
 .RB "[\|" \-N\ \fIsymbolname\fR\ |\ \fB\-\-strip\-symbol=\fIsymbolname\fR "\|]" 
+.RB "[\|" \-G\ \fIsymbolname\fR\ |\ \fB\-\-keep-global\-symbol=\fIsymbolname\fR "\|]" 
 .RB "[\|" \-L\ \fIsymbolname\fR\ |\ \fB\-\-localize\-symbol=\fIsymbolname\fR "\|]" 
 .RB "[\|" \-W\ \fIsymbolname\fR\ |\ \fB\-\-weaken\-symbol=\fIsymbolname\fR "\|]" 
 .RB "[\|" \-x\fR\ |\ \fB\-\-discard\-all\fR "\|]" 
@@ -51,6 +52,11 @@
 .RB "[\|" \-\-srec\-forceS3\fR "\|]"
 .RB "[\|" \-\-redefine\-sym\ \fIold=new\fR "\|]"
 .RB "[\|" \-\-weaken\fR "\|]"
+.RB "[\|" \-\-keep\-symbols=\fIfilename\fR "\|]"
+.RB "[\|" \-\-strip\-symbols=\fIfilename\fR "\|]"
+.RB "[\|" \-\-keep\-global\-symbols=\fIfilename\fR "\|]"
+.RB "[\|" \-\-localize\-symbols=\fIfilename\fR "\|]"
+.RB "[\|" \-\-weaken\-symbols=\fIfilename\fR "\|]"
 .RB "[\|" \-v\ |\ \-\-verbose\fR "\|]" 
 .RB "[\|" \-V\ |\ \-\-version\fR "\|]" 
 .RB "[\|" \-\-help\fR "\|]" 
@@ -155,6 +161,11 @@
 Do not copy symbol \fIsymbolname\fP from the source file. This option
 may be given more than once.
 .TP
+.B \-G \fIsymbolname\fR, \fB\-\-keep\-global\-symbol=\fIsymbolname
+Keep only symbol \fIsymbolname\fP global.  Make all other symbols
+local to the file, so that they are not visible externally.  This
+option may be given more than once.
+.TP
 .B \-L \fIsymbolname\fR, \fB\-\-localize\-symbol=\fIsymbolname
 Make symbol \fIsymbolname\fP local to the file, so that it is not
 visible externally.  This option may be given more than once.
@@ -299,6 +310,31 @@
 .TP
 .B \-\-weaken
 Change all global symbols in the file to be weak.
+.TP
+.B \-\-keep\-symbols=\fIfilename
+Apply \fB\-\-keep\-symbol\fP option to each symbol listed in the file
+\fIfilename\fP.  \fIfilename\fP is simply a flat file, with one symbol
+name per line.  This option may be given more than once.
+.TP
+.B \-\-strip\-symbols=\fIfilename
+Apply \fB\-\-strip\-symbol\fP option to each symbol listed in the file
+\fIfilename\fP.  \fIfilename\fP is simply a flat file, with one symbol
+name per line.  This option may be given more than once.
+.TP
+.B \-\-keep\-global\-symbols=\fIfilename
+Apply \fB\-\-keep\-global\-symbol\fP option to each symbol listed in
+the file \fIfilename\fP.  \fIfilename\fP is simply a flat file, with
+one symbol name per line.  This option may be given more than once.
+.TP
+.B \-\-localize\-symbols=\fIfilename
+Apply \fB\-\-localize\-symbol\fP option to each symbol listed in the
+file \fIfilename\fP.  \fIfilename\fP is simply a flat file, with one
+symbol name per line.  This option may be given more than once.
+.TP
+.B \-\-weaken\-symbols=\fIfilename
+Apply \fB\-\-weaken\-symbol\fP option to each symbol listed in the
+file \fIfilename\fP.  \fIfilename\fP is simply a flat file, with one
+symbol name per line.  This option may be given more than once.
 .TP
 .B \-v\fR, \fB\-\-verbose
 Verbose output: list all object files modified.  In the case of
--- binutils-2.11/binutils/binutils.texi.orig	Thu Jan 18 09:18:50 2001
+++ binutils-2.11/binutils/binutils.texi	Sat May 12 16:53:55 2001
@@ -877,6 +877,7 @@
         [ -S | --strip-all ]  [ -g | --strip-debug ]
         [ -K @var{symbolname} | --keep-symbol=@var{symbolname} ]
         [ -N @var{symbolname} | --strip-symbol=@var{symbolname} ]
+        [ -G @var{symbolname} | --keep-global-symbol=@var{symbolname} ]
         [ -L @var{symbolname} | --localize-symbol=@var{symbolname} ]
         [ -W @var{symbolname} | --weaken-symbol=@var{symbolname} ]
         [ -x | --discard-all ]  [ -X | --discard-locals ]
@@ -897,6 +898,11 @@
         [ --change-leading-char ] [ --remove-leading-char ]
         [ --srec-len=@var{ival} ] [ --srec-forceS3 ]
         [ --redefine-sym @var{old}=@var{new} ] [ --weaken ]
+        [ --keep-symbols=@var{filename} ]
+        [ --strip-symbols=@var{filename} ]
+        [ --keep-global-symbols=@var{filename} ]
+        [ --localize-symbols=@var{filename} ]
+        [ --weaken-symbols=@var{filename} ]
         [ -v | --verbose ] [ -V | --version ]  [ --help ]
         @var{infile} [@var{outfile}]
 @end smallexample
@@ -993,6 +999,12 @@
 Do not copy symbol @var{symbolname} from the source file.  This option
 may be given more than once.
 
+@item -G @var{symbolname}
+@itemx --keep-global-symbol=@var{symbolname}
+Keep only symbol @var{symbolname} global.  Make all other symbols local
+to the file, so that they are not visible externally.  This option may
+be given more than once.
+
 @item -L @var{symbolname}
 @itemx --localize-symbol=@var{symbolname}
 Make symbol @var{symbolname} local to the file, so that it is not
@@ -1175,6 +1187,31 @@
 when building an object which will be linked against other objects using
 the @code{-R} option to the linker.  This option is only effective when
 using an object file format which supports weak symbols.
+
+@item --keep-symbols=@var{filename}
+Apply @samp{--keep-symbol} option to each symbol listed in the file
+@var{filename}.  @var{filename} is simply a flat file, with one symbol
+name per line.  This option may be given more than once.
+
+@item --strip-symbols=@var{filename}
+Apply @samp{--strip-symbol} option to each symbol listed in the file
+@var{filename}.  @var{filename} is simply a flat file, with one symbol
+name per line.  This option may be given more than once.
+
+@item --keep-global-symbols=@var{filename}
+Apply @samp{--keep-global-symbol} option to each symbol listed in the
+file @var{filename}.  @var{filename} is simply a flat file, with one
+symbol name per line.  This option may be given more than once.
+
+@item --localize-symbols=@var{filename}
+Apply @samp{--localize-symbol} option to each symbol listed in the file
+@var{filename}.  @var{filename} is simply a flat file, with one symbol
+name per line.  This option may be given more than once.
+
+@item --weaken-symbols=@var{filename}
+Apply @samp{--weaken-symbol} option to each symbol listed in the file
+@var{filename}.  @var{filename} is simply a flat file, with one symbol
+name per line.  This option may be given more than once.
 
 @item -V
 @itemx --version



More information about the Binutils mailing list