patches/binutils/2.15/790-ld-2.15-callahan.patch
changeset 745 e445c00d134d
parent 744 4bf8448536d5
child 746 b150d6f590fc
     1.1 --- a/patches/binutils/2.15/790-ld-2.15-callahan.patch	Mon Jul 28 20:10:34 2008 +0000
     1.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.3 @@ -1,677 +0,0 @@
     1.4 -Signed-off-by: dank@kegel.com
     1.5 -Fixes ld speed issue. 
     1.6 -See http://weblogs.mozillazine.org/roc/archives/2005/02/optimizing_gnu.html
     1.7 -See thread "Re: optimizations for 3x speedup in ld",
     1.8 -http://sources.redhat.com/ml/binutils/2005-03/msg00847.html
     1.9 -
    1.10 -Wildcard section matching enhancement, backported from the binutils CVS tree.
    1.11 -Here's the CVS log comment from the original change to ldlang.c:
    1.12 -
    1.13 -revision 1.177
    1.14 -date: 2005/04/06 15:33:02;  author: jakub;  state: Exp;  lines: +438 -51
    1.15 -2005-04-06  Jakub Jelinek  <jakub@redhat.com>
    1.16 -
    1.17 -        * ldlang.c: Formatting.
    1.18 -        (walk_wild_consider_section): Remember return value from wildcardp.
    1.19 -        (is_simple_wild): Use strcspn instead of 2 strpbrk calls and strlen.
    1.20 -        (wild_spec_can_overlap): Use strcspn instead of strpbrk and strlen.
    1.21 -
    1.22 -2005-04-06  Robert O'Callahan  <rocallahan@novell.com>
    1.23 -
    1.24 -        * ld.h (lean_section_userdata_type): Remove.
    1.25 -        (fat_section_userdata_type): Remove file field.
    1.26 -        (SECTION_USERDATA_SIZE): Remove.
    1.27 -        * ldlang.c (init_os): Eliminate initialization of unused
    1.28 -        lean_section_userdata_type.
    1.29 -
    1.30 -        * ldlang.h (callback_t, walk_wild_section_handler_t): New
    1.31 -        typedefs.
    1.32 -        (struct lang_wild_statement_struct): Add walk_wild_section_handler
    1.33 -        and handler_data fields.
    1.34 -        * ldlang.c (callback_t): Removed.
    1.35 -        (walk_wild_consider_section, walk_wild_section_general,
    1.36 -        section_iterator_callback, find_section, is_simple_wild,
    1.37 -        match_simple_wild, walk_wild_section_specs1_wild0,
    1.38 -        walk_wild_section_specs1_wild1, walk_wild_section_specs2_wild1,
    1.39 -        walk_wild_section_specs3_wild2, walk_wild_section_specs4_wild2,
    1.40 -        wild_spec_can_overlap, analyze_walk_wild_section_handler): New
    1.41 -        functions.
    1.42 -        (lang_add_wild): Call analyze_walk_wild_section_handler.
    1.43 -        (walk_wild_section): Renamed to walk_wild_section_general and
    1.44 -        created a wrapper function.
    1.45 -        (section_iterator_callback_data): New typedef.
    1.46 -
    1.47 -Note that bfd_get_section_by_name_if didn't exist in 2.15, so it was backported
    1.48 -as well.
    1.49 -
    1.50 ---- binutils-2.15/bfd/bfd-in2.h.old	2004-05-17 15:35:56.000000000 -0400
    1.51 -+++ binutils-2.15/bfd/bfd-in2.h	2006-02-09 11:54:45.989940000 -0500
    1.52 -@@ -1425,6 +1425,10 @@
    1.53 - 
    1.54 - asection *bfd_get_section_by_name (bfd *abfd, const char *name);
    1.55 - 
    1.56 -+asection *bfd_get_section_by_name_if (bfd *abfd, const char *name,
    1.57 -+   bfd_boolean (*operation) (bfd *, asection *, void *),
    1.58 -+   void *user_storage);
    1.59 -+
    1.60 - char *bfd_get_unique_section_name
    1.61 -    (bfd *abfd, const char *templat, int *count);
    1.62 - 
    1.63 ---- binutils-2.15/bfd/section.c.old	2003-12-01 01:33:01.000000000 -0500
    1.64 -+++ binutils-2.15/bfd/section.c	2006-01-23 14:16:54.768993000 -0500
    1.65 -@@ -801,6 +801,57 @@
    1.66 - 
    1.67 - /*
    1.68 - FUNCTION
    1.69 -+	bfd_get_section_by_name_if
    1.70 -+
    1.71 -+SYNOPSIS
    1.72 -+	asection *bfd_get_section_by_name_if
    1.73 -+	  (bfd *abfd,
    1.74 -+	   const char *name,
    1.75 -+	   bfd_boolean (*func) (bfd *abfd, asection *sect, void *obj),
    1.76 -+	   void *obj);
    1.77 -+
    1.78 -+DESCRIPTION
    1.79 -+	Call the provided function @var{func} for each section
    1.80 -+	attached to the BFD @var{abfd} whose name matches @var{name},
    1.81 -+	passing @var{obj} as an argument. The function will be called
    1.82 -+	as if by
    1.83 -+
    1.84 -+|	func (abfd, the_section, obj);
    1.85 -+
    1.86 -+	It returns the first section for which @var{func} returns true,
    1.87 -+	otherwise <<NULL>>.
    1.88 -+
    1.89 -+*/
    1.90 -+
    1.91 -+asection *
    1.92 -+bfd_get_section_by_name_if (bfd *abfd, const char *name,
    1.93 -+			    bfd_boolean (*operation) (bfd *,
    1.94 -+						      asection *,
    1.95 -+						      void *),
    1.96 -+			    void *user_storage)
    1.97 -+{
    1.98 -+  struct section_hash_entry *sh;
    1.99 -+  unsigned long hash;
   1.100 -+
   1.101 -+  sh = section_hash_lookup (&abfd->section_htab, name, FALSE, FALSE);
   1.102 -+  if (sh == NULL)
   1.103 -+    return NULL;
   1.104 -+
   1.105 -+  hash = sh->root.hash;
   1.106 -+  do
   1.107 -+    {
   1.108 -+      if ((*operation) (abfd, &sh->section, user_storage))
   1.109 -+	return &sh->section;
   1.110 -+      sh = (struct section_hash_entry *) sh->root.next;
   1.111 -+    }
   1.112 -+  while (sh != NULL && sh->root.hash == hash
   1.113 -+	 && strcmp (sh->root.string, name) == 0);
   1.114 -+
   1.115 -+  return NULL;
   1.116 -+}
   1.117 -+
   1.118 -+/*
   1.119 -+FUNCTION
   1.120 - 	bfd_get_unique_section_name
   1.121 - 
   1.122 - SYNOPSIS
   1.123 ---- binutils-2.15/ld/ldlang.c.old	2004-05-17 15:36:16.000000000 -0400
   1.124 -+++ binutils-2.15/ld/ldlang.c	2006-01-23 13:40:12.745499000 -0500
   1.125 -@@ -81,9 +81,6 @@
   1.126 - static void lang_record_phdrs (void);
   1.127 - static void lang_do_version_exports_section (void);
   1.128 - 
   1.129 --typedef void (*callback_t) (lang_wild_statement_type *, struct wildcard_list *,
   1.130 --			    asection *, lang_input_statement_type *, void *);
   1.131 --
   1.132 - /* Exported variables.  */
   1.133 - lang_output_section_statement_type *abs_output_section;
   1.134 - lang_statement_list_type lang_output_section_statement;
   1.135 -@@ -138,21 +135,71 @@
   1.136 - 
   1.137 - /* Generic traversal routines for finding matching sections.  */
   1.138 - 
   1.139 -+/* Try processing a section against a wildcard.  This just calls
   1.140 -+   the callback unless the filename exclusion list is present
   1.141 -+   and excludes the file.  It's hardly ever present so this
   1.142 -+   function is very fast.  */
   1.143 -+
   1.144 -+static void
   1.145 -+walk_wild_consider_section (lang_wild_statement_type *ptr,
   1.146 -+			    lang_input_statement_type *file,
   1.147 -+			    asection *s,
   1.148 -+			    struct wildcard_list *sec,
   1.149 -+			    callback_t callback,
   1.150 -+			    void *data)
   1.151 -+{
   1.152 -+  bfd_boolean skip = FALSE;
   1.153 -+  struct name_list *list_tmp;
   1.154 -+
   1.155 -+  /* Don't process sections from files which were
   1.156 -+     excluded.  */
   1.157 -+  for (list_tmp = sec->spec.exclude_name_list;
   1.158 -+       list_tmp;
   1.159 -+       list_tmp = list_tmp->next)
   1.160 -+    {
   1.161 -+      bfd_boolean is_wildcard = wildcardp (list_tmp->name);
   1.162 -+      if (is_wildcard)
   1.163 -+	skip = fnmatch (list_tmp->name, file->filename, 0) == 0;
   1.164 -+      else
   1.165 -+	skip = strcmp (list_tmp->name, file->filename) == 0;
   1.166 -+
   1.167 -+      /* If this file is part of an archive, and the archive is
   1.168 -+	 excluded, exclude this file.  */
   1.169 -+      if (! skip && file->the_bfd != NULL
   1.170 -+	  && file->the_bfd->my_archive != NULL
   1.171 -+	  && file->the_bfd->my_archive->filename != NULL)
   1.172 -+	{
   1.173 -+	  if (is_wildcard)
   1.174 -+	    skip = fnmatch (list_tmp->name,
   1.175 -+			    file->the_bfd->my_archive->filename,
   1.176 -+			    0) == 0;
   1.177 -+	  else
   1.178 -+	    skip = strcmp (list_tmp->name,
   1.179 -+			   file->the_bfd->my_archive->filename) == 0;
   1.180 -+	}
   1.181 -+
   1.182 -+      if (skip)
   1.183 -+	break;
   1.184 -+    }
   1.185 -+
   1.186 -+  if (!skip)
   1.187 -+    (*callback) (ptr, sec, s, file, data);
   1.188 -+}
   1.189 -+
   1.190 -+/* Lowest common denominator routine that can handle everything correctly,
   1.191 -+   but slowly.  */
   1.192 -+
   1.193 - static void
   1.194 --walk_wild_section (lang_wild_statement_type *ptr,
   1.195 --		   lang_input_statement_type *file,
   1.196 --		   callback_t callback,
   1.197 --		   void *data)
   1.198 -+walk_wild_section_general (lang_wild_statement_type *ptr,
   1.199 -+			   lang_input_statement_type *file,
   1.200 -+			   callback_t callback,
   1.201 -+			   void *data)
   1.202 - {
   1.203 -   asection *s;
   1.204 --
   1.205 --  if (file->just_syms_flag)
   1.206 --    return;
   1.207 -+  struct wildcard_list *sec;
   1.208 - 
   1.209 -   for (s = file->the_bfd->sections; s != NULL; s = s->next)
   1.210 -     {
   1.211 --      struct wildcard_list *sec;
   1.212 --
   1.213 -       sec = ptr->section_list;
   1.214 -       if (sec == NULL)
   1.215 - 	(*callback) (ptr, sec, s, file, data);
   1.216 -@@ -160,39 +207,8 @@
   1.217 -       while (sec != NULL)
   1.218 - 	{
   1.219 - 	  bfd_boolean skip = FALSE;
   1.220 --	  struct name_list *list_tmp;
   1.221 --
   1.222 --	  /* Don't process sections from files which were
   1.223 --	     excluded.  */
   1.224 --	  for (list_tmp = sec->spec.exclude_name_list;
   1.225 --	       list_tmp;
   1.226 --	       list_tmp = list_tmp->next)
   1.227 --	    {
   1.228 --	      if (wildcardp (list_tmp->name))
   1.229 --		skip = fnmatch (list_tmp->name, file->filename, 0) == 0;
   1.230 --	      else
   1.231 --		skip = strcmp (list_tmp->name, file->filename) == 0;
   1.232 --
   1.233 --	      /* If this file is part of an archive, and the archive is
   1.234 --		 excluded, exclude this file.  */
   1.235 --	      if (! skip && file->the_bfd != NULL
   1.236 --		  && file->the_bfd->my_archive != NULL
   1.237 --		  && file->the_bfd->my_archive->filename != NULL)
   1.238 --		{
   1.239 --		  if (wildcardp (list_tmp->name))
   1.240 --		    skip = fnmatch (list_tmp->name,
   1.241 --				    file->the_bfd->my_archive->filename,
   1.242 --				    0) == 0;
   1.243 --		  else
   1.244 --		    skip = strcmp (list_tmp->name,
   1.245 --				   file->the_bfd->my_archive->filename) == 0;
   1.246 --		}
   1.247 --
   1.248 --	      if (skip)
   1.249 --		break;
   1.250 --	    }
   1.251 - 
   1.252 --	  if (!skip && sec->spec.name != NULL)
   1.253 -+	  if (sec->spec.name != NULL)
   1.254 - 	    {
   1.255 - 	      const char *sname = bfd_get_section_name (file->the_bfd, s);
   1.256 - 
   1.257 -@@ -203,13 +219,381 @@
   1.258 - 	    }
   1.259 - 
   1.260 - 	  if (!skip)
   1.261 --	    (*callback) (ptr, sec, s, file, data);
   1.262 -+	    walk_wild_consider_section (ptr, file, s, sec, callback, data);
   1.263 - 
   1.264 - 	  sec = sec->next;
   1.265 - 	}
   1.266 -     }
   1.267 - }
   1.268 - 
   1.269 -+/* Routines to find a single section given its name.  If there's more
   1.270 -+   than one section with that name, we report that.  */
   1.271 -+
   1.272 -+typedef struct
   1.273 -+{
   1.274 -+  asection *found_section;
   1.275 -+  bfd_boolean multiple_sections_found;
   1.276 -+} section_iterator_callback_data;
   1.277 -+
   1.278 -+static bfd_boolean
   1.279 -+section_iterator_callback (bfd *bfd ATTRIBUTE_UNUSED, asection *s, void *data)
   1.280 -+{
   1.281 -+  section_iterator_callback_data *d = data;
   1.282 -+
   1.283 -+  if (d->found_section != NULL)
   1.284 -+    {
   1.285 -+      d->multiple_sections_found = TRUE;
   1.286 -+      return TRUE;
   1.287 -+    }
   1.288 -+
   1.289 -+  d->found_section = s;
   1.290 -+  return FALSE;
   1.291 -+}
   1.292 -+
   1.293 -+static asection *
   1.294 -+find_section (lang_input_statement_type *file,
   1.295 -+	      struct wildcard_list *sec,
   1.296 -+	      bfd_boolean *multiple_sections_found)
   1.297 -+{
   1.298 -+  section_iterator_callback_data cb_data = { NULL, FALSE };
   1.299 -+
   1.300 -+  bfd_get_section_by_name_if (file->the_bfd, sec->spec.name, 
   1.301 -+			      section_iterator_callback, &cb_data);
   1.302 -+  *multiple_sections_found = cb_data.multiple_sections_found;
   1.303 -+  return cb_data.found_section;
   1.304 -+}
   1.305 -+
   1.306 -+/* Code for handling simple wildcards without going through fnmatch,
   1.307 -+   which can be expensive because of charset translations etc.  */
   1.308 -+
   1.309 -+/* A simple wild is a literal string followed by a single '*',
   1.310 -+   where the literal part is at least 4 characters long.  */
   1.311 -+
   1.312 -+static bfd_boolean
   1.313 -+is_simple_wild (const char *name)
   1.314 -+{
   1.315 -+  size_t len = strcspn (name, "*?[");
   1.316 -+  return len >= 4 && name[len] == '*' && name[len + 1] == '\0';
   1.317 -+}
   1.318 -+
   1.319 -+static bfd_boolean
   1.320 -+match_simple_wild (const char *pattern, const char *name)
   1.321 -+{
   1.322 -+  /* The first four characters of the pattern are guaranteed valid
   1.323 -+     non-wildcard characters.  So we can go faster.  */
   1.324 -+  if (pattern[0] != name[0] || pattern[1] != name[1]
   1.325 -+      || pattern[2] != name[2] || pattern[3] != name[3])
   1.326 -+    return FALSE;
   1.327 -+
   1.328 -+  pattern += 4;
   1.329 -+  name += 4;
   1.330 -+  while (*pattern != '*')
   1.331 -+    if (*name++ != *pattern++)
   1.332 -+      return FALSE;
   1.333 -+
   1.334 -+  return TRUE;
   1.335 -+}
   1.336 -+
   1.337 -+/* Specialized, optimized routines for handling different kinds of
   1.338 -+   wildcards */
   1.339 -+
   1.340 -+static void
   1.341 -+walk_wild_section_specs1_wild0 (lang_wild_statement_type *ptr,
   1.342 -+				lang_input_statement_type *file,
   1.343 -+				callback_t callback,
   1.344 -+				void *data)
   1.345 -+{
   1.346 -+  /* We can just do a hash lookup for the section with the right name.
   1.347 -+     But if that lookup discovers more than one section with the name
   1.348 -+     (should be rare), we fall back to the general algorithm because
   1.349 -+     we would otherwise have to sort the sections to make sure they
   1.350 -+     get processed in the bfd's order.  */
   1.351 -+  bfd_boolean multiple_sections_found;
   1.352 -+  struct wildcard_list *sec0 = ptr->handler_data[0];
   1.353 -+  asection *s0 = find_section (file, sec0, &multiple_sections_found);
   1.354 -+
   1.355 -+  if (multiple_sections_found)
   1.356 -+    walk_wild_section_general (ptr, file, callback, data);
   1.357 -+  else if (s0)
   1.358 -+    walk_wild_consider_section (ptr, file, s0, sec0, callback, data);
   1.359 -+}
   1.360 -+
   1.361 -+static void
   1.362 -+walk_wild_section_specs1_wild1 (lang_wild_statement_type *ptr,
   1.363 -+				lang_input_statement_type *file,
   1.364 -+				callback_t callback,
   1.365 -+				void *data)
   1.366 -+{
   1.367 -+  asection *s;
   1.368 -+  struct wildcard_list *wildsec0 = ptr->handler_data[0];
   1.369 -+
   1.370 -+  for (s = file->the_bfd->sections; s != NULL; s = s->next)
   1.371 -+    {
   1.372 -+      const char *sname = bfd_get_section_name (file->the_bfd, s);
   1.373 -+      bfd_boolean skip = !match_simple_wild (wildsec0->spec.name, sname);
   1.374 -+
   1.375 -+      if (!skip)
   1.376 -+	walk_wild_consider_section (ptr, file, s, wildsec0, callback, data);
   1.377 -+    }
   1.378 -+}
   1.379 -+
   1.380 -+static void
   1.381 -+walk_wild_section_specs2_wild1 (lang_wild_statement_type *ptr,
   1.382 -+				lang_input_statement_type *file,
   1.383 -+				callback_t callback,
   1.384 -+				void *data)
   1.385 -+{
   1.386 -+  asection *s;
   1.387 -+  struct wildcard_list *sec0 = ptr->handler_data[0];
   1.388 -+  struct wildcard_list *wildsec1 = ptr->handler_data[1];
   1.389 -+  bfd_boolean multiple_sections_found;
   1.390 -+  asection *s0 = find_section (file, sec0, &multiple_sections_found);
   1.391 -+
   1.392 -+  if (multiple_sections_found)
   1.393 -+    {
   1.394 -+      walk_wild_section_general (ptr, file, callback, data);
   1.395 -+      return;
   1.396 -+    }
   1.397 -+
   1.398 -+  /* Note that if the section was not found, s0 is NULL and
   1.399 -+     we'll simply never succeed the s == s0 test below.  */
   1.400 -+  for (s = file->the_bfd->sections; s != NULL; s = s->next)
   1.401 -+    {
   1.402 -+      /* Recall that in this code path, a section cannot satisfy more
   1.403 -+	 than one spec, so if s == s0 then it cannot match
   1.404 -+	 wildspec1.  */
   1.405 -+      if (s == s0)
   1.406 -+	walk_wild_consider_section (ptr, file, s, sec0, callback, data);
   1.407 -+      else
   1.408 -+	{
   1.409 -+	  const char *sname = bfd_get_section_name (file->the_bfd, s);
   1.410 -+	  bfd_boolean skip = !match_simple_wild (wildsec1->spec.name, sname);
   1.411 -+
   1.412 -+	  if (!skip)
   1.413 -+	    walk_wild_consider_section (ptr, file, s, wildsec1, callback,
   1.414 -+					data);
   1.415 -+	}
   1.416 -+    }
   1.417 -+}
   1.418 -+
   1.419 -+static void
   1.420 -+walk_wild_section_specs3_wild2 (lang_wild_statement_type *ptr,
   1.421 -+				lang_input_statement_type *file,
   1.422 -+				callback_t callback,
   1.423 -+				void *data)
   1.424 -+{
   1.425 -+  asection *s;
   1.426 -+  struct wildcard_list *sec0 = ptr->handler_data[0];
   1.427 -+  struct wildcard_list *wildsec1 = ptr->handler_data[1];
   1.428 -+  struct wildcard_list *wildsec2 = ptr->handler_data[2];
   1.429 -+  bfd_boolean multiple_sections_found;
   1.430 -+  asection *s0 = find_section (file, sec0, &multiple_sections_found);
   1.431 -+
   1.432 -+  if (multiple_sections_found)
   1.433 -+    {
   1.434 -+      walk_wild_section_general (ptr, file, callback, data);
   1.435 -+      return;
   1.436 -+    }
   1.437 -+
   1.438 -+  for (s = file->the_bfd->sections; s != NULL; s = s->next)
   1.439 -+    {
   1.440 -+      if (s == s0)
   1.441 -+	walk_wild_consider_section (ptr, file, s, sec0, callback, data);
   1.442 -+      else
   1.443 -+	{
   1.444 -+	  const char *sname = bfd_get_section_name (file->the_bfd, s);
   1.445 -+	  bfd_boolean skip = !match_simple_wild (wildsec1->spec.name, sname);
   1.446 -+
   1.447 -+	  if (!skip)
   1.448 -+	    walk_wild_consider_section (ptr, file, s, wildsec1, callback, data);
   1.449 -+	  else
   1.450 -+	    {
   1.451 -+	      skip = !match_simple_wild (wildsec2->spec.name, sname);
   1.452 -+	      if (!skip)
   1.453 -+		walk_wild_consider_section (ptr, file, s, wildsec2, callback,
   1.454 -+					    data);
   1.455 -+	    }
   1.456 -+	}
   1.457 -+    }
   1.458 -+}
   1.459 -+
   1.460 -+static void
   1.461 -+walk_wild_section_specs4_wild2 (lang_wild_statement_type *ptr,
   1.462 -+				lang_input_statement_type *file,
   1.463 -+				callback_t callback,
   1.464 -+				void *data)
   1.465 -+{
   1.466 -+  asection *s;
   1.467 -+  struct wildcard_list *sec0 = ptr->handler_data[0];
   1.468 -+  struct wildcard_list *sec1 = ptr->handler_data[1];
   1.469 -+  struct wildcard_list *wildsec2 = ptr->handler_data[2];
   1.470 -+  struct wildcard_list *wildsec3 = ptr->handler_data[3];
   1.471 -+  bfd_boolean multiple_sections_found;
   1.472 -+  asection *s0 = find_section (file, sec0, &multiple_sections_found), *s1;
   1.473 -+
   1.474 -+  if (multiple_sections_found)
   1.475 -+    {
   1.476 -+      walk_wild_section_general (ptr, file, callback, data);
   1.477 -+      return;
   1.478 -+    }
   1.479 -+
   1.480 -+  s1 = find_section (file, sec1, &multiple_sections_found);
   1.481 -+  if (multiple_sections_found)
   1.482 -+    {
   1.483 -+      walk_wild_section_general (ptr, file, callback, data);
   1.484 -+      return;
   1.485 -+    }
   1.486 -+
   1.487 -+  for (s = file->the_bfd->sections; s != NULL; s = s->next)
   1.488 -+    {
   1.489 -+      if (s == s0)
   1.490 -+	walk_wild_consider_section (ptr, file, s, sec0, callback, data);
   1.491 -+      else
   1.492 -+	if (s == s1)
   1.493 -+	  walk_wild_consider_section (ptr, file, s, sec1, callback, data);
   1.494 -+	else
   1.495 -+	  {
   1.496 -+	    const char *sname = bfd_get_section_name (file->the_bfd, s);
   1.497 -+	    bfd_boolean skip = !match_simple_wild (wildsec2->spec.name,
   1.498 -+						   sname);
   1.499 -+
   1.500 -+	    if (!skip)
   1.501 -+	      walk_wild_consider_section (ptr, file, s, wildsec2, callback,
   1.502 -+					  data);
   1.503 -+	    else
   1.504 -+	      {
   1.505 -+		skip = !match_simple_wild (wildsec3->spec.name, sname);
   1.506 -+		if (!skip)
   1.507 -+		  walk_wild_consider_section (ptr, file, s, wildsec3,
   1.508 -+					      callback, data);
   1.509 -+	      }
   1.510 -+	  }
   1.511 -+    }
   1.512 -+}
   1.513 -+
   1.514 -+static void
   1.515 -+walk_wild_section (lang_wild_statement_type *ptr,
   1.516 -+		   lang_input_statement_type *file,
   1.517 -+		   callback_t callback,
   1.518 -+		   void *data)
   1.519 -+{
   1.520 -+  if (file->just_syms_flag)
   1.521 -+    return;
   1.522 -+
   1.523 -+  (*ptr->walk_wild_section_handler) (ptr, file, callback, data);
   1.524 -+}
   1.525 -+
   1.526 -+/* Returns TRUE when name1 is a wildcard spec that might match
   1.527 -+   something name2 can match.  We're conservative: we return FALSE
   1.528 -+   only if the prefixes of name1 and name2 are different up to the
   1.529 -+   first wildcard character.  */
   1.530 -+
   1.531 -+static bfd_boolean
   1.532 -+wild_spec_can_overlap (const char *name1, const char *name2)
   1.533 -+{
   1.534 -+  size_t prefix1_len = strcspn (name1, "?*[");
   1.535 -+  size_t prefix2_len = strcspn (name2, "?*[");
   1.536 -+  size_t min_prefix_len;
   1.537 -+
   1.538 -+  /* Note that if there is no wildcard character, then we treat the
   1.539 -+     terminating 0 as part of the prefix.  Thus ".text" won't match
   1.540 -+     ".text." or ".text.*", for example.  */
   1.541 -+  if (name1[prefix1_len] == '\0')
   1.542 -+    prefix1_len++;
   1.543 -+  if (name2[prefix2_len] == '\0')
   1.544 -+    prefix2_len++;
   1.545 -+
   1.546 -+  min_prefix_len = prefix1_len < prefix2_len ? prefix1_len : prefix2_len;
   1.547 -+
   1.548 -+  return memcmp (name1, name2, min_prefix_len) == 0;
   1.549 -+}
   1.550 -+
   1.551 -+/* Select specialized code to handle various kinds of wildcard
   1.552 -+   statements.  */
   1.553 -+
   1.554 -+static void
   1.555 -+analyze_walk_wild_section_handler (lang_wild_statement_type *ptr)
   1.556 -+{
   1.557 -+  int sec_count = 0;
   1.558 -+  int wild_name_count = 0;
   1.559 -+  struct wildcard_list *sec;
   1.560 -+  int signature;
   1.561 -+  int data_counter;
   1.562 -+
   1.563 -+  ptr->walk_wild_section_handler = walk_wild_section_general;
   1.564 -+
   1.565 -+  /* Count how many wildcard_specs there are, and how many of those
   1.566 -+     actually use wildcards in the name.  Also, bail out if any of the
   1.567 -+     wildcard names are NULL. (Can this actually happen?
   1.568 -+     walk_wild_section used to test for it.)  And bail out if any
   1.569 -+     of the wildcards are more complex than a simple string
   1.570 -+     ending in a single '*'.  */
   1.571 -+  for (sec = ptr->section_list; sec != NULL; sec = sec->next)
   1.572 -+    {
   1.573 -+      ++sec_count;
   1.574 -+      if (sec->spec.name == NULL)
   1.575 -+	return;
   1.576 -+      if (wildcardp (sec->spec.name))
   1.577 -+	{
   1.578 -+	  ++wild_name_count;
   1.579 -+	  if (!is_simple_wild (sec->spec.name))
   1.580 -+	    return;
   1.581 -+	}
   1.582 -+    }
   1.583 -+
   1.584 -+  /* The zero-spec case would be easy to optimize but it doesn't
   1.585 -+     happen in practice.  Likewise, more than 4 specs doesn't
   1.586 -+     happen in practice.  */
   1.587 -+  if (sec_count == 0 || sec_count > 4)
   1.588 -+    return;
   1.589 -+
   1.590 -+  /* Check that no two specs can match the same section.  */
   1.591 -+  for (sec = ptr->section_list; sec != NULL; sec = sec->next)
   1.592 -+    {
   1.593 -+      struct wildcard_list *sec2;
   1.594 -+      for (sec2 = sec->next; sec2 != NULL; sec2 = sec2->next)
   1.595 -+	{
   1.596 -+	  if (wild_spec_can_overlap (sec->spec.name, sec2->spec.name))
   1.597 -+	    return;
   1.598 -+	}
   1.599 -+    }
   1.600 -+
   1.601 -+  signature = (sec_count << 8) + wild_name_count;
   1.602 -+  switch (signature)
   1.603 -+    {
   1.604 -+    case 0x0100:
   1.605 -+      ptr->walk_wild_section_handler = walk_wild_section_specs1_wild0;
   1.606 -+      break;
   1.607 -+    case 0x0101:
   1.608 -+      ptr->walk_wild_section_handler = walk_wild_section_specs1_wild1;
   1.609 -+      break;
   1.610 -+    case 0x0201:
   1.611 -+      ptr->walk_wild_section_handler = walk_wild_section_specs2_wild1;
   1.612 -+      break;
   1.613 -+    case 0x0302:
   1.614 -+      ptr->walk_wild_section_handler = walk_wild_section_specs3_wild2;
   1.615 -+      break;
   1.616 -+    case 0x0402:
   1.617 -+      ptr->walk_wild_section_handler = walk_wild_section_specs4_wild2;
   1.618 -+      break;
   1.619 -+    default:
   1.620 -+      return;
   1.621 -+    }
   1.622 -+
   1.623 -+  /* Now fill the data array with pointers to the specs, first the
   1.624 -+     specs with non-wildcard names, then the specs with wildcard
   1.625 -+     names.  It's OK to process the specs in different order from the
   1.626 -+     given order, because we've already determined that no section
   1.627 -+     will match more than one spec.  */
   1.628 -+  data_counter = 0;
   1.629 -+  for (sec = ptr->section_list; sec != NULL; sec = sec->next)
   1.630 -+    if (!wildcardp (sec->spec.name))
   1.631 -+      ptr->handler_data[data_counter++] = sec;
   1.632 -+  for (sec = ptr->section_list; sec != NULL; sec = sec->next)
   1.633 -+    if (wildcardp (sec->spec.name))
   1.634 -+      ptr->handler_data[data_counter++] = sec;
   1.635 -+}
   1.636 -+
   1.637 - /* Handle a wild statement for a single file F.  */
   1.638 - 
   1.639 - static void
   1.640 -@@ -4353,6 +4737,7 @@
   1.641 -   new->section_list = section_list;
   1.642 -   new->keep_sections = keep_sections;
   1.643 -   lang_list_init (&new->children);
   1.644 -+  analyze_walk_wild_section_handler (new);
   1.645 - }
   1.646 - 
   1.647 - void
   1.648 ---- binutils-2.15/ld/ldlang.h.old	2004-05-17 15:36:16.000000000 -0400
   1.649 -+++ binutils-2.15/ld/ldlang.h	2006-01-23 13:32:33.653292000 -0500
   1.650 -@@ -295,7 +295,17 @@
   1.651 -   union lang_statement_union *file;
   1.652 - } lang_afile_asection_pair_statement_type;
   1.653 - 
   1.654 --typedef struct lang_wild_statement_struct
   1.655 -+typedef struct lang_wild_statement_struct lang_wild_statement_type;
   1.656 -+
   1.657 -+typedef void (*callback_t) (lang_wild_statement_type *, struct wildcard_list *,
   1.658 -+			    asection *, lang_input_statement_type *, void *);
   1.659 -+
   1.660 -+typedef void (*walk_wild_section_handler_t) (lang_wild_statement_type *,
   1.661 -+					     lang_input_statement_type *,
   1.662 -+					     callback_t callback,
   1.663 -+					     void *data);
   1.664 -+
   1.665 -+struct lang_wild_statement_struct
   1.666 - {
   1.667 -   lang_statement_header_type header;
   1.668 -   const char *filename;
   1.669 -@@ -303,7 +313,10 @@
   1.670 -   struct wildcard_list *section_list;
   1.671 -   bfd_boolean keep_sections;
   1.672 -   lang_statement_list_type children;
   1.673 --} lang_wild_statement_type;
   1.674 -+
   1.675 -+  walk_wild_section_handler_t walk_wild_section_handler;
   1.676 -+  struct wildcard_list *handler_data[4];
   1.677 -+};
   1.678 - 
   1.679 - typedef struct lang_address_statement_struct
   1.680 - {