patches/binutils/2.16.1a/130-callahan.patch
author "Benoît Thébaudeau" <benoit.thebaudeau@advansee.com>
Mon Apr 16 15:25:36 2012 +0200 (2012-04-16)
changeset 2941 13e40098fffc
parent 402 197e1b49586e
permissions -rw-r--r--
cc/gcc: update Linaro GCC revisions to 2012.04

Update Linaro GCC with the latest available revisions.

The 4.7 revision is also released, but the infrastructure is not yet ready for
it in CT-NG.

Signed-off-by: "Benoît Thébaudeau" <benoit.thebaudeau@advansee.com>
     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  {