PR binutils/6034
* objcopy.c (stuct symlist): Rename to is_specified_symbol_predicate_data. (strip_specific_list): Rename to strip_specific_htab. (strip_unneeded_list): Rename to strip_unneeded_htab. (keep_specific_list): Rename to keep_specific_htab. (localize_specific_list): Rename to localize_specific_htab. (globalize_specific_list): Rename to globalize_specific_htab. (keepglobal_specific_list): Rename to keepglobal_specific_htab. (weaken_specific_list): Rename to weaken_specific_htab. (eq_string): New function. (create_symbol_htab): New function. (create_symbol_htabs): New function. (add_specific_symbol): Change to use hash tables. (is_specified_symbol_predicate): New function. (is_specified_symbol): Use hash table lookup. (is_strip_section): Update to use new functions and hash tables. (filter_symbols): Likewise. (copy_object): Likewise. (copy_section): Likewise. (strip_main): Likewise. (copy_main): Likewise. (main): Likewise.
This commit is contained in:
parent
bca18a16dd
commit
047c90248e
2 changed files with 141 additions and 79 deletions
|
@ -1,3 +1,29 @@
|
|||
2008-04-16 Jean-Yves Lefort <jylefort@brutele.be>
|
||||
|
||||
PR binutils/6034
|
||||
* objcopy.c (stuct symlist): Rename to
|
||||
is_specified_symbol_predicate_data.
|
||||
(strip_specific_list): Rename to strip_specific_htab.
|
||||
(strip_unneeded_list): Rename to strip_unneeded_htab.
|
||||
(keep_specific_list): Rename to keep_specific_htab.
|
||||
(localize_specific_list): Rename to localize_specific_htab.
|
||||
(globalize_specific_list): Rename to globalize_specific_htab.
|
||||
(keepglobal_specific_list): Rename to keepglobal_specific_htab.
|
||||
(weaken_specific_list): Rename to weaken_specific_htab.
|
||||
(eq_string): New function.
|
||||
(create_symbol_htab): New function.
|
||||
(create_symbol_htabs): New function.
|
||||
(add_specific_symbol): Change to use hash tables.
|
||||
(is_specified_symbol_predicate): New function.
|
||||
(is_specified_symbol): Use hash table lookup.
|
||||
(is_strip_section): Update to use new functions and hash tables.
|
||||
(filter_symbols): Likewise.
|
||||
(copy_object): Likewise.
|
||||
(copy_section): Likewise.
|
||||
(strip_main): Likewise.
|
||||
(copy_main): Likewise.
|
||||
(main): Likewise.
|
||||
|
||||
2008-04-14 David S. Miller <davem@davemloft.net>
|
||||
|
||||
* readelf.c (get_gnu_elf_note_type): Recognize NT_GNU_GOLD_VERSION.
|
||||
|
|
|
@ -33,15 +33,10 @@
|
|||
#include <sys/stat.h>
|
||||
#include "libbfd.h"
|
||||
|
||||
/* A list of symbols to explicitly strip out, or to keep. 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
|
||||
struct is_specified_symbol_predicate_data
|
||||
{
|
||||
const char *name;
|
||||
struct symlist *next;
|
||||
bfd_boolean found;
|
||||
};
|
||||
|
||||
/* A list to support redefine_sym. */
|
||||
|
@ -199,13 +194,13 @@ static bfd_boolean localize_hidden = FALSE;
|
|||
|
||||
/* List of symbols to strip, keep, localize, keep-global, weaken,
|
||||
or redefine. */
|
||||
static struct symlist *strip_specific_list = NULL;
|
||||
static struct symlist *strip_unneeded_list = NULL;
|
||||
static struct symlist *keep_specific_list = NULL;
|
||||
static struct symlist *localize_specific_list = NULL;
|
||||
static struct symlist *globalize_specific_list = NULL;
|
||||
static struct symlist *keepglobal_specific_list = NULL;
|
||||
static struct symlist *weaken_specific_list = NULL;
|
||||
static htab_t strip_specific_htab = NULL;
|
||||
static htab_t strip_unneeded_htab = NULL;
|
||||
static htab_t keep_specific_htab = NULL;
|
||||
static htab_t localize_specific_htab = NULL;
|
||||
static htab_t globalize_specific_htab = NULL;
|
||||
static htab_t keepglobal_specific_htab = NULL;
|
||||
static htab_t weaken_specific_htab = NULL;
|
||||
static struct redefine_node *redefine_sym_list = NULL;
|
||||
|
||||
/* If this is TRUE, we weaken global symbols (set BSF_WEAK). */
|
||||
|
@ -642,17 +637,38 @@ find_section_list (const char *name, bfd_boolean add)
|
|||
return p;
|
||||
}
|
||||
|
||||
/* There is htab_hash_string but no htab_eq_string. Makes sense. */
|
||||
|
||||
static int
|
||||
eq_string (const void *s1, const void *s2)
|
||||
{
|
||||
return strcmp (s1, s2) == 0;
|
||||
}
|
||||
|
||||
static htab_t
|
||||
create_symbol_htab (void)
|
||||
{
|
||||
return htab_create_alloc (16, htab_hash_string, eq_string, NULL, xcalloc, free);
|
||||
}
|
||||
|
||||
static void
|
||||
create_symbol_htabs (void)
|
||||
{
|
||||
strip_specific_htab = create_symbol_htab ();
|
||||
strip_unneeded_htab = create_symbol_htab ();
|
||||
keep_specific_htab = create_symbol_htab ();
|
||||
localize_specific_htab = create_symbol_htab ();
|
||||
globalize_specific_htab = create_symbol_htab ();
|
||||
keepglobal_specific_htab = create_symbol_htab ();
|
||||
weaken_specific_htab = create_symbol_htab ();
|
||||
}
|
||||
|
||||
/* Add a symbol to strip_specific_list. */
|
||||
|
||||
static void
|
||||
add_specific_symbol (const char *name, struct symlist **list)
|
||||
add_specific_symbol (const char *name, htab_t htab)
|
||||
{
|
||||
struct symlist *tmp_list;
|
||||
|
||||
tmp_list = xmalloc (sizeof (struct symlist));
|
||||
tmp_list->name = name;
|
||||
tmp_list->next = *list;
|
||||
*list = tmp_list;
|
||||
*htab_find_slot (htab, name, INSERT) = (char *) name;
|
||||
}
|
||||
|
||||
/* Add symbols listed in `filename' to strip_specific_list. */
|
||||
|
@ -661,7 +677,7 @@ add_specific_symbol (const char *name, struct symlist **list)
|
|||
#define IS_LINE_TERMINATOR(c) ((c) == '\n' || (c) == '\r' || (c) == '\0')
|
||||
|
||||
static void
|
||||
add_specific_symbols (const char *filename, struct symlist **list)
|
||||
add_specific_symbols (const char *filename, htab_t htab)
|
||||
{
|
||||
off_t size;
|
||||
FILE * f;
|
||||
|
@ -762,7 +778,7 @@ add_specific_symbols (const char *filename, struct symlist **list)
|
|||
* name_end = '\0';
|
||||
|
||||
if (name_end > name)
|
||||
add_specific_symbol (name, list);
|
||||
add_specific_symbol (name, htab);
|
||||
|
||||
/* Advance line pointer to end of line. The 'eol ++' in the for
|
||||
loop above will then advance us to the start of the next line. */
|
||||
|
@ -771,36 +787,54 @@ add_specific_symbols (const char *filename, struct symlist **list)
|
|||
}
|
||||
}
|
||||
|
||||
/* See whether a symbol should be stripped or kept based on
|
||||
strip_specific_list and keep_symbols. */
|
||||
/* See whether a symbol should be stripped or kept
|
||||
based on strip_specific_list and keep_symbols. */
|
||||
|
||||
static int
|
||||
is_specified_symbol_predicate (void **slot, void *data)
|
||||
{
|
||||
struct is_specified_symbol_predicate_data *d = data;
|
||||
const char *slot_name = *slot;
|
||||
|
||||
if (*slot_name != '!')
|
||||
{
|
||||
if (! fnmatch (slot_name, d->name, 0))
|
||||
{
|
||||
d->found = TRUE;
|
||||
/* Stop traversal. */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (fnmatch (slot_name + 1, d->name, 0))
|
||||
{
|
||||
d->found = TRUE;
|
||||
/* Stop traversal. */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Continue traversal. */
|
||||
return 1;
|
||||
}
|
||||
|
||||
static bfd_boolean
|
||||
is_specified_symbol (const char *name, struct symlist *list)
|
||||
is_specified_symbol (const char *name, htab_t htab)
|
||||
{
|
||||
struct symlist *tmp_list;
|
||||
|
||||
if (wildcard)
|
||||
{
|
||||
for (tmp_list = list; tmp_list; tmp_list = tmp_list->next)
|
||||
if (*(tmp_list->name) != '!')
|
||||
{
|
||||
if (!fnmatch (tmp_list->name, name, 0))
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (fnmatch (tmp_list->name + 1, name, 0))
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (tmp_list = list; tmp_list; tmp_list = tmp_list->next)
|
||||
if (strcmp (name, tmp_list->name) == 0)
|
||||
return TRUE;
|
||||
struct is_specified_symbol_predicate_data data;
|
||||
|
||||
data.name = name;
|
||||
data.found = FALSE;
|
||||
|
||||
htab_traverse (htab, is_specified_symbol_predicate, &data);
|
||||
|
||||
return data.found;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
return htab_find (htab, name) != NULL;
|
||||
}
|
||||
|
||||
/* Return a pointer to the symbol used as a signature for GROUP. */
|
||||
|
@ -877,8 +911,8 @@ is_strip_section (bfd *abfd ATTRIBUTE_UNUSED, asection *sec)
|
|||
else
|
||||
gname = sec->name;
|
||||
if ((strip_symbols == STRIP_ALL
|
||||
&& !is_specified_symbol (gname, keep_specific_list))
|
||||
|| is_specified_symbol (gname, strip_specific_list))
|
||||
&& !is_specified_symbol (gname, keep_specific_htab))
|
||||
|| is_specified_symbol (gname, strip_specific_htab))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -1026,7 +1060,7 @@ filter_symbols (bfd *abfd, bfd *obfd, asymbol **osyms,
|
|||
&& (discard_locals != LOCALS_START_L
|
||||
|| ! bfd_is_local_label (abfd, sym))));
|
||||
|
||||
if (keep && is_specified_symbol (name, strip_specific_list))
|
||||
if (keep && is_specified_symbol (name, strip_specific_htab))
|
||||
{
|
||||
/* There are multiple ways to set 'keep' above, but if it
|
||||
was the relocatable symbol case, then that's an error. */
|
||||
|
@ -1041,12 +1075,12 @@ filter_symbols (bfd *abfd, bfd *obfd, asymbol **osyms,
|
|||
|
||||
if (keep
|
||||
&& !(flags & BSF_KEEP)
|
||||
&& is_specified_symbol (name, strip_unneeded_list))
|
||||
&& is_specified_symbol (name, strip_unneeded_htab))
|
||||
keep = FALSE;
|
||||
|
||||
if (!keep
|
||||
&& ((keep_file_symbols && (flags & BSF_FILE))
|
||||
|| is_specified_symbol (name, keep_specific_list)))
|
||||
|| is_specified_symbol (name, keep_specific_htab)))
|
||||
keep = TRUE;
|
||||
|
||||
if (keep && is_strip_section (abfd, bfd_get_section (sym)))
|
||||
|
@ -1055,7 +1089,7 @@ filter_symbols (bfd *abfd, bfd *obfd, asymbol **osyms,
|
|||
if (keep)
|
||||
{
|
||||
if ((flags & BSF_GLOBAL) != 0
|
||||
&& (weaken || is_specified_symbol (name, weaken_specific_list)))
|
||||
&& (weaken || is_specified_symbol (name, weaken_specific_htab)))
|
||||
{
|
||||
sym->flags &= ~ BSF_GLOBAL;
|
||||
sym->flags |= BSF_WEAK;
|
||||
|
@ -1063,9 +1097,9 @@ filter_symbols (bfd *abfd, bfd *obfd, asymbol **osyms,
|
|||
|
||||
if (!undefined
|
||||
&& (flags & (BSF_GLOBAL | BSF_WEAK))
|
||||
&& (is_specified_symbol (name, localize_specific_list)
|
||||
|| (keepglobal_specific_list != NULL
|
||||
&& ! is_specified_symbol (name, keepglobal_specific_list))
|
||||
&& (is_specified_symbol (name, localize_specific_htab)
|
||||
|| (htab_elements (keepglobal_specific_htab) != 0
|
||||
&& ! is_specified_symbol (name, keepglobal_specific_htab))
|
||||
|| (localize_hidden && is_hidden_symbol (sym))))
|
||||
{
|
||||
sym->flags &= ~ (BSF_GLOBAL | BSF_WEAK);
|
||||
|
@ -1074,7 +1108,7 @@ filter_symbols (bfd *abfd, bfd *obfd, asymbol **osyms,
|
|||
|
||||
if (!undefined
|
||||
&& (flags & BSF_LOCAL)
|
||||
&& is_specified_symbol (name, globalize_specific_list))
|
||||
&& is_specified_symbol (name, globalize_specific_htab))
|
||||
{
|
||||
sym->flags &= ~ BSF_LOCAL;
|
||||
sym->flags |= BSF_GLOBAL;
|
||||
|
@ -1648,12 +1682,12 @@ copy_object (bfd *ibfd, bfd *obfd)
|
|||
|| strip_symbols == STRIP_NONDEBUG
|
||||
|| discard_locals != LOCALS_UNDEF
|
||||
|| localize_hidden
|
||||
|| strip_specific_list != NULL
|
||||
|| keep_specific_list != NULL
|
||||
|| localize_specific_list != NULL
|
||||
|| globalize_specific_list != NULL
|
||||
|| keepglobal_specific_list != NULL
|
||||
|| weaken_specific_list != NULL
|
||||
|| htab_elements (strip_specific_htab) != 0
|
||||
|| htab_elements (keep_specific_htab) != 0
|
||||
|| htab_elements (localize_specific_htab) != 0
|
||||
|| htab_elements (globalize_specific_htab) != 0
|
||||
|| htab_elements (keepglobal_specific_htab) != 0
|
||||
|| htab_elements (weaken_specific_htab) != 0
|
||||
|| prefix_symbols_string
|
||||
|| sections_removed
|
||||
|| sections_copied
|
||||
|
@ -2414,7 +2448,7 @@ copy_section (bfd *ibfd, sec_ptr isection, void *obfdarg)
|
|||
temp_relpp = xmalloc (relsize);
|
||||
for (i = 0; i < relcount; i++)
|
||||
if (is_specified_symbol (bfd_asymbol_name (*relpp[i]->sym_ptr_ptr),
|
||||
keep_specific_list))
|
||||
keep_specific_htab))
|
||||
temp_relpp [temp_relcount++] = relpp [i];
|
||||
relcount = temp_relcount;
|
||||
free (relpp);
|
||||
|
@ -2716,10 +2750,10 @@ strip_main (int argc, char *argv[])
|
|||
strip_symbols = STRIP_UNNEEDED;
|
||||
break;
|
||||
case 'K':
|
||||
add_specific_symbol (optarg, &keep_specific_list);
|
||||
add_specific_symbol (optarg, keep_specific_htab);
|
||||
break;
|
||||
case 'N':
|
||||
add_specific_symbol (optarg, &strip_specific_list);
|
||||
add_specific_symbol (optarg, strip_specific_htab);
|
||||
break;
|
||||
case 'o':
|
||||
output_file = optarg;
|
||||
|
@ -2774,7 +2808,7 @@ strip_main (int argc, char *argv[])
|
|||
/* Default is to strip all symbols. */
|
||||
if (strip_symbols == STRIP_UNDEF
|
||||
&& discard_locals == LOCALS_UNDEF
|
||||
&& strip_specific_list == NULL)
|
||||
&& htab_elements (strip_specific_htab) == 0)
|
||||
strip_symbols = STRIP_ALL;
|
||||
|
||||
if (output_target == NULL)
|
||||
|
@ -2927,31 +2961,31 @@ copy_main (int argc, char *argv[])
|
|||
break;
|
||||
|
||||
case 'K':
|
||||
add_specific_symbol (optarg, &keep_specific_list);
|
||||
add_specific_symbol (optarg, keep_specific_htab);
|
||||
break;
|
||||
|
||||
case 'N':
|
||||
add_specific_symbol (optarg, &strip_specific_list);
|
||||
add_specific_symbol (optarg, strip_specific_htab);
|
||||
break;
|
||||
|
||||
case OPTION_STRIP_UNNEEDED_SYMBOL:
|
||||
add_specific_symbol (optarg, &strip_unneeded_list);
|
||||
add_specific_symbol (optarg, strip_unneeded_htab);
|
||||
break;
|
||||
|
||||
case 'L':
|
||||
add_specific_symbol (optarg, &localize_specific_list);
|
||||
add_specific_symbol (optarg, localize_specific_htab);
|
||||
break;
|
||||
|
||||
case OPTION_GLOBALIZE_SYMBOL:
|
||||
add_specific_symbol (optarg, &globalize_specific_list);
|
||||
add_specific_symbol (optarg, globalize_specific_htab);
|
||||
break;
|
||||
|
||||
case 'G':
|
||||
add_specific_symbol (optarg, &keepglobal_specific_list);
|
||||
add_specific_symbol (optarg, keepglobal_specific_htab);
|
||||
break;
|
||||
|
||||
case 'W':
|
||||
add_specific_symbol (optarg, &weaken_specific_list);
|
||||
add_specific_symbol (optarg, weaken_specific_htab);
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
|
@ -3275,15 +3309,15 @@ copy_main (int argc, char *argv[])
|
|||
break;
|
||||
|
||||
case OPTION_STRIP_SYMBOLS:
|
||||
add_specific_symbols (optarg, &strip_specific_list);
|
||||
add_specific_symbols (optarg, strip_specific_htab);
|
||||
break;
|
||||
|
||||
case OPTION_STRIP_UNNEEDED_SYMBOLS:
|
||||
add_specific_symbols (optarg, &strip_unneeded_list);
|
||||
add_specific_symbols (optarg, strip_unneeded_htab);
|
||||
break;
|
||||
|
||||
case OPTION_KEEP_SYMBOLS:
|
||||
add_specific_symbols (optarg, &keep_specific_list);
|
||||
add_specific_symbols (optarg, keep_specific_htab);
|
||||
break;
|
||||
|
||||
case OPTION_LOCALIZE_HIDDEN:
|
||||
|
@ -3291,19 +3325,19 @@ copy_main (int argc, char *argv[])
|
|||
break;
|
||||
|
||||
case OPTION_LOCALIZE_SYMBOLS:
|
||||
add_specific_symbols (optarg, &localize_specific_list);
|
||||
add_specific_symbols (optarg, localize_specific_htab);
|
||||
break;
|
||||
|
||||
case OPTION_GLOBALIZE_SYMBOLS:
|
||||
add_specific_symbols (optarg, &globalize_specific_list);
|
||||
add_specific_symbols (optarg, globalize_specific_htab);
|
||||
break;
|
||||
|
||||
case OPTION_KEEPGLOBAL_SYMBOLS:
|
||||
add_specific_symbols (optarg, &keepglobal_specific_list);
|
||||
add_specific_symbols (optarg, keepglobal_specific_htab);
|
||||
break;
|
||||
|
||||
case OPTION_WEAKEN_SYMBOLS:
|
||||
add_specific_symbols (optarg, &weaken_specific_list);
|
||||
add_specific_symbols (optarg, weaken_specific_htab);
|
||||
break;
|
||||
|
||||
case OPTION_ALT_MACH_CODE:
|
||||
|
@ -3530,6 +3564,8 @@ main (int argc, char *argv[])
|
|||
is_strip = (i >= 5 && FILENAME_CMP (program_name + i - 5, "strip") == 0);
|
||||
}
|
||||
|
||||
create_symbol_htabs ();
|
||||
|
||||
if (is_strip)
|
||||
strip_main (argc, argv);
|
||||
else
|
||||
|
|
Loading…
Reference in a new issue