patches/binutils/2.16.1/130-callahan.patch
changeset 2664 346263a07115
parent 2663 7179903f8d2e
child 2665 5b7e91ec300c
     1.1 --- a/patches/binutils/2.16.1/130-callahan.patch	Sun Sep 11 18:26:12 2011 +0200
     1.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.3 @@ -1,693 +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 -
    1.48 -Index: src/ld/ld.h
    1.49 -===================================================================
    1.50 -RCS file: /cvs/src/src/ld/ld.h,v
    1.51 -retrieving revision 1.26
    1.52 -retrieving revision 1.27
    1.53 -diff -u -r1.26 -r1.27
    1.54 ---- binutils/ld/ld.h.old	16 Mar 2005 21:52:42 -0000	1.26
    1.55 -+++ binutils/ld/ld.h	6 Apr 2005 15:33:02 -0000	1.27
    1.56 -@@ -1,6 +1,6 @@
    1.57 - /* ld.h -- general linker header file
    1.58 -    Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
    1.59 --   2001, 2002, 2003, 2004
    1.60 -+   2001, 2002, 2003, 2004, 2005
    1.61 -    Free Software Foundation, Inc.
    1.62 - 
    1.63 -    This file is part of GLD, the Gnu Linker.
    1.64 -@@ -89,28 +89,15 @@
    1.65 -   struct map_symbol_def *next;
    1.66 - };
    1.67 - 
    1.68 --/* Extra information we hold on sections */
    1.69 --typedef struct lean_user_section_struct {
    1.70 --  /* For output sections: pointer to the section where this data will go.  */
    1.71 --  struct lang_input_statement_struct *file;
    1.72 --} lean_section_userdata_type;
    1.73 --
    1.74 - /* The initial part of fat_user_section_struct has to be idential with
    1.75 -    lean_user_section_struct.  */
    1.76 - typedef struct fat_user_section_struct {
    1.77 --  /* For output sections: pointer to the section where this data will go.  */
    1.78 --  struct lang_input_statement_struct *file;
    1.79 -   /* For input sections, when writing a map file: head / tail of a linked
    1.80 -      list of hash table entries for symbols defined in this section.  */
    1.81 -   struct map_symbol_def *map_symbol_def_head;
    1.82 -   struct map_symbol_def **map_symbol_def_tail;
    1.83 - } fat_section_userdata_type;
    1.84 - 
    1.85 --#define SECTION_USERDATA_SIZE \
    1.86 -- (command_line.reduce_memory_overheads \
    1.87 --  ? sizeof (lean_section_userdata_type) \
    1.88 --  : sizeof (fat_section_userdata_type))
    1.89 --
    1.90 - #define get_userdata(x) ((x)->userdata)
    1.91 - 
    1.92 - #define BYTE_SIZE	(1)
    1.93 -Index: src/ld/ldlang.c
    1.94 -===================================================================
    1.95 -RCS file: /cvs/src/src/ld/ldlang.c,v
    1.96 -retrieving revision 1.176
    1.97 -retrieving revision 1.177
    1.98 -diff -u -r1.176 -r1.177
    1.99 ---- binutils/ld/ldlang.c.old	18 Mar 2005 13:56:26 -0000	1.176
   1.100 -+++ binutils/ld/ldlang.c	6 Apr 2005 15:33:02 -0000	1.177
   1.101 -@@ -84,9 +84,6 @@
   1.102 - static void lang_record_phdrs (void);
   1.103 - static void lang_do_version_exports_section (void);
   1.104 - 
   1.105 --typedef void (*callback_t) (lang_wild_statement_type *, struct wildcard_list *,
   1.106 --			    asection *, lang_input_statement_type *, void *);
   1.107 --
   1.108 - /* Exported variables.  */
   1.109 - lang_output_section_statement_type *abs_output_section;
   1.110 - lang_statement_list_type lang_output_section_statement;
   1.111 -@@ -155,21 +152,71 @@
   1.112 - 
   1.113 - /* Generic traversal routines for finding matching sections.  */
   1.114 - 
   1.115 -+/* Try processing a section against a wildcard.  This just calls
   1.116 -+   the callback unless the filename exclusion list is present
   1.117 -+   and excludes the file.  It's hardly ever present so this
   1.118 -+   function is very fast.  */
   1.119 -+
   1.120 -+static void
   1.121 -+walk_wild_consider_section (lang_wild_statement_type *ptr,
   1.122 -+			    lang_input_statement_type *file,
   1.123 -+			    asection *s,
   1.124 -+			    struct wildcard_list *sec,
   1.125 -+			    callback_t callback,
   1.126 -+			    void *data)
   1.127 -+{
   1.128 -+  bfd_boolean skip = FALSE;
   1.129 -+  struct name_list *list_tmp;
   1.130 -+
   1.131 -+  /* Don't process sections from files which were
   1.132 -+     excluded.  */
   1.133 -+  for (list_tmp = sec->spec.exclude_name_list;
   1.134 -+       list_tmp;
   1.135 -+       list_tmp = list_tmp->next)
   1.136 -+    {
   1.137 -+      bfd_boolean is_wildcard = wildcardp (list_tmp->name);
   1.138 -+      if (is_wildcard)
   1.139 -+	skip = fnmatch (list_tmp->name, file->filename, 0) == 0;
   1.140 -+      else
   1.141 -+	skip = strcmp (list_tmp->name, file->filename) == 0;
   1.142 -+
   1.143 -+      /* If this file is part of an archive, and the archive is
   1.144 -+	 excluded, exclude this file.  */
   1.145 -+      if (! skip && file->the_bfd != NULL
   1.146 -+	  && file->the_bfd->my_archive != NULL
   1.147 -+	  && file->the_bfd->my_archive->filename != NULL)
   1.148 -+	{
   1.149 -+	  if (is_wildcard)
   1.150 -+	    skip = fnmatch (list_tmp->name,
   1.151 -+			    file->the_bfd->my_archive->filename,
   1.152 -+			    0) == 0;
   1.153 -+	  else
   1.154 -+	    skip = strcmp (list_tmp->name,
   1.155 -+			   file->the_bfd->my_archive->filename) == 0;
   1.156 -+	}
   1.157 -+
   1.158 -+      if (skip)
   1.159 -+	break;
   1.160 -+    }
   1.161 -+
   1.162 -+  if (!skip)
   1.163 -+    (*callback) (ptr, sec, s, file, data);
   1.164 -+}
   1.165 -+
   1.166 -+/* Lowest common denominator routine that can handle everything correctly,
   1.167 -+   but slowly.  */
   1.168 -+
   1.169 - static void
   1.170 --walk_wild_section (lang_wild_statement_type *ptr,
   1.171 --		   lang_input_statement_type *file,
   1.172 --		   callback_t callback,
   1.173 --		   void *data)
   1.174 -+walk_wild_section_general (lang_wild_statement_type *ptr,
   1.175 -+			   lang_input_statement_type *file,
   1.176 -+			   callback_t callback,
   1.177 -+			   void *data)
   1.178 - {
   1.179 -   asection *s;
   1.180 --
   1.181 --  if (file->just_syms_flag)
   1.182 --    return;
   1.183 -+  struct wildcard_list *sec;
   1.184 - 
   1.185 -   for (s = file->the_bfd->sections; s != NULL; s = s->next)
   1.186 -     {
   1.187 --      struct wildcard_list *sec;
   1.188 --
   1.189 -       sec = ptr->section_list;
   1.190 -       if (sec == NULL)
   1.191 - 	(*callback) (ptr, sec, s, file, data);
   1.192 -@@ -177,39 +224,8 @@
   1.193 -       while (sec != NULL)
   1.194 - 	{
   1.195 - 	  bfd_boolean skip = FALSE;
   1.196 --	  struct name_list *list_tmp;
   1.197 - 
   1.198 --	  /* Don't process sections from files which were
   1.199 --	     excluded.  */
   1.200 --	  for (list_tmp = sec->spec.exclude_name_list;
   1.201 --	       list_tmp;
   1.202 --	       list_tmp = list_tmp->next)
   1.203 --	    {
   1.204 --	      if (wildcardp (list_tmp->name))
   1.205 --		skip = fnmatch (list_tmp->name, file->filename, 0) == 0;
   1.206 --	      else
   1.207 --		skip = strcmp (list_tmp->name, file->filename) == 0;
   1.208 --
   1.209 --	      /* If this file is part of an archive, and the archive is
   1.210 --		 excluded, exclude this file.  */
   1.211 --	      if (! skip && file->the_bfd != NULL
   1.212 --		  && file->the_bfd->my_archive != NULL
   1.213 --		  && file->the_bfd->my_archive->filename != NULL)
   1.214 --		{
   1.215 --		  if (wildcardp (list_tmp->name))
   1.216 --		    skip = fnmatch (list_tmp->name,
   1.217 --				    file->the_bfd->my_archive->filename,
   1.218 --				    0) == 0;
   1.219 --		  else
   1.220 --		    skip = strcmp (list_tmp->name,
   1.221 --				   file->the_bfd->my_archive->filename) == 0;
   1.222 --		}
   1.223 --
   1.224 --	      if (skip)
   1.225 --		break;
   1.226 --	    }
   1.227 --
   1.228 --	  if (!skip && sec->spec.name != NULL)
   1.229 -+	  if (sec->spec.name != NULL)
   1.230 - 	    {
   1.231 - 	      const char *sname = bfd_get_section_name (file->the_bfd, s);
   1.232 - 
   1.233 -@@ -220,13 +236,381 @@
   1.234 - 	    }
   1.235 - 
   1.236 - 	  if (!skip)
   1.237 --	    (*callback) (ptr, sec, s, file, data);
   1.238 -+	    walk_wild_consider_section (ptr, file, s, sec, callback, data);
   1.239 - 
   1.240 - 	  sec = sec->next;
   1.241 - 	}
   1.242 -     }
   1.243 - }
   1.244 - 
   1.245 -+/* Routines to find a single section given its name.  If there's more
   1.246 -+   than one section with that name, we report that.  */
   1.247 -+
   1.248 -+typedef struct
   1.249 -+{
   1.250 -+  asection *found_section;
   1.251 -+  bfd_boolean multiple_sections_found;
   1.252 -+} section_iterator_callback_data;
   1.253 -+
   1.254 -+static bfd_boolean
   1.255 -+section_iterator_callback (bfd *bfd ATTRIBUTE_UNUSED, asection *s, void *data)
   1.256 -+{
   1.257 -+  section_iterator_callback_data *d = data;
   1.258 -+
   1.259 -+  if (d->found_section != NULL)
   1.260 -+    {
   1.261 -+      d->multiple_sections_found = TRUE;
   1.262 -+      return TRUE;
   1.263 -+    }
   1.264 -+
   1.265 -+  d->found_section = s;
   1.266 -+  return FALSE;
   1.267 -+}
   1.268 -+
   1.269 -+static asection *
   1.270 -+find_section (lang_input_statement_type *file,
   1.271 -+	      struct wildcard_list *sec,
   1.272 -+	      bfd_boolean *multiple_sections_found)
   1.273 -+{
   1.274 -+  section_iterator_callback_data cb_data = { NULL, FALSE };
   1.275 -+
   1.276 -+  bfd_get_section_by_name_if (file->the_bfd, sec->spec.name, 
   1.277 -+			      section_iterator_callback, &cb_data);
   1.278 -+  *multiple_sections_found = cb_data.multiple_sections_found;
   1.279 -+  return cb_data.found_section;
   1.280 -+}
   1.281 -+
   1.282 -+/* Code for handling simple wildcards without going through fnmatch,
   1.283 -+   which can be expensive because of charset translations etc.  */
   1.284 -+
   1.285 -+/* A simple wild is a literal string followed by a single '*',
   1.286 -+   where the literal part is at least 4 characters long.  */
   1.287 -+
   1.288 -+static bfd_boolean
   1.289 -+is_simple_wild (const char *name)
   1.290 -+{
   1.291 -+  size_t len = strcspn (name, "*?[");
   1.292 -+  return len >= 4 && name[len] == '*' && name[len + 1] == '\0';
   1.293 -+}
   1.294 -+
   1.295 -+static bfd_boolean
   1.296 -+match_simple_wild (const char *pattern, const char *name)
   1.297 -+{
   1.298 -+  /* The first four characters of the pattern are guaranteed valid
   1.299 -+     non-wildcard characters.  So we can go faster.  */
   1.300 -+  if (pattern[0] != name[0] || pattern[1] != name[1]
   1.301 -+      || pattern[2] != name[2] || pattern[3] != name[3])
   1.302 -+    return FALSE;
   1.303 -+
   1.304 -+  pattern += 4;
   1.305 -+  name += 4;
   1.306 -+  while (*pattern != '*')
   1.307 -+    if (*name++ != *pattern++)
   1.308 -+      return FALSE;
   1.309 -+
   1.310 -+  return TRUE;
   1.311 -+}
   1.312 -+
   1.313 -+/* Specialized, optimized routines for handling different kinds of
   1.314 -+   wildcards */
   1.315 -+
   1.316 -+static void
   1.317 -+walk_wild_section_specs1_wild0 (lang_wild_statement_type *ptr,
   1.318 -+				lang_input_statement_type *file,
   1.319 -+				callback_t callback,
   1.320 -+				void *data)
   1.321 -+{
   1.322 -+  /* We can just do a hash lookup for the section with the right name.
   1.323 -+     But if that lookup discovers more than one section with the name
   1.324 -+     (should be rare), we fall back to the general algorithm because
   1.325 -+     we would otherwise have to sort the sections to make sure they
   1.326 -+     get processed in the bfd's order.  */
   1.327 -+  bfd_boolean multiple_sections_found;
   1.328 -+  struct wildcard_list *sec0 = ptr->handler_data[0];
   1.329 -+  asection *s0 = find_section (file, sec0, &multiple_sections_found);
   1.330 -+
   1.331 -+  if (multiple_sections_found)
   1.332 -+    walk_wild_section_general (ptr, file, callback, data);
   1.333 -+  else if (s0)
   1.334 -+    walk_wild_consider_section (ptr, file, s0, sec0, callback, data);
   1.335 -+}
   1.336 -+
   1.337 -+static void
   1.338 -+walk_wild_section_specs1_wild1 (lang_wild_statement_type *ptr,
   1.339 -+				lang_input_statement_type *file,
   1.340 -+				callback_t callback,
   1.341 -+				void *data)
   1.342 -+{
   1.343 -+  asection *s;
   1.344 -+  struct wildcard_list *wildsec0 = ptr->handler_data[0];
   1.345 -+
   1.346 -+  for (s = file->the_bfd->sections; s != NULL; s = s->next)
   1.347 -+    {
   1.348 -+      const char *sname = bfd_get_section_name (file->the_bfd, s);
   1.349 -+      bfd_boolean skip = !match_simple_wild (wildsec0->spec.name, sname);
   1.350 -+
   1.351 -+      if (!skip)
   1.352 -+	walk_wild_consider_section (ptr, file, s, wildsec0, callback, data);
   1.353 -+    }
   1.354 -+}
   1.355 -+
   1.356 -+static void
   1.357 -+walk_wild_section_specs2_wild1 (lang_wild_statement_type *ptr,
   1.358 -+				lang_input_statement_type *file,
   1.359 -+				callback_t callback,
   1.360 -+				void *data)
   1.361 -+{
   1.362 -+  asection *s;
   1.363 -+  struct wildcard_list *sec0 = ptr->handler_data[0];
   1.364 -+  struct wildcard_list *wildsec1 = ptr->handler_data[1];
   1.365 -+  bfd_boolean multiple_sections_found;
   1.366 -+  asection *s0 = find_section (file, sec0, &multiple_sections_found);
   1.367 -+
   1.368 -+  if (multiple_sections_found)
   1.369 -+    {
   1.370 -+      walk_wild_section_general (ptr, file, callback, data);
   1.371 -+      return;
   1.372 -+    }
   1.373 -+
   1.374 -+  /* Note that if the section was not found, s0 is NULL and
   1.375 -+     we'll simply never succeed the s == s0 test below.  */
   1.376 -+  for (s = file->the_bfd->sections; s != NULL; s = s->next)
   1.377 -+    {
   1.378 -+      /* Recall that in this code path, a section cannot satisfy more
   1.379 -+	 than one spec, so if s == s0 then it cannot match
   1.380 -+	 wildspec1.  */
   1.381 -+      if (s == s0)
   1.382 -+	walk_wild_consider_section (ptr, file, s, sec0, callback, data);
   1.383 -+      else
   1.384 -+	{
   1.385 -+	  const char *sname = bfd_get_section_name (file->the_bfd, s);
   1.386 -+	  bfd_boolean skip = !match_simple_wild (wildsec1->spec.name, sname);
   1.387 -+
   1.388 -+	  if (!skip)
   1.389 -+	    walk_wild_consider_section (ptr, file, s, wildsec1, callback,
   1.390 -+					data);
   1.391 -+	}
   1.392 -+    }
   1.393 -+}
   1.394 -+
   1.395 -+static void
   1.396 -+walk_wild_section_specs3_wild2 (lang_wild_statement_type *ptr,
   1.397 -+				lang_input_statement_type *file,
   1.398 -+				callback_t callback,
   1.399 -+				void *data)
   1.400 -+{
   1.401 -+  asection *s;
   1.402 -+  struct wildcard_list *sec0 = ptr->handler_data[0];
   1.403 -+  struct wildcard_list *wildsec1 = ptr->handler_data[1];
   1.404 -+  struct wildcard_list *wildsec2 = ptr->handler_data[2];
   1.405 -+  bfd_boolean multiple_sections_found;
   1.406 -+  asection *s0 = find_section (file, sec0, &multiple_sections_found);
   1.407 -+
   1.408 -+  if (multiple_sections_found)
   1.409 -+    {
   1.410 -+      walk_wild_section_general (ptr, file, callback, data);
   1.411 -+      return;
   1.412 -+    }
   1.413 -+
   1.414 -+  for (s = file->the_bfd->sections; s != NULL; s = s->next)
   1.415 -+    {
   1.416 -+      if (s == s0)
   1.417 -+	walk_wild_consider_section (ptr, file, s, sec0, callback, data);
   1.418 -+      else
   1.419 -+	{
   1.420 -+	  const char *sname = bfd_get_section_name (file->the_bfd, s);
   1.421 -+	  bfd_boolean skip = !match_simple_wild (wildsec1->spec.name, sname);
   1.422 -+
   1.423 -+	  if (!skip)
   1.424 -+	    walk_wild_consider_section (ptr, file, s, wildsec1, callback, data);
   1.425 -+	  else
   1.426 -+	    {
   1.427 -+	      skip = !match_simple_wild (wildsec2->spec.name, sname);
   1.428 -+	      if (!skip)
   1.429 -+		walk_wild_consider_section (ptr, file, s, wildsec2, callback,
   1.430 -+					    data);
   1.431 -+	    }
   1.432 -+	}
   1.433 -+    }
   1.434 -+}
   1.435 -+
   1.436 -+static void
   1.437 -+walk_wild_section_specs4_wild2 (lang_wild_statement_type *ptr,
   1.438 -+				lang_input_statement_type *file,
   1.439 -+				callback_t callback,
   1.440 -+				void *data)
   1.441 -+{
   1.442 -+  asection *s;
   1.443 -+  struct wildcard_list *sec0 = ptr->handler_data[0];
   1.444 -+  struct wildcard_list *sec1 = ptr->handler_data[1];
   1.445 -+  struct wildcard_list *wildsec2 = ptr->handler_data[2];
   1.446 -+  struct wildcard_list *wildsec3 = ptr->handler_data[3];
   1.447 -+  bfd_boolean multiple_sections_found;
   1.448 -+  asection *s0 = find_section (file, sec0, &multiple_sections_found), *s1;
   1.449 -+
   1.450 -+  if (multiple_sections_found)
   1.451 -+    {
   1.452 -+      walk_wild_section_general (ptr, file, callback, data);
   1.453 -+      return;
   1.454 -+    }
   1.455 -+
   1.456 -+  s1 = find_section (file, sec1, &multiple_sections_found);
   1.457 -+  if (multiple_sections_found)
   1.458 -+    {
   1.459 -+      walk_wild_section_general (ptr, file, callback, data);
   1.460 -+      return;
   1.461 -+    }
   1.462 -+
   1.463 -+  for (s = file->the_bfd->sections; s != NULL; s = s->next)
   1.464 -+    {
   1.465 -+      if (s == s0)
   1.466 -+	walk_wild_consider_section (ptr, file, s, sec0, callback, data);
   1.467 -+      else
   1.468 -+	if (s == s1)
   1.469 -+	  walk_wild_consider_section (ptr, file, s, sec1, callback, data);
   1.470 -+	else
   1.471 -+	  {
   1.472 -+	    const char *sname = bfd_get_section_name (file->the_bfd, s);
   1.473 -+	    bfd_boolean skip = !match_simple_wild (wildsec2->spec.name,
   1.474 -+						   sname);
   1.475 -+
   1.476 -+	    if (!skip)
   1.477 -+	      walk_wild_consider_section (ptr, file, s, wildsec2, callback,
   1.478 -+					  data);
   1.479 -+	    else
   1.480 -+	      {
   1.481 -+		skip = !match_simple_wild (wildsec3->spec.name, sname);
   1.482 -+		if (!skip)
   1.483 -+		  walk_wild_consider_section (ptr, file, s, wildsec3,
   1.484 -+					      callback, data);
   1.485 -+	      }
   1.486 -+	  }
   1.487 -+    }
   1.488 -+}
   1.489 -+
   1.490 -+static void
   1.491 -+walk_wild_section (lang_wild_statement_type *ptr,
   1.492 -+		   lang_input_statement_type *file,
   1.493 -+		   callback_t callback,
   1.494 -+		   void *data)
   1.495 -+{
   1.496 -+  if (file->just_syms_flag)
   1.497 -+    return;
   1.498 -+
   1.499 -+  (*ptr->walk_wild_section_handler) (ptr, file, callback, data);
   1.500 -+}
   1.501 -+
   1.502 -+/* Returns TRUE when name1 is a wildcard spec that might match
   1.503 -+   something name2 can match.  We're conservative: we return FALSE
   1.504 -+   only if the prefixes of name1 and name2 are different up to the
   1.505 -+   first wildcard character.  */
   1.506 -+
   1.507 -+static bfd_boolean
   1.508 -+wild_spec_can_overlap (const char *name1, const char *name2)
   1.509 -+{
   1.510 -+  size_t prefix1_len = strcspn (name1, "?*[");
   1.511 -+  size_t prefix2_len = strcspn (name2, "?*[");
   1.512 -+  size_t min_prefix_len;
   1.513 -+
   1.514 -+  /* Note that if there is no wildcard character, then we treat the
   1.515 -+     terminating 0 as part of the prefix.  Thus ".text" won't match
   1.516 -+     ".text." or ".text.*", for example.  */
   1.517 -+  if (name1[prefix1_len] == '\0')
   1.518 -+    prefix1_len++;
   1.519 -+  if (name2[prefix2_len] == '\0')
   1.520 -+    prefix2_len++;
   1.521 -+
   1.522 -+  min_prefix_len = prefix1_len < prefix2_len ? prefix1_len : prefix2_len;
   1.523 -+
   1.524 -+  return memcmp (name1, name2, min_prefix_len) == 0;
   1.525 -+}
   1.526 -+
   1.527 -+/* Select specialized code to handle various kinds of wildcard
   1.528 -+   statements.  */
   1.529 -+
   1.530 -+static void
   1.531 -+analyze_walk_wild_section_handler (lang_wild_statement_type *ptr)
   1.532 -+{
   1.533 -+  int sec_count = 0;
   1.534 -+  int wild_name_count = 0;
   1.535 -+  struct wildcard_list *sec;
   1.536 -+  int signature;
   1.537 -+  int data_counter;
   1.538 -+
   1.539 -+  ptr->walk_wild_section_handler = walk_wild_section_general;
   1.540 -+
   1.541 -+  /* Count how many wildcard_specs there are, and how many of those
   1.542 -+     actually use wildcards in the name.  Also, bail out if any of the
   1.543 -+     wildcard names are NULL. (Can this actually happen?
   1.544 -+     walk_wild_section used to test for it.)  And bail out if any
   1.545 -+     of the wildcards are more complex than a simple string
   1.546 -+     ending in a single '*'.  */
   1.547 -+  for (sec = ptr->section_list; sec != NULL; sec = sec->next)
   1.548 -+    {
   1.549 -+      ++sec_count;
   1.550 -+      if (sec->spec.name == NULL)
   1.551 -+	return;
   1.552 -+      if (wildcardp (sec->spec.name))
   1.553 -+	{
   1.554 -+	  ++wild_name_count;
   1.555 -+	  if (!is_simple_wild (sec->spec.name))
   1.556 -+	    return;
   1.557 -+	}
   1.558 -+    }
   1.559 -+
   1.560 -+  /* The zero-spec case would be easy to optimize but it doesn't
   1.561 -+     happen in practice.  Likewise, more than 4 specs doesn't
   1.562 -+     happen in practice.  */
   1.563 -+  if (sec_count == 0 || sec_count > 4)
   1.564 -+    return;
   1.565 -+
   1.566 -+  /* Check that no two specs can match the same section.  */
   1.567 -+  for (sec = ptr->section_list; sec != NULL; sec = sec->next)
   1.568 -+    {
   1.569 -+      struct wildcard_list *sec2;
   1.570 -+      for (sec2 = sec->next; sec2 != NULL; sec2 = sec2->next)
   1.571 -+	{
   1.572 -+	  if (wild_spec_can_overlap (sec->spec.name, sec2->spec.name))
   1.573 -+	    return;
   1.574 -+	}
   1.575 -+    }
   1.576 -+
   1.577 -+  signature = (sec_count << 8) + wild_name_count;
   1.578 -+  switch (signature)
   1.579 -+    {
   1.580 -+    case 0x0100:
   1.581 -+      ptr->walk_wild_section_handler = walk_wild_section_specs1_wild0;
   1.582 -+      break;
   1.583 -+    case 0x0101:
   1.584 -+      ptr->walk_wild_section_handler = walk_wild_section_specs1_wild1;
   1.585 -+      break;
   1.586 -+    case 0x0201:
   1.587 -+      ptr->walk_wild_section_handler = walk_wild_section_specs2_wild1;
   1.588 -+      break;
   1.589 -+    case 0x0302:
   1.590 -+      ptr->walk_wild_section_handler = walk_wild_section_specs3_wild2;
   1.591 -+      break;
   1.592 -+    case 0x0402:
   1.593 -+      ptr->walk_wild_section_handler = walk_wild_section_specs4_wild2;
   1.594 -+      break;
   1.595 -+    default:
   1.596 -+      return;
   1.597 -+    }
   1.598 -+
   1.599 -+  /* Now fill the data array with pointers to the specs, first the
   1.600 -+     specs with non-wildcard names, then the specs with wildcard
   1.601 -+     names.  It's OK to process the specs in different order from the
   1.602 -+     given order, because we've already determined that no section
   1.603 -+     will match more than one spec.  */
   1.604 -+  data_counter = 0;
   1.605 -+  for (sec = ptr->section_list; sec != NULL; sec = sec->next)
   1.606 -+    if (!wildcardp (sec->spec.name))
   1.607 -+      ptr->handler_data[data_counter++] = sec;
   1.608 -+  for (sec = ptr->section_list; sec != NULL; sec = sec->next)
   1.609 -+    if (wildcardp (sec->spec.name))
   1.610 -+      ptr->handler_data[data_counter++] = sec;
   1.611 -+}
   1.612 -+
   1.613 - /* Handle a wild statement for a single file F.  */
   1.614 - 
   1.615 - static void
   1.616 -@@ -1175,17 +1559,12 @@
   1.617 - static void
   1.618 - init_os (lang_output_section_statement_type *s)
   1.619 - {
   1.620 --  lean_section_userdata_type *new;
   1.621 --
   1.622 -   if (s->bfd_section != NULL)
   1.623 -     return;
   1.624 - 
   1.625 -   if (strcmp (s->name, DISCARD_SECTION_NAME) == 0)
   1.626 -     einfo (_("%P%F: Illegal use of `%s' section\n"), DISCARD_SECTION_NAME);
   1.627 - 
   1.628 --  new = stat_alloc (SECTION_USERDATA_SIZE);
   1.629 --  memset (new, 0, SECTION_USERDATA_SIZE);
   1.630 --
   1.631 -   s->bfd_section = bfd_get_section_by_name (output_bfd, s->name);
   1.632 -   if (s->bfd_section == NULL)
   1.633 -     s->bfd_section = bfd_make_section (output_bfd, s->name);
   1.634 -@@ -1199,7 +1578,14 @@
   1.635 -   /* We initialize an output sections output offset to minus its own
   1.636 -      vma to allow us to output a section through itself.  */
   1.637 -   s->bfd_section->output_offset = 0;
   1.638 --  get_userdata (s->bfd_section) = new;
   1.639 -+  if (!command_line.reduce_memory_overheads)
   1.640 -+    {
   1.641 -+      fat_section_userdata_type *new
   1.642 -+	= stat_alloc (sizeof (fat_section_userdata_type));
   1.643 -+      memset (new, 0, sizeof (fat_section_userdata_type));
   1.644 -+      get_userdata (s->bfd_section) = new;
   1.645 -+    }
   1.646 -+
   1.647 - 
   1.648 -   /* If there is a base address, make sure that any sections it might
   1.649 -      mention are initialized.  */
   1.650 -@@ -4939,6 +5325,7 @@
   1.651 -   new->section_list = section_list;
   1.652 -   new->keep_sections = keep_sections;
   1.653 -   lang_list_init (&new->children);
   1.654 -+  analyze_walk_wild_section_handler (new);
   1.655 - }
   1.656 - 
   1.657 - void
   1.658 -Index: src/ld/ldlang.h
   1.659 -===================================================================
   1.660 -RCS file: /cvs/src/src/ld/ldlang.h,v
   1.661 -retrieving revision 1.44
   1.662 -retrieving revision 1.45
   1.663 -diff -u -r1.44 -r1.45
   1.664 ---- binutils/ld/ldlang.h.old	3 Mar 2005 11:51:58 -0000	1.44
   1.665 -+++ binutils/ld/ldlang.h	6 Apr 2005 15:33:03 -0000	1.45
   1.666 -@@ -298,7 +298,17 @@
   1.667 -   union lang_statement_union *file;
   1.668 - } lang_afile_asection_pair_statement_type;
   1.669 - 
   1.670 --typedef struct lang_wild_statement_struct
   1.671 -+typedef struct lang_wild_statement_struct lang_wild_statement_type;
   1.672 -+
   1.673 -+typedef void (*callback_t) (lang_wild_statement_type *, struct wildcard_list *,
   1.674 -+			    asection *, lang_input_statement_type *, void *);
   1.675 -+
   1.676 -+typedef void (*walk_wild_section_handler_t) (lang_wild_statement_type *,
   1.677 -+					     lang_input_statement_type *,
   1.678 -+					     callback_t callback,
   1.679 -+					     void *data);
   1.680 -+
   1.681 -+struct lang_wild_statement_struct
   1.682 - {
   1.683 -   lang_statement_header_type header;
   1.684 -   const char *filename;
   1.685 -@@ -306,7 +316,10 @@
   1.686 -   struct wildcard_list *section_list;
   1.687 -   bfd_boolean keep_sections;
   1.688 -   lang_statement_list_type children;
   1.689 --} lang_wild_statement_type;
   1.690 -+
   1.691 -+  walk_wild_section_handler_t walk_wild_section_handler;
   1.692 -+  struct wildcard_list *handler_data[4];
   1.693 -+};
   1.694 - 
   1.695 - typedef struct lang_address_statement_struct
   1.696 - {