patches/binutils/2.16.1a/130-callahan.patch
author "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
Sun Sep 11 18:18:53 2011 +0200 (2011-09-11)
changeset 2664 346263a07115
parent 402 patches/binutils/2.16.1/130-callahan.patch@197e1b49586e
permissions -rw-r--r--
binutils/binutils: fixup version strings

Recently, all binutils versions have been renamed after a GPL compliance
issue was found and fixed in binutils;
http://sourceware.org/ml/binutils/2011-08/msg00198.html

Although legacy symlinks have been put in place, we should now use
the new, real version strings.

Signed-off-by: "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
     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 
    45 Index: src/ld/ld.h
    46 ===================================================================
    47 RCS file: /cvs/src/src/ld/ld.h,v
    48 retrieving revision 1.26
    49 retrieving revision 1.27
    50 diff -u -r1.26 -r1.27
    51 --- binutils/ld/ld.h.old	16 Mar 2005 21:52:42 -0000	1.26
    52 +++ binutils/ld/ld.h	6 Apr 2005 15:33:02 -0000	1.27
    53 @@ -1,6 +1,6 @@
    54  /* ld.h -- general linker header file
    55     Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
    56 -   2001, 2002, 2003, 2004
    57 +   2001, 2002, 2003, 2004, 2005
    58     Free Software Foundation, Inc.
    59  
    60     This file is part of GLD, the Gnu Linker.
    61 @@ -89,28 +89,15 @@
    62    struct map_symbol_def *next;
    63  };
    64  
    65 -/* Extra information we hold on sections */
    66 -typedef struct lean_user_section_struct {
    67 -  /* For output sections: pointer to the section where this data will go.  */
    68 -  struct lang_input_statement_struct *file;
    69 -} lean_section_userdata_type;
    70 -
    71  /* The initial part of fat_user_section_struct has to be idential with
    72     lean_user_section_struct.  */
    73  typedef struct fat_user_section_struct {
    74 -  /* For output sections: pointer to the section where this data will go.  */
    75 -  struct lang_input_statement_struct *file;
    76    /* For input sections, when writing a map file: head / tail of a linked
    77       list of hash table entries for symbols defined in this section.  */
    78    struct map_symbol_def *map_symbol_def_head;
    79    struct map_symbol_def **map_symbol_def_tail;
    80  } fat_section_userdata_type;
    81  
    82 -#define SECTION_USERDATA_SIZE \
    83 - (command_line.reduce_memory_overheads \
    84 -  ? sizeof (lean_section_userdata_type) \
    85 -  : sizeof (fat_section_userdata_type))
    86 -
    87  #define get_userdata(x) ((x)->userdata)
    88  
    89  #define BYTE_SIZE	(1)
    90 Index: src/ld/ldlang.c
    91 ===================================================================
    92 RCS file: /cvs/src/src/ld/ldlang.c,v
    93 retrieving revision 1.176
    94 retrieving revision 1.177
    95 diff -u -r1.176 -r1.177
    96 --- binutils/ld/ldlang.c.old	18 Mar 2005 13:56:26 -0000	1.176
    97 +++ binutils/ld/ldlang.c	6 Apr 2005 15:33:02 -0000	1.177
    98 @@ -84,9 +84,6 @@
    99  static void lang_record_phdrs (void);
   100  static void lang_do_version_exports_section (void);
   101  
   102 -typedef void (*callback_t) (lang_wild_statement_type *, struct wildcard_list *,
   103 -			    asection *, lang_input_statement_type *, void *);
   104 -
   105  /* Exported variables.  */
   106  lang_output_section_statement_type *abs_output_section;
   107  lang_statement_list_type lang_output_section_statement;
   108 @@ -155,21 +152,71 @@
   109  
   110  /* Generic traversal routines for finding matching sections.  */
   111  
   112 +/* Try processing a section against a wildcard.  This just calls
   113 +   the callback unless the filename exclusion list is present
   114 +   and excludes the file.  It's hardly ever present so this
   115 +   function is very fast.  */
   116 +
   117 +static void
   118 +walk_wild_consider_section (lang_wild_statement_type *ptr,
   119 +			    lang_input_statement_type *file,
   120 +			    asection *s,
   121 +			    struct wildcard_list *sec,
   122 +			    callback_t callback,
   123 +			    void *data)
   124 +{
   125 +  bfd_boolean skip = FALSE;
   126 +  struct name_list *list_tmp;
   127 +
   128 +  /* Don't process sections from files which were
   129 +     excluded.  */
   130 +  for (list_tmp = sec->spec.exclude_name_list;
   131 +       list_tmp;
   132 +       list_tmp = list_tmp->next)
   133 +    {
   134 +      bfd_boolean is_wildcard = wildcardp (list_tmp->name);
   135 +      if (is_wildcard)
   136 +	skip = fnmatch (list_tmp->name, file->filename, 0) == 0;
   137 +      else
   138 +	skip = strcmp (list_tmp->name, file->filename) == 0;
   139 +
   140 +      /* If this file is part of an archive, and the archive is
   141 +	 excluded, exclude this file.  */
   142 +      if (! skip && file->the_bfd != NULL
   143 +	  && file->the_bfd->my_archive != NULL
   144 +	  && file->the_bfd->my_archive->filename != NULL)
   145 +	{
   146 +	  if (is_wildcard)
   147 +	    skip = fnmatch (list_tmp->name,
   148 +			    file->the_bfd->my_archive->filename,
   149 +			    0) == 0;
   150 +	  else
   151 +	    skip = strcmp (list_tmp->name,
   152 +			   file->the_bfd->my_archive->filename) == 0;
   153 +	}
   154 +
   155 +      if (skip)
   156 +	break;
   157 +    }
   158 +
   159 +  if (!skip)
   160 +    (*callback) (ptr, sec, s, file, data);
   161 +}
   162 +
   163 +/* Lowest common denominator routine that can handle everything correctly,
   164 +   but slowly.  */
   165 +
   166  static void
   167 -walk_wild_section (lang_wild_statement_type *ptr,
   168 -		   lang_input_statement_type *file,
   169 -		   callback_t callback,
   170 -		   void *data)
   171 +walk_wild_section_general (lang_wild_statement_type *ptr,
   172 +			   lang_input_statement_type *file,
   173 +			   callback_t callback,
   174 +			   void *data)
   175  {
   176    asection *s;
   177 -
   178 -  if (file->just_syms_flag)
   179 -    return;
   180 +  struct wildcard_list *sec;
   181  
   182    for (s = file->the_bfd->sections; s != NULL; s = s->next)
   183      {
   184 -      struct wildcard_list *sec;
   185 -
   186        sec = ptr->section_list;
   187        if (sec == NULL)
   188  	(*callback) (ptr, sec, s, file, data);
   189 @@ -177,39 +224,8 @@
   190        while (sec != NULL)
   191  	{
   192  	  bfd_boolean skip = FALSE;
   193 -	  struct name_list *list_tmp;
   194  
   195 -	  /* Don't process sections from files which were
   196 -	     excluded.  */
   197 -	  for (list_tmp = sec->spec.exclude_name_list;
   198 -	       list_tmp;
   199 -	       list_tmp = list_tmp->next)
   200 -	    {
   201 -	      if (wildcardp (list_tmp->name))
   202 -		skip = fnmatch (list_tmp->name, file->filename, 0) == 0;
   203 -	      else
   204 -		skip = strcmp (list_tmp->name, file->filename) == 0;
   205 -
   206 -	      /* If this file is part of an archive, and the archive is
   207 -		 excluded, exclude this file.  */
   208 -	      if (! skip && file->the_bfd != NULL
   209 -		  && file->the_bfd->my_archive != NULL
   210 -		  && file->the_bfd->my_archive->filename != NULL)
   211 -		{
   212 -		  if (wildcardp (list_tmp->name))
   213 -		    skip = fnmatch (list_tmp->name,
   214 -				    file->the_bfd->my_archive->filename,
   215 -				    0) == 0;
   216 -		  else
   217 -		    skip = strcmp (list_tmp->name,
   218 -				   file->the_bfd->my_archive->filename) == 0;
   219 -		}
   220 -
   221 -	      if (skip)
   222 -		break;
   223 -	    }
   224 -
   225 -	  if (!skip && sec->spec.name != NULL)
   226 +	  if (sec->spec.name != NULL)
   227  	    {
   228  	      const char *sname = bfd_get_section_name (file->the_bfd, s);
   229  
   230 @@ -220,13 +236,381 @@
   231  	    }
   232  
   233  	  if (!skip)
   234 -	    (*callback) (ptr, sec, s, file, data);
   235 +	    walk_wild_consider_section (ptr, file, s, sec, callback, data);
   236  
   237  	  sec = sec->next;
   238  	}
   239      }
   240  }
   241  
   242 +/* Routines to find a single section given its name.  If there's more
   243 +   than one section with that name, we report that.  */
   244 +
   245 +typedef struct
   246 +{
   247 +  asection *found_section;
   248 +  bfd_boolean multiple_sections_found;
   249 +} section_iterator_callback_data;
   250 +
   251 +static bfd_boolean
   252 +section_iterator_callback (bfd *bfd ATTRIBUTE_UNUSED, asection *s, void *data)
   253 +{
   254 +  section_iterator_callback_data *d = data;
   255 +
   256 +  if (d->found_section != NULL)
   257 +    {
   258 +      d->multiple_sections_found = TRUE;
   259 +      return TRUE;
   260 +    }
   261 +
   262 +  d->found_section = s;
   263 +  return FALSE;
   264 +}
   265 +
   266 +static asection *
   267 +find_section (lang_input_statement_type *file,
   268 +	      struct wildcard_list *sec,
   269 +	      bfd_boolean *multiple_sections_found)
   270 +{
   271 +  section_iterator_callback_data cb_data = { NULL, FALSE };
   272 +
   273 +  bfd_get_section_by_name_if (file->the_bfd, sec->spec.name, 
   274 +			      section_iterator_callback, &cb_data);
   275 +  *multiple_sections_found = cb_data.multiple_sections_found;
   276 +  return cb_data.found_section;
   277 +}
   278 +
   279 +/* Code for handling simple wildcards without going through fnmatch,
   280 +   which can be expensive because of charset translations etc.  */
   281 +
   282 +/* A simple wild is a literal string followed by a single '*',
   283 +   where the literal part is at least 4 characters long.  */
   284 +
   285 +static bfd_boolean
   286 +is_simple_wild (const char *name)
   287 +{
   288 +  size_t len = strcspn (name, "*?[");
   289 +  return len >= 4 && name[len] == '*' && name[len + 1] == '\0';
   290 +}
   291 +
   292 +static bfd_boolean
   293 +match_simple_wild (const char *pattern, const char *name)
   294 +{
   295 +  /* The first four characters of the pattern are guaranteed valid
   296 +     non-wildcard characters.  So we can go faster.  */
   297 +  if (pattern[0] != name[0] || pattern[1] != name[1]
   298 +      || pattern[2] != name[2] || pattern[3] != name[3])
   299 +    return FALSE;
   300 +
   301 +  pattern += 4;
   302 +  name += 4;
   303 +  while (*pattern != '*')
   304 +    if (*name++ != *pattern++)
   305 +      return FALSE;
   306 +
   307 +  return TRUE;
   308 +}
   309 +
   310 +/* Specialized, optimized routines for handling different kinds of
   311 +   wildcards */
   312 +
   313 +static void
   314 +walk_wild_section_specs1_wild0 (lang_wild_statement_type *ptr,
   315 +				lang_input_statement_type *file,
   316 +				callback_t callback,
   317 +				void *data)
   318 +{
   319 +  /* We can just do a hash lookup for the section with the right name.
   320 +     But if that lookup discovers more than one section with the name
   321 +     (should be rare), we fall back to the general algorithm because
   322 +     we would otherwise have to sort the sections to make sure they
   323 +     get processed in the bfd's order.  */
   324 +  bfd_boolean multiple_sections_found;
   325 +  struct wildcard_list *sec0 = ptr->handler_data[0];
   326 +  asection *s0 = find_section (file, sec0, &multiple_sections_found);
   327 +
   328 +  if (multiple_sections_found)
   329 +    walk_wild_section_general (ptr, file, callback, data);
   330 +  else if (s0)
   331 +    walk_wild_consider_section (ptr, file, s0, sec0, callback, data);
   332 +}
   333 +
   334 +static void
   335 +walk_wild_section_specs1_wild1 (lang_wild_statement_type *ptr,
   336 +				lang_input_statement_type *file,
   337 +				callback_t callback,
   338 +				void *data)
   339 +{
   340 +  asection *s;
   341 +  struct wildcard_list *wildsec0 = ptr->handler_data[0];
   342 +
   343 +  for (s = file->the_bfd->sections; s != NULL; s = s->next)
   344 +    {
   345 +      const char *sname = bfd_get_section_name (file->the_bfd, s);
   346 +      bfd_boolean skip = !match_simple_wild (wildsec0->spec.name, sname);
   347 +
   348 +      if (!skip)
   349 +	walk_wild_consider_section (ptr, file, s, wildsec0, callback, data);
   350 +    }
   351 +}
   352 +
   353 +static void
   354 +walk_wild_section_specs2_wild1 (lang_wild_statement_type *ptr,
   355 +				lang_input_statement_type *file,
   356 +				callback_t callback,
   357 +				void *data)
   358 +{
   359 +  asection *s;
   360 +  struct wildcard_list *sec0 = ptr->handler_data[0];
   361 +  struct wildcard_list *wildsec1 = ptr->handler_data[1];
   362 +  bfd_boolean multiple_sections_found;
   363 +  asection *s0 = find_section (file, sec0, &multiple_sections_found);
   364 +
   365 +  if (multiple_sections_found)
   366 +    {
   367 +      walk_wild_section_general (ptr, file, callback, data);
   368 +      return;
   369 +    }
   370 +
   371 +  /* Note that if the section was not found, s0 is NULL and
   372 +     we'll simply never succeed the s == s0 test below.  */
   373 +  for (s = file->the_bfd->sections; s != NULL; s = s->next)
   374 +    {
   375 +      /* Recall that in this code path, a section cannot satisfy more
   376 +	 than one spec, so if s == s0 then it cannot match
   377 +	 wildspec1.  */
   378 +      if (s == s0)
   379 +	walk_wild_consider_section (ptr, file, s, sec0, callback, data);
   380 +      else
   381 +	{
   382 +	  const char *sname = bfd_get_section_name (file->the_bfd, s);
   383 +	  bfd_boolean skip = !match_simple_wild (wildsec1->spec.name, sname);
   384 +
   385 +	  if (!skip)
   386 +	    walk_wild_consider_section (ptr, file, s, wildsec1, callback,
   387 +					data);
   388 +	}
   389 +    }
   390 +}
   391 +
   392 +static void
   393 +walk_wild_section_specs3_wild2 (lang_wild_statement_type *ptr,
   394 +				lang_input_statement_type *file,
   395 +				callback_t callback,
   396 +				void *data)
   397 +{
   398 +  asection *s;
   399 +  struct wildcard_list *sec0 = ptr->handler_data[0];
   400 +  struct wildcard_list *wildsec1 = ptr->handler_data[1];
   401 +  struct wildcard_list *wildsec2 = ptr->handler_data[2];
   402 +  bfd_boolean multiple_sections_found;
   403 +  asection *s0 = find_section (file, sec0, &multiple_sections_found);
   404 +
   405 +  if (multiple_sections_found)
   406 +    {
   407 +      walk_wild_section_general (ptr, file, callback, data);
   408 +      return;
   409 +    }
   410 +
   411 +  for (s = file->the_bfd->sections; s != NULL; s = s->next)
   412 +    {
   413 +      if (s == s0)
   414 +	walk_wild_consider_section (ptr, file, s, sec0, callback, data);
   415 +      else
   416 +	{
   417 +	  const char *sname = bfd_get_section_name (file->the_bfd, s);
   418 +	  bfd_boolean skip = !match_simple_wild (wildsec1->spec.name, sname);
   419 +
   420 +	  if (!skip)
   421 +	    walk_wild_consider_section (ptr, file, s, wildsec1, callback, data);
   422 +	  else
   423 +	    {
   424 +	      skip = !match_simple_wild (wildsec2->spec.name, sname);
   425 +	      if (!skip)
   426 +		walk_wild_consider_section (ptr, file, s, wildsec2, callback,
   427 +					    data);
   428 +	    }
   429 +	}
   430 +    }
   431 +}
   432 +
   433 +static void
   434 +walk_wild_section_specs4_wild2 (lang_wild_statement_type *ptr,
   435 +				lang_input_statement_type *file,
   436 +				callback_t callback,
   437 +				void *data)
   438 +{
   439 +  asection *s;
   440 +  struct wildcard_list *sec0 = ptr->handler_data[0];
   441 +  struct wildcard_list *sec1 = ptr->handler_data[1];
   442 +  struct wildcard_list *wildsec2 = ptr->handler_data[2];
   443 +  struct wildcard_list *wildsec3 = ptr->handler_data[3];
   444 +  bfd_boolean multiple_sections_found;
   445 +  asection *s0 = find_section (file, sec0, &multiple_sections_found), *s1;
   446 +
   447 +  if (multiple_sections_found)
   448 +    {
   449 +      walk_wild_section_general (ptr, file, callback, data);
   450 +      return;
   451 +    }
   452 +
   453 +  s1 = find_section (file, sec1, &multiple_sections_found);
   454 +  if (multiple_sections_found)
   455 +    {
   456 +      walk_wild_section_general (ptr, file, callback, data);
   457 +      return;
   458 +    }
   459 +
   460 +  for (s = file->the_bfd->sections; s != NULL; s = s->next)
   461 +    {
   462 +      if (s == s0)
   463 +	walk_wild_consider_section (ptr, file, s, sec0, callback, data);
   464 +      else
   465 +	if (s == s1)
   466 +	  walk_wild_consider_section (ptr, file, s, sec1, callback, data);
   467 +	else
   468 +	  {
   469 +	    const char *sname = bfd_get_section_name (file->the_bfd, s);
   470 +	    bfd_boolean skip = !match_simple_wild (wildsec2->spec.name,
   471 +						   sname);
   472 +
   473 +	    if (!skip)
   474 +	      walk_wild_consider_section (ptr, file, s, wildsec2, callback,
   475 +					  data);
   476 +	    else
   477 +	      {
   478 +		skip = !match_simple_wild (wildsec3->spec.name, sname);
   479 +		if (!skip)
   480 +		  walk_wild_consider_section (ptr, file, s, wildsec3,
   481 +					      callback, data);
   482 +	      }
   483 +	  }
   484 +    }
   485 +}
   486 +
   487 +static void
   488 +walk_wild_section (lang_wild_statement_type *ptr,
   489 +		   lang_input_statement_type *file,
   490 +		   callback_t callback,
   491 +		   void *data)
   492 +{
   493 +  if (file->just_syms_flag)
   494 +    return;
   495 +
   496 +  (*ptr->walk_wild_section_handler) (ptr, file, callback, data);
   497 +}
   498 +
   499 +/* Returns TRUE when name1 is a wildcard spec that might match
   500 +   something name2 can match.  We're conservative: we return FALSE
   501 +   only if the prefixes of name1 and name2 are different up to the
   502 +   first wildcard character.  */
   503 +
   504 +static bfd_boolean
   505 +wild_spec_can_overlap (const char *name1, const char *name2)
   506 +{
   507 +  size_t prefix1_len = strcspn (name1, "?*[");
   508 +  size_t prefix2_len = strcspn (name2, "?*[");
   509 +  size_t min_prefix_len;
   510 +
   511 +  /* Note that if there is no wildcard character, then we treat the
   512 +     terminating 0 as part of the prefix.  Thus ".text" won't match
   513 +     ".text." or ".text.*", for example.  */
   514 +  if (name1[prefix1_len] == '\0')
   515 +    prefix1_len++;
   516 +  if (name2[prefix2_len] == '\0')
   517 +    prefix2_len++;
   518 +
   519 +  min_prefix_len = prefix1_len < prefix2_len ? prefix1_len : prefix2_len;
   520 +
   521 +  return memcmp (name1, name2, min_prefix_len) == 0;
   522 +}
   523 +
   524 +/* Select specialized code to handle various kinds of wildcard
   525 +   statements.  */
   526 +
   527 +static void
   528 +analyze_walk_wild_section_handler (lang_wild_statement_type *ptr)
   529 +{
   530 +  int sec_count = 0;
   531 +  int wild_name_count = 0;
   532 +  struct wildcard_list *sec;
   533 +  int signature;
   534 +  int data_counter;
   535 +
   536 +  ptr->walk_wild_section_handler = walk_wild_section_general;
   537 +
   538 +  /* Count how many wildcard_specs there are, and how many of those
   539 +     actually use wildcards in the name.  Also, bail out if any of the
   540 +     wildcard names are NULL. (Can this actually happen?
   541 +     walk_wild_section used to test for it.)  And bail out if any
   542 +     of the wildcards are more complex than a simple string
   543 +     ending in a single '*'.  */
   544 +  for (sec = ptr->section_list; sec != NULL; sec = sec->next)
   545 +    {
   546 +      ++sec_count;
   547 +      if (sec->spec.name == NULL)
   548 +	return;
   549 +      if (wildcardp (sec->spec.name))
   550 +	{
   551 +	  ++wild_name_count;
   552 +	  if (!is_simple_wild (sec->spec.name))
   553 +	    return;
   554 +	}
   555 +    }
   556 +
   557 +  /* The zero-spec case would be easy to optimize but it doesn't
   558 +     happen in practice.  Likewise, more than 4 specs doesn't
   559 +     happen in practice.  */
   560 +  if (sec_count == 0 || sec_count > 4)
   561 +    return;
   562 +
   563 +  /* Check that no two specs can match the same section.  */
   564 +  for (sec = ptr->section_list; sec != NULL; sec = sec->next)
   565 +    {
   566 +      struct wildcard_list *sec2;
   567 +      for (sec2 = sec->next; sec2 != NULL; sec2 = sec2->next)
   568 +	{
   569 +	  if (wild_spec_can_overlap (sec->spec.name, sec2->spec.name))
   570 +	    return;
   571 +	}
   572 +    }
   573 +
   574 +  signature = (sec_count << 8) + wild_name_count;
   575 +  switch (signature)
   576 +    {
   577 +    case 0x0100:
   578 +      ptr->walk_wild_section_handler = walk_wild_section_specs1_wild0;
   579 +      break;
   580 +    case 0x0101:
   581 +      ptr->walk_wild_section_handler = walk_wild_section_specs1_wild1;
   582 +      break;
   583 +    case 0x0201:
   584 +      ptr->walk_wild_section_handler = walk_wild_section_specs2_wild1;
   585 +      break;
   586 +    case 0x0302:
   587 +      ptr->walk_wild_section_handler = walk_wild_section_specs3_wild2;
   588 +      break;
   589 +    case 0x0402:
   590 +      ptr->walk_wild_section_handler = walk_wild_section_specs4_wild2;
   591 +      break;
   592 +    default:
   593 +      return;
   594 +    }
   595 +
   596 +  /* Now fill the data array with pointers to the specs, first the
   597 +     specs with non-wildcard names, then the specs with wildcard
   598 +     names.  It's OK to process the specs in different order from the
   599 +     given order, because we've already determined that no section
   600 +     will match more than one spec.  */
   601 +  data_counter = 0;
   602 +  for (sec = ptr->section_list; sec != NULL; sec = sec->next)
   603 +    if (!wildcardp (sec->spec.name))
   604 +      ptr->handler_data[data_counter++] = sec;
   605 +  for (sec = ptr->section_list; sec != NULL; sec = sec->next)
   606 +    if (wildcardp (sec->spec.name))
   607 +      ptr->handler_data[data_counter++] = sec;
   608 +}
   609 +
   610  /* Handle a wild statement for a single file F.  */
   611  
   612  static void
   613 @@ -1175,17 +1559,12 @@
   614  static void
   615  init_os (lang_output_section_statement_type *s)
   616  {
   617 -  lean_section_userdata_type *new;
   618 -
   619    if (s->bfd_section != NULL)
   620      return;
   621  
   622    if (strcmp (s->name, DISCARD_SECTION_NAME) == 0)
   623      einfo (_("%P%F: Illegal use of `%s' section\n"), DISCARD_SECTION_NAME);
   624  
   625 -  new = stat_alloc (SECTION_USERDATA_SIZE);
   626 -  memset (new, 0, SECTION_USERDATA_SIZE);
   627 -
   628    s->bfd_section = bfd_get_section_by_name (output_bfd, s->name);
   629    if (s->bfd_section == NULL)
   630      s->bfd_section = bfd_make_section (output_bfd, s->name);
   631 @@ -1199,7 +1578,14 @@
   632    /* We initialize an output sections output offset to minus its own
   633       vma to allow us to output a section through itself.  */
   634    s->bfd_section->output_offset = 0;
   635 -  get_userdata (s->bfd_section) = new;
   636 +  if (!command_line.reduce_memory_overheads)
   637 +    {
   638 +      fat_section_userdata_type *new
   639 +	= stat_alloc (sizeof (fat_section_userdata_type));
   640 +      memset (new, 0, sizeof (fat_section_userdata_type));
   641 +      get_userdata (s->bfd_section) = new;
   642 +    }
   643 +
   644  
   645    /* If there is a base address, make sure that any sections it might
   646       mention are initialized.  */
   647 @@ -4939,6 +5325,7 @@
   648    new->section_list = section_list;
   649    new->keep_sections = keep_sections;
   650    lang_list_init (&new->children);
   651 +  analyze_walk_wild_section_handler (new);
   652  }
   653  
   654  void
   655 Index: src/ld/ldlang.h
   656 ===================================================================
   657 RCS file: /cvs/src/src/ld/ldlang.h,v
   658 retrieving revision 1.44
   659 retrieving revision 1.45
   660 diff -u -r1.44 -r1.45
   661 --- binutils/ld/ldlang.h.old	3 Mar 2005 11:51:58 -0000	1.44
   662 +++ binutils/ld/ldlang.h	6 Apr 2005 15:33:03 -0000	1.45
   663 @@ -298,7 +298,17 @@
   664    union lang_statement_union *file;
   665  } lang_afile_asection_pair_statement_type;
   666  
   667 -typedef struct lang_wild_statement_struct
   668 +typedef struct lang_wild_statement_struct lang_wild_statement_type;
   669 +
   670 +typedef void (*callback_t) (lang_wild_statement_type *, struct wildcard_list *,
   671 +			    asection *, lang_input_statement_type *, void *);
   672 +
   673 +typedef void (*walk_wild_section_handler_t) (lang_wild_statement_type *,
   674 +					     lang_input_statement_type *,
   675 +					     callback_t callback,
   676 +					     void *data);
   677 +
   678 +struct lang_wild_statement_struct
   679  {
   680    lang_statement_header_type header;
   681    const char *filename;
   682 @@ -306,7 +316,10 @@
   683    struct wildcard_list *section_list;
   684    bfd_boolean keep_sections;
   685    lang_statement_list_type children;
   686 -} lang_wild_statement_type;
   687 +
   688 +  walk_wild_section_handler_t walk_wild_section_handler;
   689 +  struct wildcard_list *handler_data[4];
   690 +};
   691  
   692  typedef struct lang_address_statement_struct
   693  {