static void copy_section PARAMS ((bfd *, asection *, PTR));
static void get_sections PARAMS ((bfd *, asection *, PTR));
static int compare_section_vma PARAMS ((const PTR, const PTR));
+static void add_strip_symbol PARAMS ((const char *));
+static int is_strip_symbol PARAMS ((const char *));
+static unsigned int filter_symbols
+ PARAMS ((bfd *, asymbol **, asymbol **, long));
static void mark_symbols_used_in_relocations PARAMS ((bfd *, asection *, PTR));
#define nonfatal(s) {bfd_nonfatal(s); status = 1; return;}
{"remove-section", required_argument, 0, 'R'},
{"strip-all", no_argument, 0, 's'},
{"strip-debug", no_argument, 0, 'S'},
+ {"strip-symbol", required_argument, 0, 'N'},
{"target", required_argument, 0, 'F'},
{"verbose", no_argument, 0, 'v'},
{"version", no_argument, 0, 'V'},
{"set-start", required_argument, 0, OPTION_SET_START},
{"strip-all", no_argument, 0, 'S'},
{"strip-debug", no_argument, 0, 'g'},
+ {"strip-symbol", required_argument, 0, 'N'},
{"target", required_argument, 0, 'F'},
{"verbose", no_argument, 0, 'v'},
{"version", no_argument, 0, 'V'},
[--set-start=val] [--adjust-start=incr] [--adjust-vma=incr]\n\
[--adjust-section-vma=section{=,+,-}val] [--adjust-warnings]\n\
[--no-adjust-warnings] [--verbose] [--version] [--help]\n\
+ [--strip-symbol symbol] [-N symbol]\n\
in-file [out-file]\n",
program_name);
exit (status);
Usage: %s [-vVsSgxX] [-I bfdname] [-O bfdname] [-F bfdname] [-R section]\n\
[--input-target=bfdname] [--output-target=bfdname] [--target=bfdname]\n\
[--strip-all] [--strip-debug] [--discard-all] [--discard-locals]\n\
+ [--strip-symbol symbol] [-N symbol]\n\
[--remove-section=section] [--verbose] [--version] [--help] file...\n",
program_name);
exit (status);
return tmpname;
}
+/* Make a list of symbols to explicitly strip out. A linked list is
+ good enough for a small number from the command line, but this will
+ slow things down a lot if many symbols are being deleted. */
+
+struct symlist
+{
+ const char *name;
+ struct symlist *next;
+};
+
+static struct symlist *strip_specific_list = NULL;
+
+static void
+add_strip_symbol (name)
+ const char *name;
+{
+ struct symlist *tmp_list;
+
+ tmp_list = (struct symlist *) xmalloc (sizeof (struct symlist));
+ tmp_list->name = name;
+ tmp_list->next = strip_specific_list;
+ strip_specific_list = tmp_list;
+}
+
+static int
+is_strip_symbol (name)
+ const char *name;
+{
+ struct symlist *tmp_list;
+
+ for (tmp_list = strip_specific_list; tmp_list; tmp_list = tmp_list->next)
+ {
+ if (strcmp (name, tmp_list->name) == 0)
+ return 1;
+ }
+ return 0;
+}
+
/* Choose which symbol entries to copy; put the result in OSYMS.
We don't copy in place, because that confuses the relocs.
Return the number of symbols to print. */
keep = discard_locals != locals_all
&& (discard_locals != locals_start_L ||
! bfd_is_local_label (abfd, sym));
+
+ if (keep && is_strip_symbol (bfd_asymbol_name (sym)))
+ keep = 0;
+
if (keep)
to[dst_count++] = sym;
}
nonfatal (bfd_get_filename (ibfd));
}
- if (strip_symbols == strip_debug || discard_locals != locals_undef)
+ if (strip_symbols == strip_debug
+ || discard_locals != locals_undef
+ || strip_specific_list)
{
/* Mark symbols used in output relocations so that they
are kept, even if they are local labels or static symbols.
boolean show_version = false;
int c, i;
- while ((c = getopt_long (argc, argv, "I:O:F:R:sSgxXVv",
+ while ((c = getopt_long (argc, argv, "I:O:F:R:sSgxXVvN:",
strip_options, (int *) 0)) != EOF)
{
switch (c)
case 'g':
strip_symbols = strip_debug;
break;
+ case 'N':
+ add_strip_symbol (optarg);
+ break;
case 'x':
discard_locals = locals_all;
break;
}
/* Default is to strip all symbols. */
- if (strip_symbols == strip_undef && discard_locals == locals_undef)
+ if (strip_symbols == strip_undef
+ && discard_locals == locals_undef
+ && strip_specific_list == NULL)
strip_symbols = strip_all;
if (output_target == (char *) NULL)
int c;
struct section_list *p;
- while ((c = getopt_long (argc, argv, "b:i:I:s:O:d:F:R:SgxXVv",
+ while ((c = getopt_long (argc, argv, "b:i:I:s:O:d:F:R:SgxXVvN:",
copy_options, (int *) 0)) != EOF)
{
switch (c)
case 'g':
strip_symbols = strip_debug;
break;
+ case 'N':
+ add_strip_symbol (optarg);
+ break;
case 'x':
discard_locals = locals_all;
break;