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 - {