Robert P. J. DAY says:
apparently, the patchset for gcc 4.2.1 applies properly to the
source for gcc 4.2.2 and gcc 4.2.3. so, if you want, you can simply
add support for those last two just by augmenting menuconfig and
adding a couple symlinks for those two directories. seems like a
cheap way to add a couple new versions.
1 Signed-off-by: dank@kegel.com
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
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:
11 date: 2005/04/06 15:33:02; author: jakub; state: Exp; lines: +438 -51
12 2005-04-06 Jakub Jelinek <jakub@redhat.com>
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.
19 2005-04-06 Robert O'Callahan <rocallahan@novell.com>
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.
27 * ldlang.h (callback_t, walk_wild_section_handler_t): New
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
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.
46 ===================================================================
47 RCS file: /cvs/src/src/ld/ld.h,v
48 retrieving revision 1.26
49 retrieving revision 1.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
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.
60 This file is part of GLD, the Gnu Linker.
62 struct map_symbol_def *next;
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;
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;
82 -#define SECTION_USERDATA_SIZE \
83 - (command_line.reduce_memory_overheads \
84 - ? sizeof (lean_section_userdata_type) \
85 - : sizeof (fat_section_userdata_type))
87 #define get_userdata(x) ((x)->userdata)
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
99 static void lang_record_phdrs (void);
100 static void lang_do_version_exports_section (void);
102 -typedef void (*callback_t) (lang_wild_statement_type *, struct wildcard_list *,
103 - asection *, lang_input_statement_type *, void *);
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 @@
110 /* Generic traversal routines for finding matching sections. */
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. */
118 +walk_wild_consider_section (lang_wild_statement_type *ptr,
119 + lang_input_statement_type *file,
121 + struct wildcard_list *sec,
122 + callback_t callback,
125 + bfd_boolean skip = FALSE;
126 + struct name_list *list_tmp;
128 + /* Don't process sections from files which were
130 + for (list_tmp = sec->spec.exclude_name_list;
132 + list_tmp = list_tmp->next)
134 + bfd_boolean is_wildcard = wildcardp (list_tmp->name);
136 + skip = fnmatch (list_tmp->name, file->filename, 0) == 0;
138 + skip = strcmp (list_tmp->name, file->filename) == 0;
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)
147 + skip = fnmatch (list_tmp->name,
148 + file->the_bfd->my_archive->filename,
151 + skip = strcmp (list_tmp->name,
152 + file->the_bfd->my_archive->filename) == 0;
160 + (*callback) (ptr, sec, s, file, data);
163 +/* Lowest common denominator routine that can handle everything correctly,
167 -walk_wild_section (lang_wild_statement_type *ptr,
168 - lang_input_statement_type *file,
169 - callback_t callback,
171 +walk_wild_section_general (lang_wild_statement_type *ptr,
172 + lang_input_statement_type *file,
173 + callback_t callback,
178 - if (file->just_syms_flag)
180 + struct wildcard_list *sec;
182 for (s = file->the_bfd->sections; s != NULL; s = s->next)
184 - struct wildcard_list *sec;
186 sec = ptr->section_list;
188 (*callback) (ptr, sec, s, file, data);
192 bfd_boolean skip = FALSE;
193 - struct name_list *list_tmp;
195 - /* Don't process sections from files which were
197 - for (list_tmp = sec->spec.exclude_name_list;
199 - list_tmp = list_tmp->next)
201 - if (wildcardp (list_tmp->name))
202 - skip = fnmatch (list_tmp->name, file->filename, 0) == 0;
204 - skip = strcmp (list_tmp->name, file->filename) == 0;
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)
212 - if (wildcardp (list_tmp->name))
213 - skip = fnmatch (list_tmp->name,
214 - file->the_bfd->my_archive->filename,
217 - skip = strcmp (list_tmp->name,
218 - file->the_bfd->my_archive->filename) == 0;
225 - if (!skip && sec->spec.name != NULL)
226 + if (sec->spec.name != NULL)
228 const char *sname = bfd_get_section_name (file->the_bfd, s);
230 @@ -220,13 +236,381 @@
234 - (*callback) (ptr, sec, s, file, data);
235 + walk_wild_consider_section (ptr, file, s, sec, callback, data);
242 +/* Routines to find a single section given its name. If there's more
243 + than one section with that name, we report that. */
247 + asection *found_section;
248 + bfd_boolean multiple_sections_found;
249 +} section_iterator_callback_data;
252 +section_iterator_callback (bfd *bfd ATTRIBUTE_UNUSED, asection *s, void *data)
254 + section_iterator_callback_data *d = data;
256 + if (d->found_section != NULL)
258 + d->multiple_sections_found = TRUE;
262 + d->found_section = s;
267 +find_section (lang_input_statement_type *file,
268 + struct wildcard_list *sec,
269 + bfd_boolean *multiple_sections_found)
271 + section_iterator_callback_data cb_data = { NULL, FALSE };
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;
279 +/* Code for handling simple wildcards without going through fnmatch,
280 + which can be expensive because of charset translations etc. */
282 +/* A simple wild is a literal string followed by a single '*',
283 + where the literal part is at least 4 characters long. */
286 +is_simple_wild (const char *name)
288 + size_t len = strcspn (name, "*?[");
289 + return len >= 4 && name[len] == '*' && name[len + 1] == '\0';
293 +match_simple_wild (const char *pattern, const char *name)
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])
303 + while (*pattern != '*')
304 + if (*name++ != *pattern++)
310 +/* Specialized, optimized routines for handling different kinds of
314 +walk_wild_section_specs1_wild0 (lang_wild_statement_type *ptr,
315 + lang_input_statement_type *file,
316 + callback_t callback,
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);
328 + if (multiple_sections_found)
329 + walk_wild_section_general (ptr, file, callback, data);
331 + walk_wild_consider_section (ptr, file, s0, sec0, callback, data);
335 +walk_wild_section_specs1_wild1 (lang_wild_statement_type *ptr,
336 + lang_input_statement_type *file,
337 + callback_t callback,
341 + struct wildcard_list *wildsec0 = ptr->handler_data[0];
343 + for (s = file->the_bfd->sections; s != NULL; s = s->next)
345 + const char *sname = bfd_get_section_name (file->the_bfd, s);
346 + bfd_boolean skip = !match_simple_wild (wildsec0->spec.name, sname);
349 + walk_wild_consider_section (ptr, file, s, wildsec0, callback, data);
354 +walk_wild_section_specs2_wild1 (lang_wild_statement_type *ptr,
355 + lang_input_statement_type *file,
356 + callback_t callback,
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);
365 + if (multiple_sections_found)
367 + walk_wild_section_general (ptr, file, callback, data);
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)
375 + /* Recall that in this code path, a section cannot satisfy more
376 + than one spec, so if s == s0 then it cannot match
379 + walk_wild_consider_section (ptr, file, s, sec0, callback, data);
382 + const char *sname = bfd_get_section_name (file->the_bfd, s);
383 + bfd_boolean skip = !match_simple_wild (wildsec1->spec.name, sname);
386 + walk_wild_consider_section (ptr, file, s, wildsec1, callback,
393 +walk_wild_section_specs3_wild2 (lang_wild_statement_type *ptr,
394 + lang_input_statement_type *file,
395 + callback_t callback,
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);
405 + if (multiple_sections_found)
407 + walk_wild_section_general (ptr, file, callback, data);
411 + for (s = file->the_bfd->sections; s != NULL; s = s->next)
414 + walk_wild_consider_section (ptr, file, s, sec0, callback, data);
417 + const char *sname = bfd_get_section_name (file->the_bfd, s);
418 + bfd_boolean skip = !match_simple_wild (wildsec1->spec.name, sname);
421 + walk_wild_consider_section (ptr, file, s, wildsec1, callback, data);
424 + skip = !match_simple_wild (wildsec2->spec.name, sname);
426 + walk_wild_consider_section (ptr, file, s, wildsec2, callback,
434 +walk_wild_section_specs4_wild2 (lang_wild_statement_type *ptr,
435 + lang_input_statement_type *file,
436 + callback_t callback,
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;
447 + if (multiple_sections_found)
449 + walk_wild_section_general (ptr, file, callback, data);
453 + s1 = find_section (file, sec1, &multiple_sections_found);
454 + if (multiple_sections_found)
456 + walk_wild_section_general (ptr, file, callback, data);
460 + for (s = file->the_bfd->sections; s != NULL; s = s->next)
463 + walk_wild_consider_section (ptr, file, s, sec0, callback, data);
466 + walk_wild_consider_section (ptr, file, s, sec1, callback, data);
469 + const char *sname = bfd_get_section_name (file->the_bfd, s);
470 + bfd_boolean skip = !match_simple_wild (wildsec2->spec.name,
474 + walk_wild_consider_section (ptr, file, s, wildsec2, callback,
478 + skip = !match_simple_wild (wildsec3->spec.name, sname);
480 + walk_wild_consider_section (ptr, file, s, wildsec3,
488 +walk_wild_section (lang_wild_statement_type *ptr,
489 + lang_input_statement_type *file,
490 + callback_t callback,
493 + if (file->just_syms_flag)
496 + (*ptr->walk_wild_section_handler) (ptr, file, callback, data);
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. */
505 +wild_spec_can_overlap (const char *name1, const char *name2)
507 + size_t prefix1_len = strcspn (name1, "?*[");
508 + size_t prefix2_len = strcspn (name2, "?*[");
509 + size_t min_prefix_len;
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')
516 + if (name2[prefix2_len] == '\0')
519 + min_prefix_len = prefix1_len < prefix2_len ? prefix1_len : prefix2_len;
521 + return memcmp (name1, name2, min_prefix_len) == 0;
524 +/* Select specialized code to handle various kinds of wildcard
528 +analyze_walk_wild_section_handler (lang_wild_statement_type *ptr)
531 + int wild_name_count = 0;
532 + struct wildcard_list *sec;
536 + ptr->walk_wild_section_handler = walk_wild_section_general;
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)
547 + if (sec->spec.name == NULL)
549 + if (wildcardp (sec->spec.name))
552 + if (!is_simple_wild (sec->spec.name))
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)
563 + /* Check that no two specs can match the same section. */
564 + for (sec = ptr->section_list; sec != NULL; sec = sec->next)
566 + struct wildcard_list *sec2;
567 + for (sec2 = sec->next; sec2 != NULL; sec2 = sec2->next)
569 + if (wild_spec_can_overlap (sec->spec.name, sec2->spec.name))
574 + signature = (sec_count << 8) + wild_name_count;
578 + ptr->walk_wild_section_handler = walk_wild_section_specs1_wild0;
581 + ptr->walk_wild_section_handler = walk_wild_section_specs1_wild1;
584 + ptr->walk_wild_section_handler = walk_wild_section_specs2_wild1;
587 + ptr->walk_wild_section_handler = walk_wild_section_specs3_wild2;
590 + ptr->walk_wild_section_handler = walk_wild_section_specs4_wild2;
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. */
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;
610 /* Handle a wild statement for a single file F. */
613 @@ -1175,17 +1559,12 @@
615 init_os (lang_output_section_statement_type *s)
617 - lean_section_userdata_type *new;
619 if (s->bfd_section != NULL)
622 if (strcmp (s->name, DISCARD_SECTION_NAME) == 0)
623 einfo (_("%P%F: Illegal use of `%s' section\n"), DISCARD_SECTION_NAME);
625 - new = stat_alloc (SECTION_USERDATA_SIZE);
626 - memset (new, 0, SECTION_USERDATA_SIZE);
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)
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;
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);
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
664 union lang_statement_union *file;
665 } lang_afile_asection_pair_statement_type;
667 -typedef struct lang_wild_statement_struct
668 +typedef struct lang_wild_statement_struct lang_wild_statement_type;
670 +typedef void (*callback_t) (lang_wild_statement_type *, struct wildcard_list *,
671 + asection *, lang_input_statement_type *, void *);
673 +typedef void (*walk_wild_section_handler_t) (lang_wild_statement_type *,
674 + lang_input_statement_type *,
675 + callback_t callback,
678 +struct lang_wild_statement_struct
680 lang_statement_header_type header;
681 const char *filename;
683 struct wildcard_list *section_list;
684 bfd_boolean keep_sections;
685 lang_statement_list_type children;
686 -} lang_wild_statement_type;
688 + walk_wild_section_handler_t walk_wild_section_handler;
689 + struct wildcard_list *handler_data[4];
692 typedef struct lang_address_statement_struct