Update the list of kernel 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