PR binutils/6034
authorNick Clifton <nickc@redhat.com>
Wed, 16 Apr 2008 08:24:21 +0000 (08:24 +0000)
committerNick Clifton <nickc@redhat.com>
Wed, 16 Apr 2008 08:24:21 +0000 (08:24 +0000)
        * 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.

binutils/ChangeLog
binutils/objcopy.c

index 6876607ca140d48289a7b2c2c9a9da55dc800ac8..b923b9210bb4e7f04b612681b7835afff8a143d5 100644 (file)
@@ -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.
index 1dd36114e908fc95733702d73fa4cd87adff8bd4..d44114ad71e8cc1dacf8f7b2ebd3f218f66def4f 100644 (file)
 #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;
+  const char   *name;
+  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;
 }
 
-/* Add a symbol to strip_specific_list.  */
+/* 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
-add_specific_symbol (const char *name, struct symlist **list)
+create_symbol_htabs (void)
 {
-  struct symlist *tmp_list;
+  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.  */
 
-  tmp_list = xmalloc (sizeof (struct symlist));
-  tmp_list->name = name;
-  tmp_list->next = *list;
-  *list = tmp_list;
+static void
+add_specific_symbol (const char *name, htab_t htab)
+{
+  *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 bfd_boolean
-is_specified_symbol (const char *name, struct symlist *list)
+static int
+is_specified_symbol_predicate (void **slot, void *data)
 {
-  struct symlist *tmp_list;
+  struct is_specified_symbol_predicate_data *d = data;
+  const char *slot_name = *slot;
 
-  if (wildcard)
+  if (*slot_name != '!')
     {
-      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;
-         }
+      if (! fnmatch (slot_name, d->name, 0))
+       {
+         d->found = TRUE;
+         /* Stop traversal.  */
+         return 0;
+       }
     }
   else
     {
-      for (tmp_list = list; tmp_list; tmp_list = tmp_list->next)
-       if (strcmp (name, tmp_list->name) == 0)
-         return TRUE;
+      if (fnmatch (slot_name + 1, d->name, 0))
+       {
+         d->found = TRUE;
+         /* Stop traversal.  */
+         return 0;
+       }
     }
 
-  return FALSE;
+  /* Continue traversal.  */
+  return 1;
+}
+
+static bfd_boolean
+is_specified_symbol (const char *name, htab_t htab)
+{
+  if (wildcard)
+    {
+      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 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