1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/patches/binutils/2.16.1/callahan.patch Tue May 22 20:36:44 2007 +0000
1.3 @@ -0,0 +1,693 @@
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 + {