1 2005-03-29 Jakub Jelinek <jakub@redhat.com>
3 * ldlang.c: Formatting.
4 (walk_wild_consider_section): Remember return value from wildcardp.
5 (is_simple_wild): Use strcspn instead of 2 strpbrk calls and strlen.
6 (wild_spec_can_overlap): Use strcspn instead of strpbrk and strlen.
8 2005-02-17 Robert O'Callahan <rocallahan@novell.com>
10 * ld.h (lean_section_userdata_type): Remove.
11 (fat_section_userdata_type): Remove file field.
12 (SECTION_USERDATA_SIZE): Remove.
13 * ldlang.c (init_os): Eliminate initialization of unused
14 lean_section_userdata_type.
16 * ldlang.h (callback_t, walk_wild_section_handler_t): New
18 (struct lang_wild_statement_struct): Add walk_wild_section_handler
19 and handler_data fields.
20 * ldlang.c (callback_t): Removed.
21 (walk_wild_consider_section, walk_wild_section_general,
22 section_iterator_callback, find_section, is_simple_wild,
23 match_simple_wild, walk_wild_section_specs1_wild0,
24 walk_wild_section_specs1_wild1, walk_wild_section_specs2_wild1,
25 walk_wild_section_specs3_wild2, walk_wild_section_specs4_wild2,
26 wild_spec_can_overlap, analyze_walk_wild_section_handler): New
28 (lang_add_wild): Call analyze_walk_wild_section_handler.
29 (walk_wild_section): Renamed to walk_wild_section_general and
30 created a wrapper function.
31 (section_iterator_callback_data): New typedef.
33 --- ld/ld.h 16 Mar 2005 21:52:42 -0000 1.26
34 +++ ld/ld.h 29 Mar 2005 13:02:02 -0000
35 @@ -89,28 +89,15 @@ struct map_symbol_def {
36 struct map_symbol_def *next;
39 -/* Extra information we hold on sections */
40 -typedef struct lean_user_section_struct {
41 - /* For output sections: pointer to the section where this data will go. */
42 - struct lang_input_statement_struct *file;
43 -} lean_section_userdata_type;
45 /* The initial part of fat_user_section_struct has to be idential with
46 lean_user_section_struct. */
47 typedef struct fat_user_section_struct {
48 - /* For output sections: pointer to the section where this data will go. */
49 - struct lang_input_statement_struct *file;
50 /* For input sections, when writing a map file: head / tail of a linked
51 list of hash table entries for symbols defined in this section. */
52 struct map_symbol_def *map_symbol_def_head;
53 struct map_symbol_def **map_symbol_def_tail;
54 } fat_section_userdata_type;
56 -#define SECTION_USERDATA_SIZE \
57 - (command_line.reduce_memory_overheads \
58 - ? sizeof (lean_section_userdata_type) \
59 - : sizeof (fat_section_userdata_type))
61 #define get_userdata(x) ((x)->userdata)
64 --- ld/ldlang.c 18 Mar 2005 13:56:26 -0000 1.176
65 +++ ld/ldlang.c 29 Mar 2005 13:02:03 -0000
66 @@ -84,9 +84,6 @@ static bfd_boolean lang_one_common (stru
67 static void lang_record_phdrs (void);
68 static void lang_do_version_exports_section (void);
70 -typedef void (*callback_t) (lang_wild_statement_type *, struct wildcard_list *,
71 - asection *, lang_input_statement_type *, void *);
73 /* Exported variables. */
74 lang_output_section_statement_type *abs_output_section;
75 lang_statement_list_type lang_output_section_statement;
76 @@ -155,21 +152,71 @@ unique_section_p (const asection *sec)
78 /* Generic traversal routines for finding matching sections. */
80 +/* Try processing a section against a wildcard. This just calls
81 + the callback unless the filename exclusion list is present
82 + and excludes the file. It's hardly ever present so this
83 + function is very fast. */
86 +walk_wild_consider_section (lang_wild_statement_type *ptr,
87 + lang_input_statement_type *file,
89 + struct wildcard_list *sec,
90 + callback_t callback,
93 + bfd_boolean skip = FALSE;
94 + struct name_list *list_tmp;
96 + /* Don't process sections from files which were
98 + for (list_tmp = sec->spec.exclude_name_list;
100 + list_tmp = list_tmp->next)
102 + bfd_boolean is_wildcard = wildcardp (list_tmp->name);
104 + skip = fnmatch (list_tmp->name, file->filename, 0) == 0;
106 + skip = strcmp (list_tmp->name, file->filename) == 0;
108 + /* If this file is part of an archive, and the archive is
109 + excluded, exclude this file. */
110 + if (! skip && file->the_bfd != NULL
111 + && file->the_bfd->my_archive != NULL
112 + && file->the_bfd->my_archive->filename != NULL)
115 + skip = fnmatch (list_tmp->name,
116 + file->the_bfd->my_archive->filename,
119 + skip = strcmp (list_tmp->name,
120 + file->the_bfd->my_archive->filename) == 0;
128 + (*callback) (ptr, sec, s, file, data);
131 +/* Lowest common denominator routine that can handle everything correctly,
135 -walk_wild_section (lang_wild_statement_type *ptr,
136 - lang_input_statement_type *file,
137 - callback_t callback,
139 +walk_wild_section_general (lang_wild_statement_type *ptr,
140 + lang_input_statement_type *file,
141 + callback_t callback,
146 - if (file->just_syms_flag)
148 + struct wildcard_list *sec;
150 for (s = file->the_bfd->sections; s != NULL; s = s->next)
152 - struct wildcard_list *sec;
154 sec = ptr->section_list;
156 (*callback) (ptr, sec, s, file, data);
157 @@ -177,39 +224,8 @@ walk_wild_section (lang_wild_statement_t
160 bfd_boolean skip = FALSE;
161 - struct name_list *list_tmp;
163 - /* Don't process sections from files which were
165 - for (list_tmp = sec->spec.exclude_name_list;
167 - list_tmp = list_tmp->next)
169 - if (wildcardp (list_tmp->name))
170 - skip = fnmatch (list_tmp->name, file->filename, 0) == 0;
172 - skip = strcmp (list_tmp->name, file->filename) == 0;
174 - /* If this file is part of an archive, and the archive is
175 - excluded, exclude this file. */
176 - if (! skip && file->the_bfd != NULL
177 - && file->the_bfd->my_archive != NULL
178 - && file->the_bfd->my_archive->filename != NULL)
180 - if (wildcardp (list_tmp->name))
181 - skip = fnmatch (list_tmp->name,
182 - file->the_bfd->my_archive->filename,
185 - skip = strcmp (list_tmp->name,
186 - file->the_bfd->my_archive->filename) == 0;
193 - if (!skip && sec->spec.name != NULL)
194 + if (sec->spec.name != NULL)
196 const char *sname = bfd_get_section_name (file->the_bfd, s);
198 @@ -220,13 +236,381 @@ walk_wild_section (lang_wild_statement_t
202 - (*callback) (ptr, sec, s, file, data);
203 + walk_wild_consider_section (ptr, file, s, sec, callback, data);
210 +/* Routines to find a single section given its name. If there's more
211 + than one section with that name, we report that. */
215 + asection *found_section;
216 + bfd_boolean multiple_sections_found;
217 +} section_iterator_callback_data;
220 +section_iterator_callback (bfd *bfd ATTRIBUTE_UNUSED, asection *s, void *data)
222 + section_iterator_callback_data *d = data;
224 + if (d->found_section != NULL)
226 + d->multiple_sections_found = TRUE;
230 + d->found_section = s;
235 +find_section (lang_input_statement_type *file,
236 + struct wildcard_list *sec,
237 + bfd_boolean *multiple_sections_found)
239 + section_iterator_callback_data cb_data = { NULL, FALSE };
241 + bfd_get_section_by_name_if (file->the_bfd, sec->spec.name,
242 + section_iterator_callback, &cb_data);
243 + *multiple_sections_found = cb_data.multiple_sections_found;
244 + return cb_data.found_section;
247 +/* Code for handling simple wildcards without going through fnmatch,
248 + which can be expensive because of charset translations etc. */
250 +/* A simple wild is a literal string followed by a single '*',
251 + where the literal part is at least 4 characters long. */
254 +is_simple_wild (const char *name)
256 + size_t len = strcspn (name, "*?[");
257 + return len >= 4 && name[len] == '*' && name[len + 1] == '\0';
261 +match_simple_wild (const char *pattern, const char *name)
263 + /* The first four characters of the pattern are guaranteed valid
264 + non-wildcard characters. So we can go faster. */
265 + if (pattern[0] != name[0] || pattern[1] != name[1]
266 + || pattern[2] != name[2] || pattern[3] != name[3])
271 + while (*pattern != '*')
272 + if (*name++ != *pattern++)
278 +/* Specialized, optimized routines for handling different kinds of
282 +walk_wild_section_specs1_wild0 (lang_wild_statement_type *ptr,
283 + lang_input_statement_type *file,
284 + callback_t callback,
287 + /* We can just do a hash lookup for the section with the right name.
288 + But if that lookup discovers more than one section with the name
289 + (should be rare), we fall back to the general algorithm because
290 + we would otherwise have to sort the sections to make sure they
291 + get processed in the bfd's order. */
292 + bfd_boolean multiple_sections_found;
293 + struct wildcard_list *sec0 = ptr->handler_data[0];
294 + asection *s0 = find_section (file, sec0, &multiple_sections_found);
296 + if (multiple_sections_found)
297 + walk_wild_section_general (ptr, file, callback, data);
299 + walk_wild_consider_section (ptr, file, s0, sec0, callback, data);
303 +walk_wild_section_specs1_wild1 (lang_wild_statement_type *ptr,
304 + lang_input_statement_type *file,
305 + callback_t callback,
309 + struct wildcard_list *wildsec0 = ptr->handler_data[0];
311 + for (s = file->the_bfd->sections; s != NULL; s = s->next)
313 + const char *sname = bfd_get_section_name (file->the_bfd, s);
314 + bfd_boolean skip = !match_simple_wild (wildsec0->spec.name, sname);
317 + walk_wild_consider_section (ptr, file, s, wildsec0, callback, data);
322 +walk_wild_section_specs2_wild1 (lang_wild_statement_type *ptr,
323 + lang_input_statement_type *file,
324 + callback_t callback,
328 + struct wildcard_list *sec0 = ptr->handler_data[0];
329 + struct wildcard_list *wildsec1 = ptr->handler_data[1];
330 + bfd_boolean multiple_sections_found;
331 + asection *s0 = find_section (file, sec0, &multiple_sections_found);
333 + if (multiple_sections_found)
335 + walk_wild_section_general (ptr, file, callback, data);
339 + /* Note that if the section was not found, s0 is NULL and
340 + we'll simply never succeed the s == s0 test below. */
341 + for (s = file->the_bfd->sections; s != NULL; s = s->next)
343 + /* Recall that in this code path, a section cannot satisfy more
344 + than one spec, so if s == s0 then it cannot match
347 + walk_wild_consider_section (ptr, file, s, sec0, callback, data);
350 + const char *sname = bfd_get_section_name (file->the_bfd, s);
351 + bfd_boolean skip = !match_simple_wild (wildsec1->spec.name, sname);
354 + walk_wild_consider_section (ptr, file, s, wildsec1, callback,
361 +walk_wild_section_specs3_wild2 (lang_wild_statement_type *ptr,
362 + lang_input_statement_type *file,
363 + callback_t callback,
367 + struct wildcard_list *sec0 = ptr->handler_data[0];
368 + struct wildcard_list *wildsec1 = ptr->handler_data[1];
369 + struct wildcard_list *wildsec2 = ptr->handler_data[2];
370 + bfd_boolean multiple_sections_found;
371 + asection *s0 = find_section (file, sec0, &multiple_sections_found);
373 + if (multiple_sections_found)
375 + walk_wild_section_general (ptr, file, callback, data);
379 + for (s = file->the_bfd->sections; s != NULL; s = s->next)
382 + walk_wild_consider_section (ptr, file, s, sec0, callback, data);
385 + const char *sname = bfd_get_section_name (file->the_bfd, s);
386 + bfd_boolean skip = !match_simple_wild (wildsec1->spec.name, sname);
389 + walk_wild_consider_section (ptr, file, s, wildsec1, callback, data);
392 + skip = !match_simple_wild (wildsec2->spec.name, sname);
394 + walk_wild_consider_section (ptr, file, s, wildsec2, callback,
402 +walk_wild_section_specs4_wild2 (lang_wild_statement_type *ptr,
403 + lang_input_statement_type *file,
404 + callback_t callback,
408 + struct wildcard_list *sec0 = ptr->handler_data[0];
409 + struct wildcard_list *sec1 = ptr->handler_data[1];
410 + struct wildcard_list *wildsec2 = ptr->handler_data[2];
411 + struct wildcard_list *wildsec3 = ptr->handler_data[3];
412 + bfd_boolean multiple_sections_found;
413 + asection *s0 = find_section (file, sec0, &multiple_sections_found), *s1;
415 + if (multiple_sections_found)
417 + walk_wild_section_general (ptr, file, callback, data);
421 + s1 = find_section (file, sec1, &multiple_sections_found);
422 + if (multiple_sections_found)
424 + walk_wild_section_general (ptr, file, callback, data);
428 + for (s = file->the_bfd->sections; s != NULL; s = s->next)
431 + walk_wild_consider_section (ptr, file, s, sec0, callback, data);
434 + walk_wild_consider_section (ptr, file, s, sec1, callback, data);
437 + const char *sname = bfd_get_section_name (file->the_bfd, s);
438 + bfd_boolean skip = !match_simple_wild (wildsec2->spec.name,
442 + walk_wild_consider_section (ptr, file, s, wildsec2, callback,
446 + skip = !match_simple_wild (wildsec3->spec.name, sname);
448 + walk_wild_consider_section (ptr, file, s, wildsec3,
456 +walk_wild_section (lang_wild_statement_type *ptr,
457 + lang_input_statement_type *file,
458 + callback_t callback,
461 + if (file->just_syms_flag)
464 + (*ptr->walk_wild_section_handler) (ptr, file, callback, data);
467 +/* Returns TRUE when name1 is a wildcard spec that might match
468 + something name2 can match. We're conservative: we return FALSE
469 + only if the prefixes of name1 and name2 are different up to the
470 + first wildcard character. */
473 +wild_spec_can_overlap (const char *name1, const char *name2)
475 + size_t prefix1_len = strcspn (name1, "?*[");
476 + size_t prefix2_len = strcspn (name2, "?*[");
477 + size_t min_prefix_len;
479 + /* Note that if there is no wildcard character, then we treat the
480 + terminating 0 as part of the prefix. Thus ".text" won't match
481 + ".text." or ".text.*", for example. */
482 + if (name1[prefix1_len] == '\0')
484 + if (name2[prefix2_len] == '\0')
487 + min_prefix_len = prefix1_len < prefix2_len ? prefix1_len : prefix2_len;
489 + return memcmp (name1, name2, min_prefix_len) == 0;
492 +/* Select specialized code to handle various kinds of wildcard
496 +analyze_walk_wild_section_handler (lang_wild_statement_type *ptr)
499 + int wild_name_count = 0;
500 + struct wildcard_list *sec;
504 + ptr->walk_wild_section_handler = walk_wild_section_general;
506 + /* Count how many wildcard_specs there are, and how many of those
507 + actually use wildcards in the name. Also, bail out if any of the
508 + wildcard names are NULL. (Can this actually happen?
509 + walk_wild_section used to test for it.) And bail out if any
510 + of the wildcards are more complex than a simple string
511 + ending in a single '*'. */
512 + for (sec = ptr->section_list; sec != NULL; sec = sec->next)
515 + if (sec->spec.name == NULL)
517 + if (wildcardp (sec->spec.name))
520 + if (!is_simple_wild (sec->spec.name))
525 + /* The zero-spec case would be easy to optimize but it doesn't
526 + happen in practice. Likewise, more than 4 specs doesn't
527 + happen in practice. */
528 + if (sec_count == 0 || sec_count > 4)
531 + /* Check that no two specs can match the same section. */
532 + for (sec = ptr->section_list; sec != NULL; sec = sec->next)
534 + struct wildcard_list *sec2;
535 + for (sec2 = sec->next; sec2 != NULL; sec2 = sec2->next)
537 + if (wild_spec_can_overlap (sec->spec.name, sec2->spec.name))
542 + signature = (sec_count << 8) + wild_name_count;
546 + ptr->walk_wild_section_handler = walk_wild_section_specs1_wild0;
549 + ptr->walk_wild_section_handler = walk_wild_section_specs1_wild1;
552 + ptr->walk_wild_section_handler = walk_wild_section_specs2_wild1;
555 + ptr->walk_wild_section_handler = walk_wild_section_specs3_wild2;
558 + ptr->walk_wild_section_handler = walk_wild_section_specs4_wild2;
564 + /* Now fill the data array with pointers to the specs, first the
565 + specs with non-wildcard names, then the specs with wildcard
566 + names. It's OK to process the specs in different order from the
567 + given order, because we've already determined that no section
568 + will match more than one spec. */
570 + for (sec = ptr->section_list; sec != NULL; sec = sec->next)
571 + if (!wildcardp (sec->spec.name))
572 + ptr->handler_data[data_counter++] = sec;
573 + for (sec = ptr->section_list; sec != NULL; sec = sec->next)
574 + if (wildcardp (sec->spec.name))
575 + ptr->handler_data[data_counter++] = sec;
578 /* Handle a wild statement for a single file F. */
581 @@ -1175,17 +1559,12 @@ sort_def_symbol (hash_entry, info)
583 init_os (lang_output_section_statement_type *s)
585 - lean_section_userdata_type *new;
587 if (s->bfd_section != NULL)
590 if (strcmp (s->name, DISCARD_SECTION_NAME) == 0)
591 einfo (_("%P%F: Illegal use of `%s' section\n"), DISCARD_SECTION_NAME);
593 - new = stat_alloc (SECTION_USERDATA_SIZE);
594 - memset (new, 0, SECTION_USERDATA_SIZE);
596 s->bfd_section = bfd_get_section_by_name (output_bfd, s->name);
597 if (s->bfd_section == NULL)
598 s->bfd_section = bfd_make_section (output_bfd, s->name);
599 @@ -1199,7 +1578,14 @@ init_os (lang_output_section_statement_t
600 /* We initialize an output sections output offset to minus its own
601 vma to allow us to output a section through itself. */
602 s->bfd_section->output_offset = 0;
603 - get_userdata (s->bfd_section) = new;
604 + if (!command_line.reduce_memory_overheads)
606 + fat_section_userdata_type *new
607 + = stat_alloc (sizeof (fat_section_userdata_type));
608 + memset (new, 0, sizeof (fat_section_userdata_type));
609 + get_userdata (s->bfd_section) = new;
613 /* If there is a base address, make sure that any sections it might
614 mention are initialized. */
615 @@ -4939,6 +5325,7 @@ lang_add_wild (struct wildcard_spec *fil
616 new->section_list = section_list;
617 new->keep_sections = keep_sections;
618 lang_list_init (&new->children);
619 + analyze_walk_wild_section_handler (new);
623 --- ld/ldlang.h 3 Mar 2005 11:51:58 -0000 1.44
624 +++ ld/ldlang.h 29 Mar 2005 13:02:03 -0000
625 @@ -298,7 +298,17 @@ typedef struct
626 union lang_statement_union *file;
627 } lang_afile_asection_pair_statement_type;
629 -typedef struct lang_wild_statement_struct
630 +typedef struct lang_wild_statement_struct lang_wild_statement_type;
632 +typedef void (*callback_t) (lang_wild_statement_type *, struct wildcard_list *,
633 + asection *, lang_input_statement_type *, void *);
635 +typedef void (*walk_wild_section_handler_t) (lang_wild_statement_type *,
636 + lang_input_statement_type *,
637 + callback_t callback,
640 +struct lang_wild_statement_struct
642 lang_statement_header_type header;
643 const char *filename;
644 @@ -306,7 +316,10 @@ typedef struct lang_wild_statement_struc
645 struct wildcard_list *section_list;
646 bfd_boolean keep_sections;
647 lang_statement_list_type children;
648 -} lang_wild_statement_type;
650 + walk_wild_section_handler_t walk_wild_section_handler;
651 + struct wildcard_list *handler_data[4];
654 typedef struct lang_address_statement_struct