patches/binutils/2.15/240-ld-callahan.patch
author "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
Fri Sep 04 17:27:16 2009 +0200 (2009-09-04)
changeset 1512 439a6b292917
parent 745 e445c00d134d
permissions -rw-r--r--
TODO: update

Add TODO list for m4, autoconf, automake and libtool.
Building our own versions would remove burden from the users
who have older versions on their distributions, and are not
ready/able/allowed to upgrade.
     1 Signed-off-by: dank@kegel.com
     2 Fixes ld speed issue. 
     3 See http://weblogs.mozillazine.org/roc/archives/2005/02/optimizing_gnu.html
     4 See thread "Re: optimizations for 3x speedup in ld",
     5 http://sources.redhat.com/ml/binutils/2005-03/msg00847.html
     6 
     7 Wildcard section matching enhancement, backported from the binutils CVS tree.
     8 Here's the CVS log comment from the original change to ldlang.c:
     9 
    10 revision 1.177
    11 date: 2005/04/06 15:33:02;  author: jakub;  state: Exp;  lines: +438 -51
    12 2005-04-06  Jakub Jelinek  <jakub@redhat.com>
    13 
    14         * ldlang.c: Formatting.
    15         (walk_wild_consider_section): Remember return value from wildcardp.
    16         (is_simple_wild): Use strcspn instead of 2 strpbrk calls and strlen.
    17         (wild_spec_can_overlap): Use strcspn instead of strpbrk and strlen.
    18 
    19 2005-04-06  Robert O'Callahan  <rocallahan@novell.com>
    20 
    21         * ld.h (lean_section_userdata_type): Remove.
    22         (fat_section_userdata_type): Remove file field.
    23         (SECTION_USERDATA_SIZE): Remove.
    24         * ldlang.c (init_os): Eliminate initialization of unused
    25         lean_section_userdata_type.
    26 
    27         * ldlang.h (callback_t, walk_wild_section_handler_t): New
    28         typedefs.
    29         (struct lang_wild_statement_struct): Add walk_wild_section_handler
    30         and handler_data fields.
    31         * ldlang.c (callback_t): Removed.
    32         (walk_wild_consider_section, walk_wild_section_general,
    33         section_iterator_callback, find_section, is_simple_wild,
    34         match_simple_wild, walk_wild_section_specs1_wild0,
    35         walk_wild_section_specs1_wild1, walk_wild_section_specs2_wild1,
    36         walk_wild_section_specs3_wild2, walk_wild_section_specs4_wild2,
    37         wild_spec_can_overlap, analyze_walk_wild_section_handler): New
    38         functions.
    39         (lang_add_wild): Call analyze_walk_wild_section_handler.
    40         (walk_wild_section): Renamed to walk_wild_section_general and
    41         created a wrapper function.
    42         (section_iterator_callback_data): New typedef.
    43 
    44 Note that bfd_get_section_by_name_if didn't exist in 2.15, so it was backported
    45 as well.
    46 
    47 --- binutils-2.15/bfd/bfd-in2.h.old	2004-05-17 15:35:56.000000000 -0400
    48 +++ binutils-2.15/bfd/bfd-in2.h	2006-02-09 11:54:45.989940000 -0500
    49 @@ -1425,6 +1425,10 @@
    50  
    51  asection *bfd_get_section_by_name (bfd *abfd, const char *name);
    52  
    53 +asection *bfd_get_section_by_name_if (bfd *abfd, const char *name,
    54 +   bfd_boolean (*operation) (bfd *, asection *, void *),
    55 +   void *user_storage);
    56 +
    57  char *bfd_get_unique_section_name
    58     (bfd *abfd, const char *templat, int *count);
    59  
    60 --- binutils-2.15/bfd/section.c.old	2003-12-01 01:33:01.000000000 -0500
    61 +++ binutils-2.15/bfd/section.c	2006-01-23 14:16:54.768993000 -0500
    62 @@ -801,6 +801,57 @@
    63  
    64  /*
    65  FUNCTION
    66 +	bfd_get_section_by_name_if
    67 +
    68 +SYNOPSIS
    69 +	asection *bfd_get_section_by_name_if
    70 +	  (bfd *abfd,
    71 +	   const char *name,
    72 +	   bfd_boolean (*func) (bfd *abfd, asection *sect, void *obj),
    73 +	   void *obj);
    74 +
    75 +DESCRIPTION
    76 +	Call the provided function @var{func} for each section
    77 +	attached to the BFD @var{abfd} whose name matches @var{name},
    78 +	passing @var{obj} as an argument. The function will be called
    79 +	as if by
    80 +
    81 +|	func (abfd, the_section, obj);
    82 +
    83 +	It returns the first section for which @var{func} returns true,
    84 +	otherwise <<NULL>>.
    85 +
    86 +*/
    87 +
    88 +asection *
    89 +bfd_get_section_by_name_if (bfd *abfd, const char *name,
    90 +			    bfd_boolean (*operation) (bfd *,
    91 +						      asection *,
    92 +						      void *),
    93 +			    void *user_storage)
    94 +{
    95 +  struct section_hash_entry *sh;
    96 +  unsigned long hash;
    97 +
    98 +  sh = section_hash_lookup (&abfd->section_htab, name, FALSE, FALSE);
    99 +  if (sh == NULL)
   100 +    return NULL;
   101 +
   102 +  hash = sh->root.hash;
   103 +  do
   104 +    {
   105 +      if ((*operation) (abfd, &sh->section, user_storage))
   106 +	return &sh->section;
   107 +      sh = (struct section_hash_entry *) sh->root.next;
   108 +    }
   109 +  while (sh != NULL && sh->root.hash == hash
   110 +	 && strcmp (sh->root.string, name) == 0);
   111 +
   112 +  return NULL;
   113 +}
   114 +
   115 +/*
   116 +FUNCTION
   117  	bfd_get_unique_section_name
   118  
   119  SYNOPSIS
   120 --- binutils-2.15/ld/ldlang.c.old	2004-05-17 15:36:16.000000000 -0400
   121 +++ binutils-2.15/ld/ldlang.c	2006-01-23 13:40:12.745499000 -0500
   122 @@ -81,9 +81,6 @@
   123  static void lang_record_phdrs (void);
   124  static void lang_do_version_exports_section (void);
   125  
   126 -typedef void (*callback_t) (lang_wild_statement_type *, struct wildcard_list *,
   127 -			    asection *, lang_input_statement_type *, void *);
   128 -
   129  /* Exported variables.  */
   130  lang_output_section_statement_type *abs_output_section;
   131  lang_statement_list_type lang_output_section_statement;
   132 @@ -138,21 +135,71 @@
   133  
   134  /* Generic traversal routines for finding matching sections.  */
   135  
   136 +/* Try processing a section against a wildcard.  This just calls
   137 +   the callback unless the filename exclusion list is present
   138 +   and excludes the file.  It's hardly ever present so this
   139 +   function is very fast.  */
   140 +
   141 +static void
   142 +walk_wild_consider_section (lang_wild_statement_type *ptr,
   143 +			    lang_input_statement_type *file,
   144 +			    asection *s,
   145 +			    struct wildcard_list *sec,
   146 +			    callback_t callback,
   147 +			    void *data)
   148 +{
   149 +  bfd_boolean skip = FALSE;
   150 +  struct name_list *list_tmp;
   151 +
   152 +  /* Don't process sections from files which were
   153 +     excluded.  */
   154 +  for (list_tmp = sec->spec.exclude_name_list;
   155 +       list_tmp;
   156 +       list_tmp = list_tmp->next)
   157 +    {
   158 +      bfd_boolean is_wildcard = wildcardp (list_tmp->name);
   159 +      if (is_wildcard)
   160 +	skip = fnmatch (list_tmp->name, file->filename, 0) == 0;
   161 +      else
   162 +	skip = strcmp (list_tmp->name, file->filename) == 0;
   163 +
   164 +      /* If this file is part of an archive, and the archive is
   165 +	 excluded, exclude this file.  */
   166 +      if (! skip && file->the_bfd != NULL
   167 +	  && file->the_bfd->my_archive != NULL
   168 +	  && file->the_bfd->my_archive->filename != NULL)
   169 +	{
   170 +	  if (is_wildcard)
   171 +	    skip = fnmatch (list_tmp->name,
   172 +			    file->the_bfd->my_archive->filename,
   173 +			    0) == 0;
   174 +	  else
   175 +	    skip = strcmp (list_tmp->name,
   176 +			   file->the_bfd->my_archive->filename) == 0;
   177 +	}
   178 +
   179 +      if (skip)
   180 +	break;
   181 +    }
   182 +
   183 +  if (!skip)
   184 +    (*callback) (ptr, sec, s, file, data);
   185 +}
   186 +
   187 +/* Lowest common denominator routine that can handle everything correctly,
   188 +   but slowly.  */
   189 +
   190  static void
   191 -walk_wild_section (lang_wild_statement_type *ptr,
   192 -		   lang_input_statement_type *file,
   193 -		   callback_t callback,
   194 -		   void *data)
   195 +walk_wild_section_general (lang_wild_statement_type *ptr,
   196 +			   lang_input_statement_type *file,
   197 +			   callback_t callback,
   198 +			   void *data)
   199  {
   200    asection *s;
   201 -
   202 -  if (file->just_syms_flag)
   203 -    return;
   204 +  struct wildcard_list *sec;
   205  
   206    for (s = file->the_bfd->sections; s != NULL; s = s->next)
   207      {
   208 -      struct wildcard_list *sec;
   209 -
   210        sec = ptr->section_list;
   211        if (sec == NULL)
   212  	(*callback) (ptr, sec, s, file, data);
   213 @@ -160,39 +207,8 @@
   214        while (sec != NULL)
   215  	{
   216  	  bfd_boolean skip = FALSE;
   217 -	  struct name_list *list_tmp;
   218 -
   219 -	  /* Don't process sections from files which were
   220 -	     excluded.  */
   221 -	  for (list_tmp = sec->spec.exclude_name_list;
   222 -	       list_tmp;
   223 -	       list_tmp = list_tmp->next)
   224 -	    {
   225 -	      if (wildcardp (list_tmp->name))
   226 -		skip = fnmatch (list_tmp->name, file->filename, 0) == 0;
   227 -	      else
   228 -		skip = strcmp (list_tmp->name, file->filename) == 0;
   229 -
   230 -	      /* If this file is part of an archive, and the archive is
   231 -		 excluded, exclude this file.  */
   232 -	      if (! skip && file->the_bfd != NULL
   233 -		  && file->the_bfd->my_archive != NULL
   234 -		  && file->the_bfd->my_archive->filename != NULL)
   235 -		{
   236 -		  if (wildcardp (list_tmp->name))
   237 -		    skip = fnmatch (list_tmp->name,
   238 -				    file->the_bfd->my_archive->filename,
   239 -				    0) == 0;
   240 -		  else
   241 -		    skip = strcmp (list_tmp->name,
   242 -				   file->the_bfd->my_archive->filename) == 0;
   243 -		}
   244 -
   245 -	      if (skip)
   246 -		break;
   247 -	    }
   248  
   249 -	  if (!skip && sec->spec.name != NULL)
   250 +	  if (sec->spec.name != NULL)
   251  	    {
   252  	      const char *sname = bfd_get_section_name (file->the_bfd, s);
   253  
   254 @@ -203,13 +219,381 @@
   255  	    }
   256  
   257  	  if (!skip)
   258 -	    (*callback) (ptr, sec, s, file, data);
   259 +	    walk_wild_consider_section (ptr, file, s, sec, callback, data);
   260  
   261  	  sec = sec->next;
   262  	}
   263      }
   264  }
   265  
   266 +/* Routines to find a single section given its name.  If there's more
   267 +   than one section with that name, we report that.  */
   268 +
   269 +typedef struct
   270 +{
   271 +  asection *found_section;
   272 +  bfd_boolean multiple_sections_found;
   273 +} section_iterator_callback_data;
   274 +
   275 +static bfd_boolean
   276 +section_iterator_callback (bfd *bfd ATTRIBUTE_UNUSED, asection *s, void *data)
   277 +{
   278 +  section_iterator_callback_data *d = data;
   279 +
   280 +  if (d->found_section != NULL)
   281 +    {
   282 +      d->multiple_sections_found = TRUE;
   283 +      return TRUE;
   284 +    }
   285 +
   286 +  d->found_section = s;
   287 +  return FALSE;
   288 +}
   289 +
   290 +static asection *
   291 +find_section (lang_input_statement_type *file,
   292 +	      struct wildcard_list *sec,
   293 +	      bfd_boolean *multiple_sections_found)
   294 +{
   295 +  section_iterator_callback_data cb_data = { NULL, FALSE };
   296 +
   297 +  bfd_get_section_by_name_if (file->the_bfd, sec->spec.name, 
   298 +			      section_iterator_callback, &cb_data);
   299 +  *multiple_sections_found = cb_data.multiple_sections_found;
   300 +  return cb_data.found_section;
   301 +}
   302 +
   303 +/* Code for handling simple wildcards without going through fnmatch,
   304 +   which can be expensive because of charset translations etc.  */
   305 +
   306 +/* A simple wild is a literal string followed by a single '*',
   307 +   where the literal part is at least 4 characters long.  */
   308 +
   309 +static bfd_boolean
   310 +is_simple_wild (const char *name)
   311 +{
   312 +  size_t len = strcspn (name, "*?[");
   313 +  return len >= 4 && name[len] == '*' && name[len + 1] == '\0';
   314 +}
   315 +
   316 +static bfd_boolean
   317 +match_simple_wild (const char *pattern, const char *name)
   318 +{
   319 +  /* The first four characters of the pattern are guaranteed valid
   320 +     non-wildcard characters.  So we can go faster.  */
   321 +  if (pattern[0] != name[0] || pattern[1] != name[1]
   322 +      || pattern[2] != name[2] || pattern[3] != name[3])
   323 +    return FALSE;
   324 +
   325 +  pattern += 4;
   326 +  name += 4;
   327 +  while (*pattern != '*')
   328 +    if (*name++ != *pattern++)
   329 +      return FALSE;
   330 +
   331 +  return TRUE;
   332 +}
   333 +
   334 +/* Specialized, optimized routines for handling different kinds of
   335 +   wildcards */
   336 +
   337 +static void
   338 +walk_wild_section_specs1_wild0 (lang_wild_statement_type *ptr,
   339 +				lang_input_statement_type *file,
   340 +				callback_t callback,
   341 +				void *data)
   342 +{
   343 +  /* We can just do a hash lookup for the section with the right name.
   344 +     But if that lookup discovers more than one section with the name
   345 +     (should be rare), we fall back to the general algorithm because
   346 +     we would otherwise have to sort the sections to make sure they
   347 +     get processed in the bfd's order.  */
   348 +  bfd_boolean multiple_sections_found;
   349 +  struct wildcard_list *sec0 = ptr->handler_data[0];
   350 +  asection *s0 = find_section (file, sec0, &multiple_sections_found);
   351 +
   352 +  if (multiple_sections_found)
   353 +    walk_wild_section_general (ptr, file, callback, data);
   354 +  else if (s0)
   355 +    walk_wild_consider_section (ptr, file, s0, sec0, callback, data);
   356 +}
   357 +
   358 +static void
   359 +walk_wild_section_specs1_wild1 (lang_wild_statement_type *ptr,
   360 +				lang_input_statement_type *file,
   361 +				callback_t callback,
   362 +				void *data)
   363 +{
   364 +  asection *s;
   365 +  struct wildcard_list *wildsec0 = ptr->handler_data[0];
   366 +
   367 +  for (s = file->the_bfd->sections; s != NULL; s = s->next)
   368 +    {
   369 +      const char *sname = bfd_get_section_name (file->the_bfd, s);
   370 +      bfd_boolean skip = !match_simple_wild (wildsec0->spec.name, sname);
   371 +
   372 +      if (!skip)
   373 +	walk_wild_consider_section (ptr, file, s, wildsec0, callback, data);
   374 +    }
   375 +}
   376 +
   377 +static void
   378 +walk_wild_section_specs2_wild1 (lang_wild_statement_type *ptr,
   379 +				lang_input_statement_type *file,
   380 +				callback_t callback,
   381 +				void *data)
   382 +{
   383 +  asection *s;
   384 +  struct wildcard_list *sec0 = ptr->handler_data[0];
   385 +  struct wildcard_list *wildsec1 = ptr->handler_data[1];
   386 +  bfd_boolean multiple_sections_found;
   387 +  asection *s0 = find_section (file, sec0, &multiple_sections_found);
   388 +
   389 +  if (multiple_sections_found)
   390 +    {
   391 +      walk_wild_section_general (ptr, file, callback, data);
   392 +      return;
   393 +    }
   394 +
   395 +  /* Note that if the section was not found, s0 is NULL and
   396 +     we'll simply never succeed the s == s0 test below.  */
   397 +  for (s = file->the_bfd->sections; s != NULL; s = s->next)
   398 +    {
   399 +      /* Recall that in this code path, a section cannot satisfy more
   400 +	 than one spec, so if s == s0 then it cannot match
   401 +	 wildspec1.  */
   402 +      if (s == s0)
   403 +	walk_wild_consider_section (ptr, file, s, sec0, callback, data);
   404 +      else
   405 +	{
   406 +	  const char *sname = bfd_get_section_name (file->the_bfd, s);
   407 +	  bfd_boolean skip = !match_simple_wild (wildsec1->spec.name, sname);
   408 +
   409 +	  if (!skip)
   410 +	    walk_wild_consider_section (ptr, file, s, wildsec1, callback,
   411 +					data);
   412 +	}
   413 +    }
   414 +}
   415 +
   416 +static void
   417 +walk_wild_section_specs3_wild2 (lang_wild_statement_type *ptr,
   418 +				lang_input_statement_type *file,
   419 +				callback_t callback,
   420 +				void *data)
   421 +{
   422 +  asection *s;
   423 +  struct wildcard_list *sec0 = ptr->handler_data[0];
   424 +  struct wildcard_list *wildsec1 = ptr->handler_data[1];
   425 +  struct wildcard_list *wildsec2 = ptr->handler_data[2];
   426 +  bfd_boolean multiple_sections_found;
   427 +  asection *s0 = find_section (file, sec0, &multiple_sections_found);
   428 +
   429 +  if (multiple_sections_found)
   430 +    {
   431 +      walk_wild_section_general (ptr, file, callback, data);
   432 +      return;
   433 +    }
   434 +
   435 +  for (s = file->the_bfd->sections; s != NULL; s = s->next)
   436 +    {
   437 +      if (s == s0)
   438 +	walk_wild_consider_section (ptr, file, s, sec0, callback, data);
   439 +      else
   440 +	{
   441 +	  const char *sname = bfd_get_section_name (file->the_bfd, s);
   442 +	  bfd_boolean skip = !match_simple_wild (wildsec1->spec.name, sname);
   443 +
   444 +	  if (!skip)
   445 +	    walk_wild_consider_section (ptr, file, s, wildsec1, callback, data);
   446 +	  else
   447 +	    {
   448 +	      skip = !match_simple_wild (wildsec2->spec.name, sname);
   449 +	      if (!skip)
   450 +		walk_wild_consider_section (ptr, file, s, wildsec2, callback,
   451 +					    data);
   452 +	    }
   453 +	}
   454 +    }
   455 +}
   456 +
   457 +static void
   458 +walk_wild_section_specs4_wild2 (lang_wild_statement_type *ptr,
   459 +				lang_input_statement_type *file,
   460 +				callback_t callback,
   461 +				void *data)
   462 +{
   463 +  asection *s;
   464 +  struct wildcard_list *sec0 = ptr->handler_data[0];
   465 +  struct wildcard_list *sec1 = ptr->handler_data[1];
   466 +  struct wildcard_list *wildsec2 = ptr->handler_data[2];
   467 +  struct wildcard_list *wildsec3 = ptr->handler_data[3];
   468 +  bfd_boolean multiple_sections_found;
   469 +  asection *s0 = find_section (file, sec0, &multiple_sections_found), *s1;
   470 +
   471 +  if (multiple_sections_found)
   472 +    {
   473 +      walk_wild_section_general (ptr, file, callback, data);
   474 +      return;
   475 +    }
   476 +
   477 +  s1 = find_section (file, sec1, &multiple_sections_found);
   478 +  if (multiple_sections_found)
   479 +    {
   480 +      walk_wild_section_general (ptr, file, callback, data);
   481 +      return;
   482 +    }
   483 +
   484 +  for (s = file->the_bfd->sections; s != NULL; s = s->next)
   485 +    {
   486 +      if (s == s0)
   487 +	walk_wild_consider_section (ptr, file, s, sec0, callback, data);
   488 +      else
   489 +	if (s == s1)
   490 +	  walk_wild_consider_section (ptr, file, s, sec1, callback, data);
   491 +	else
   492 +	  {
   493 +	    const char *sname = bfd_get_section_name (file->the_bfd, s);
   494 +	    bfd_boolean skip = !match_simple_wild (wildsec2->spec.name,
   495 +						   sname);
   496 +
   497 +	    if (!skip)
   498 +	      walk_wild_consider_section (ptr, file, s, wildsec2, callback,
   499 +					  data);
   500 +	    else
   501 +	      {
   502 +		skip = !match_simple_wild (wildsec3->spec.name, sname);
   503 +		if (!skip)
   504 +		  walk_wild_consider_section (ptr, file, s, wildsec3,
   505 +					      callback, data);
   506 +	      }
   507 +	  }
   508 +    }
   509 +}
   510 +
   511 +static void
   512 +walk_wild_section (lang_wild_statement_type *ptr,
   513 +		   lang_input_statement_type *file,
   514 +		   callback_t callback,
   515 +		   void *data)
   516 +{
   517 +  if (file->just_syms_flag)
   518 +    return;
   519 +
   520 +  (*ptr->walk_wild_section_handler) (ptr, file, callback, data);
   521 +}
   522 +
   523 +/* Returns TRUE when name1 is a wildcard spec that might match
   524 +   something name2 can match.  We're conservative: we return FALSE
   525 +   only if the prefixes of name1 and name2 are different up to the
   526 +   first wildcard character.  */
   527 +
   528 +static bfd_boolean
   529 +wild_spec_can_overlap (const char *name1, const char *name2)
   530 +{
   531 +  size_t prefix1_len = strcspn (name1, "?*[");
   532 +  size_t prefix2_len = strcspn (name2, "?*[");
   533 +  size_t min_prefix_len;
   534 +
   535 +  /* Note that if there is no wildcard character, then we treat the
   536 +     terminating 0 as part of the prefix.  Thus ".text" won't match
   537 +     ".text." or ".text.*", for example.  */
   538 +  if (name1[prefix1_len] == '\0')
   539 +    prefix1_len++;
   540 +  if (name2[prefix2_len] == '\0')
   541 +    prefix2_len++;
   542 +
   543 +  min_prefix_len = prefix1_len < prefix2_len ? prefix1_len : prefix2_len;
   544 +
   545 +  return memcmp (name1, name2, min_prefix_len) == 0;
   546 +}
   547 +
   548 +/* Select specialized code to handle various kinds of wildcard
   549 +   statements.  */
   550 +
   551 +static void
   552 +analyze_walk_wild_section_handler (lang_wild_statement_type *ptr)
   553 +{
   554 +  int sec_count = 0;
   555 +  int wild_name_count = 0;
   556 +  struct wildcard_list *sec;
   557 +  int signature;
   558 +  int data_counter;
   559 +
   560 +  ptr->walk_wild_section_handler = walk_wild_section_general;
   561 +
   562 +  /* Count how many wildcard_specs there are, and how many of those
   563 +     actually use wildcards in the name.  Also, bail out if any of the
   564 +     wildcard names are NULL. (Can this actually happen?
   565 +     walk_wild_section used to test for it.)  And bail out if any
   566 +     of the wildcards are more complex than a simple string
   567 +     ending in a single '*'.  */
   568 +  for (sec = ptr->section_list; sec != NULL; sec = sec->next)
   569 +    {
   570 +      ++sec_count;
   571 +      if (sec->spec.name == NULL)
   572 +	return;
   573 +      if (wildcardp (sec->spec.name))
   574 +	{
   575 +	  ++wild_name_count;
   576 +	  if (!is_simple_wild (sec->spec.name))
   577 +	    return;
   578 +	}
   579 +    }
   580 +
   581 +  /* The zero-spec case would be easy to optimize but it doesn't
   582 +     happen in practice.  Likewise, more than 4 specs doesn't
   583 +     happen in practice.  */
   584 +  if (sec_count == 0 || sec_count > 4)
   585 +    return;
   586 +
   587 +  /* Check that no two specs can match the same section.  */
   588 +  for (sec = ptr->section_list; sec != NULL; sec = sec->next)
   589 +    {
   590 +      struct wildcard_list *sec2;
   591 +      for (sec2 = sec->next; sec2 != NULL; sec2 = sec2->next)
   592 +	{
   593 +	  if (wild_spec_can_overlap (sec->spec.name, sec2->spec.name))
   594 +	    return;
   595 +	}
   596 +    }
   597 +
   598 +  signature = (sec_count << 8) + wild_name_count;
   599 +  switch (signature)
   600 +    {
   601 +    case 0x0100:
   602 +      ptr->walk_wild_section_handler = walk_wild_section_specs1_wild0;
   603 +      break;
   604 +    case 0x0101:
   605 +      ptr->walk_wild_section_handler = walk_wild_section_specs1_wild1;
   606 +      break;
   607 +    case 0x0201:
   608 +      ptr->walk_wild_section_handler = walk_wild_section_specs2_wild1;
   609 +      break;
   610 +    case 0x0302:
   611 +      ptr->walk_wild_section_handler = walk_wild_section_specs3_wild2;
   612 +      break;
   613 +    case 0x0402:
   614 +      ptr->walk_wild_section_handler = walk_wild_section_specs4_wild2;
   615 +      break;
   616 +    default:
   617 +      return;
   618 +    }
   619 +
   620 +  /* Now fill the data array with pointers to the specs, first the
   621 +     specs with non-wildcard names, then the specs with wildcard
   622 +     names.  It's OK to process the specs in different order from the
   623 +     given order, because we've already determined that no section
   624 +     will match more than one spec.  */
   625 +  data_counter = 0;
   626 +  for (sec = ptr->section_list; sec != NULL; sec = sec->next)
   627 +    if (!wildcardp (sec->spec.name))
   628 +      ptr->handler_data[data_counter++] = sec;
   629 +  for (sec = ptr->section_list; sec != NULL; sec = sec->next)
   630 +    if (wildcardp (sec->spec.name))
   631 +      ptr->handler_data[data_counter++] = sec;
   632 +}
   633 +
   634  /* Handle a wild statement for a single file F.  */
   635  
   636  static void
   637 @@ -4353,6 +4737,7 @@
   638    new->section_list = section_list;
   639    new->keep_sections = keep_sections;
   640    lang_list_init (&new->children);
   641 +  analyze_walk_wild_section_handler (new);
   642  }
   643  
   644  void
   645 --- binutils-2.15/ld/ldlang.h.old	2004-05-17 15:36:16.000000000 -0400
   646 +++ binutils-2.15/ld/ldlang.h	2006-01-23 13:32:33.653292000 -0500
   647 @@ -295,7 +295,17 @@
   648    union lang_statement_union *file;
   649  } lang_afile_asection_pair_statement_type;
   650  
   651 -typedef struct lang_wild_statement_struct
   652 +typedef struct lang_wild_statement_struct lang_wild_statement_type;
   653 +
   654 +typedef void (*callback_t) (lang_wild_statement_type *, struct wildcard_list *,
   655 +			    asection *, lang_input_statement_type *, void *);
   656 +
   657 +typedef void (*walk_wild_section_handler_t) (lang_wild_statement_type *,
   658 +					     lang_input_statement_type *,
   659 +					     callback_t callback,
   660 +					     void *data);
   661 +
   662 +struct lang_wild_statement_struct
   663  {
   664    lang_statement_header_type header;
   665    const char *filename;
   666 @@ -303,7 +313,10 @@
   667    struct wildcard_list *section_list;
   668    bfd_boolean keep_sections;
   669    lang_statement_list_type children;
   670 -} lang_wild_statement_type;
   671 +
   672 +  walk_wild_section_handler_t walk_wild_section_handler;
   673 +  struct wildcard_list *handler_data[4];
   674 +};
   675  
   676  typedef struct lang_address_statement_struct
   677  {