]> git.pld-linux.org Git - packages/binutils.git/blob - binutils-ld-speedup.patch
This commit was manufactured by cvs2git to create branch 'AC-branch'.
[packages/binutils.git] / binutils-ld-speedup.patch
1 2005-03-29  Jakub Jelinek  <jakub@redhat.com>
2
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.
7
8 2005-02-17  Robert O'Callahan  <rocallahan@novell.com>
9
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.
15
16         * ldlang.h (callback_t, walk_wild_section_handler_t): New
17         typedefs.
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
27         functions.
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.
32
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;
37  };
38  
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;
44 -
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;
55  
56 -#define SECTION_USERDATA_SIZE \
57 - (command_line.reduce_memory_overheads \
58 -  ? sizeof (lean_section_userdata_type) \
59 -  : sizeof (fat_section_userdata_type))
60 -
61  #define get_userdata(x) ((x)->userdata)
62  
63  #define BYTE_SIZE      (1)
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);
69  
70 -typedef void (*callback_t) (lang_wild_statement_type *, struct wildcard_list *,
71 -                           asection *, lang_input_statement_type *, void *);
72 -
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)
77  
78  /* Generic traversal routines for finding matching sections.  */
79  
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.  */
84 +
85 +static void
86 +walk_wild_consider_section (lang_wild_statement_type *ptr,
87 +                           lang_input_statement_type *file,
88 +                           asection *s,
89 +                           struct wildcard_list *sec,
90 +                           callback_t callback,
91 +                           void *data)
92 +{
93 +  bfd_boolean skip = FALSE;
94 +  struct name_list *list_tmp;
95 +
96 +  /* Don't process sections from files which were
97 +     excluded.  */
98 +  for (list_tmp = sec->spec.exclude_name_list;
99 +       list_tmp;
100 +       list_tmp = list_tmp->next)
101 +    {
102 +      bfd_boolean is_wildcard = wildcardp (list_tmp->name);
103 +      if (is_wildcard)
104 +       skip = fnmatch (list_tmp->name, file->filename, 0) == 0;
105 +      else
106 +       skip = strcmp (list_tmp->name, file->filename) == 0;
107 +
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)
113 +       {
114 +         if (is_wildcard)
115 +           skip = fnmatch (list_tmp->name,
116 +                           file->the_bfd->my_archive->filename,
117 +                           0) == 0;
118 +         else
119 +           skip = strcmp (list_tmp->name,
120 +                          file->the_bfd->my_archive->filename) == 0;
121 +       }
122 +
123 +      if (skip)
124 +       break;
125 +    }
126 +
127 +  if (!skip)
128 +    (*callback) (ptr, sec, s, file, data);
129 +}
130 +
131 +/* Lowest common denominator routine that can handle everything correctly,
132 +   but slowly.  */
133 +
134  static void
135 -walk_wild_section (lang_wild_statement_type *ptr,
136 -                  lang_input_statement_type *file,
137 -                  callback_t callback,
138 -                  void *data)
139 +walk_wild_section_general (lang_wild_statement_type *ptr,
140 +                          lang_input_statement_type *file,
141 +                          callback_t callback,
142 +                          void *data)
143  {
144    asection *s;
145 -
146 -  if (file->just_syms_flag)
147 -    return;
148 +  struct wildcard_list *sec;
149  
150    for (s = file->the_bfd->sections; s != NULL; s = s->next)
151      {
152 -      struct wildcard_list *sec;
153 -
154        sec = ptr->section_list;
155        if (sec == NULL)
156         (*callback) (ptr, sec, s, file, data);
157 @@ -177,39 +224,8 @@ walk_wild_section (lang_wild_statement_t
158        while (sec != NULL)
159         {
160           bfd_boolean skip = FALSE;
161 -         struct name_list *list_tmp;
162  
163 -         /* Don't process sections from files which were
164 -            excluded.  */
165 -         for (list_tmp = sec->spec.exclude_name_list;
166 -              list_tmp;
167 -              list_tmp = list_tmp->next)
168 -           {
169 -             if (wildcardp (list_tmp->name))
170 -               skip = fnmatch (list_tmp->name, file->filename, 0) == 0;
171 -             else
172 -               skip = strcmp (list_tmp->name, file->filename) == 0;
173 -
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)
179 -               {
180 -                 if (wildcardp (list_tmp->name))
181 -                   skip = fnmatch (list_tmp->name,
182 -                                   file->the_bfd->my_archive->filename,
183 -                                   0) == 0;
184 -                 else
185 -                   skip = strcmp (list_tmp->name,
186 -                                  file->the_bfd->my_archive->filename) == 0;
187 -               }
188 -
189 -             if (skip)
190 -               break;
191 -           }
192 -
193 -         if (!skip && sec->spec.name != NULL)
194 +         if (sec->spec.name != NULL)
195             {
196               const char *sname = bfd_get_section_name (file->the_bfd, s);
197  
198 @@ -220,13 +236,381 @@ walk_wild_section (lang_wild_statement_t
199             }
200  
201           if (!skip)
202 -           (*callback) (ptr, sec, s, file, data);
203 +           walk_wild_consider_section (ptr, file, s, sec, callback, data);
204  
205           sec = sec->next;
206         }
207      }
208  }
209  
210 +/* Routines to find a single section given its name.  If there's more
211 +   than one section with that name, we report that.  */
212 +
213 +typedef struct
214 +{
215 +  asection *found_section;
216 +  bfd_boolean multiple_sections_found;
217 +} section_iterator_callback_data;
218 +
219 +static bfd_boolean
220 +section_iterator_callback (bfd *bfd ATTRIBUTE_UNUSED, asection *s, void *data)
221 +{
222 +  section_iterator_callback_data *d = data;
223 +
224 +  if (d->found_section != NULL)
225 +    {
226 +      d->multiple_sections_found = TRUE;
227 +      return TRUE;
228 +    }
229 +
230 +  d->found_section = s;
231 +  return FALSE;
232 +}
233 +
234 +static asection *
235 +find_section (lang_input_statement_type *file,
236 +             struct wildcard_list *sec,
237 +             bfd_boolean *multiple_sections_found)
238 +{
239 +  section_iterator_callback_data cb_data = { NULL, FALSE };
240 +
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;
245 +}
246 +
247 +/* Code for handling simple wildcards without going through fnmatch,
248 +   which can be expensive because of charset translations etc.  */
249 +
250 +/* A simple wild is a literal string followed by a single '*',
251 +   where the literal part is at least 4 characters long.  */
252 +
253 +static bfd_boolean
254 +is_simple_wild (const char *name)
255 +{
256 +  size_t len = strcspn (name, "*?[");
257 +  return len >= 4 && name[len] == '*' && name[len + 1] == '\0';
258 +}
259 +
260 +static bfd_boolean
261 +match_simple_wild (const char *pattern, const char *name)
262 +{
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])
267 +    return FALSE;
268 +
269 +  pattern += 4;
270 +  name += 4;
271 +  while (*pattern != '*')
272 +    if (*name++ != *pattern++)
273 +      return FALSE;
274 +
275 +  return TRUE;
276 +}
277 +
278 +/* Specialized, optimized routines for handling different kinds of
279 +   wildcards */
280 +
281 +static void
282 +walk_wild_section_specs1_wild0 (lang_wild_statement_type *ptr,
283 +                               lang_input_statement_type *file,
284 +                               callback_t callback,
285 +                               void *data)
286 +{
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);
295 +
296 +  if (multiple_sections_found)
297 +    walk_wild_section_general (ptr, file, callback, data);
298 +  else if (s0)
299 +    walk_wild_consider_section (ptr, file, s0, sec0, callback, data);
300 +}
301 +
302 +static void
303 +walk_wild_section_specs1_wild1 (lang_wild_statement_type *ptr,
304 +                               lang_input_statement_type *file,
305 +                               callback_t callback,
306 +                               void *data)
307 +{
308 +  asection *s;
309 +  struct wildcard_list *wildsec0 = ptr->handler_data[0];
310 +
311 +  for (s = file->the_bfd->sections; s != NULL; s = s->next)
312 +    {
313 +      const char *sname = bfd_get_section_name (file->the_bfd, s);
314 +      bfd_boolean skip = !match_simple_wild (wildsec0->spec.name, sname);
315 +
316 +      if (!skip)
317 +       walk_wild_consider_section (ptr, file, s, wildsec0, callback, data);
318 +    }
319 +}
320 +
321 +static void
322 +walk_wild_section_specs2_wild1 (lang_wild_statement_type *ptr,
323 +                               lang_input_statement_type *file,
324 +                               callback_t callback,
325 +                               void *data)
326 +{
327 +  asection *s;
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);
332 +
333 +  if (multiple_sections_found)
334 +    {
335 +      walk_wild_section_general (ptr, file, callback, data);
336 +      return;
337 +    }
338 +
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)
342 +    {
343 +      /* Recall that in this code path, a section cannot satisfy more
344 +        than one spec, so if s == s0 then it cannot match
345 +        wildspec1.  */
346 +      if (s == s0)
347 +       walk_wild_consider_section (ptr, file, s, sec0, callback, data);
348 +      else
349 +       {
350 +         const char *sname = bfd_get_section_name (file->the_bfd, s);
351 +         bfd_boolean skip = !match_simple_wild (wildsec1->spec.name, sname);
352 +
353 +         if (!skip)
354 +           walk_wild_consider_section (ptr, file, s, wildsec1, callback,
355 +                                       data);
356 +       }
357 +    }
358 +}
359 +
360 +static void
361 +walk_wild_section_specs3_wild2 (lang_wild_statement_type *ptr,
362 +                               lang_input_statement_type *file,
363 +                               callback_t callback,
364 +                               void *data)
365 +{
366 +  asection *s;
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);
372 +
373 +  if (multiple_sections_found)
374 +    {
375 +      walk_wild_section_general (ptr, file, callback, data);
376 +      return;
377 +    }
378 +
379 +  for (s = file->the_bfd->sections; s != NULL; s = s->next)
380 +    {
381 +      if (s == s0)
382 +       walk_wild_consider_section (ptr, file, s, sec0, callback, data);
383 +      else
384 +       {
385 +         const char *sname = bfd_get_section_name (file->the_bfd, s);
386 +         bfd_boolean skip = !match_simple_wild (wildsec1->spec.name, sname);
387 +
388 +         if (!skip)
389 +           walk_wild_consider_section (ptr, file, s, wildsec1, callback, data);
390 +         else
391 +           {
392 +             skip = !match_simple_wild (wildsec2->spec.name, sname);
393 +             if (!skip)
394 +               walk_wild_consider_section (ptr, file, s, wildsec2, callback,
395 +                                           data);
396 +           }
397 +       }
398 +    }
399 +}
400 +
401 +static void
402 +walk_wild_section_specs4_wild2 (lang_wild_statement_type *ptr,
403 +                               lang_input_statement_type *file,
404 +                               callback_t callback,
405 +                               void *data)
406 +{
407 +  asection *s;
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;
414 +
415 +  if (multiple_sections_found)
416 +    {
417 +      walk_wild_section_general (ptr, file, callback, data);
418 +      return;
419 +    }
420 +
421 +  s1 = find_section (file, sec1, &multiple_sections_found);
422 +  if (multiple_sections_found)
423 +    {
424 +      walk_wild_section_general (ptr, file, callback, data);
425 +      return;
426 +    }
427 +
428 +  for (s = file->the_bfd->sections; s != NULL; s = s->next)
429 +    {
430 +      if (s == s0)
431 +       walk_wild_consider_section (ptr, file, s, sec0, callback, data);
432 +      else
433 +       if (s == s1)
434 +         walk_wild_consider_section (ptr, file, s, sec1, callback, data);
435 +       else
436 +         {
437 +           const char *sname = bfd_get_section_name (file->the_bfd, s);
438 +           bfd_boolean skip = !match_simple_wild (wildsec2->spec.name,
439 +                                                  sname);
440 +
441 +           if (!skip)
442 +             walk_wild_consider_section (ptr, file, s, wildsec2, callback,
443 +                                         data);
444 +           else
445 +             {
446 +               skip = !match_simple_wild (wildsec3->spec.name, sname);
447 +               if (!skip)
448 +                 walk_wild_consider_section (ptr, file, s, wildsec3,
449 +                                             callback, data);
450 +             }
451 +         }
452 +    }
453 +}
454 +
455 +static void
456 +walk_wild_section (lang_wild_statement_type *ptr,
457 +                  lang_input_statement_type *file,
458 +                  callback_t callback,
459 +                  void *data)
460 +{
461 +  if (file->just_syms_flag)
462 +    return;
463 +
464 +  (*ptr->walk_wild_section_handler) (ptr, file, callback, data);
465 +}
466 +
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.  */
471 +
472 +static bfd_boolean
473 +wild_spec_can_overlap (const char *name1, const char *name2)
474 +{
475 +  size_t prefix1_len = strcspn (name1, "?*[");
476 +  size_t prefix2_len = strcspn (name2, "?*[");
477 +  size_t min_prefix_len;
478 +
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')
483 +    prefix1_len++;
484 +  if (name2[prefix2_len] == '\0')
485 +    prefix2_len++;
486 +
487 +  min_prefix_len = prefix1_len < prefix2_len ? prefix1_len : prefix2_len;
488 +
489 +  return memcmp (name1, name2, min_prefix_len) == 0;
490 +}
491 +
492 +/* Select specialized code to handle various kinds of wildcard
493 +   statements.  */
494 +
495 +static void
496 +analyze_walk_wild_section_handler (lang_wild_statement_type *ptr)
497 +{
498 +  int sec_count = 0;
499 +  int wild_name_count = 0;
500 +  struct wildcard_list *sec;
501 +  int signature;
502 +  int data_counter;
503 +
504 +  ptr->walk_wild_section_handler = walk_wild_section_general;
505 +
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)
513 +    {
514 +      ++sec_count;
515 +      if (sec->spec.name == NULL)
516 +       return;
517 +      if (wildcardp (sec->spec.name))
518 +       {
519 +         ++wild_name_count;
520 +         if (!is_simple_wild (sec->spec.name))
521 +           return;
522 +       }
523 +    }
524 +
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)
529 +    return;
530 +
531 +  /* Check that no two specs can match the same section.  */
532 +  for (sec = ptr->section_list; sec != NULL; sec = sec->next)
533 +    {
534 +      struct wildcard_list *sec2;
535 +      for (sec2 = sec->next; sec2 != NULL; sec2 = sec2->next)
536 +       {
537 +         if (wild_spec_can_overlap (sec->spec.name, sec2->spec.name))
538 +           return;
539 +       }
540 +    }
541 +
542 +  signature = (sec_count << 8) + wild_name_count;
543 +  switch (signature)
544 +    {
545 +    case 0x0100:
546 +      ptr->walk_wild_section_handler = walk_wild_section_specs1_wild0;
547 +      break;
548 +    case 0x0101:
549 +      ptr->walk_wild_section_handler = walk_wild_section_specs1_wild1;
550 +      break;
551 +    case 0x0201:
552 +      ptr->walk_wild_section_handler = walk_wild_section_specs2_wild1;
553 +      break;
554 +    case 0x0302:
555 +      ptr->walk_wild_section_handler = walk_wild_section_specs3_wild2;
556 +      break;
557 +    case 0x0402:
558 +      ptr->walk_wild_section_handler = walk_wild_section_specs4_wild2;
559 +      break;
560 +    default:
561 +      return;
562 +    }
563 +
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.  */
569 +  data_counter = 0;
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;
576 +}
577 +
578  /* Handle a wild statement for a single file F.  */
579  
580  static void
581 @@ -1175,17 +1559,12 @@ sort_def_symbol (hash_entry, info)
582  static void
583  init_os (lang_output_section_statement_type *s)
584  {
585 -  lean_section_userdata_type *new;
586 -
587    if (s->bfd_section != NULL)
588      return;
589  
590    if (strcmp (s->name, DISCARD_SECTION_NAME) == 0)
591      einfo (_("%P%F: Illegal use of `%s' section\n"), DISCARD_SECTION_NAME);
592  
593 -  new = stat_alloc (SECTION_USERDATA_SIZE);
594 -  memset (new, 0, SECTION_USERDATA_SIZE);
595 -
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)
605 +    {
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;
610 +    }
611 +
612  
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);
620  }
621  
622  void
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;
628  
629 -typedef struct lang_wild_statement_struct
630 +typedef struct lang_wild_statement_struct lang_wild_statement_type;
631 +
632 +typedef void (*callback_t) (lang_wild_statement_type *, struct wildcard_list *,
633 +                           asection *, lang_input_statement_type *, void *);
634 +
635 +typedef void (*walk_wild_section_handler_t) (lang_wild_statement_type *,
636 +                                            lang_input_statement_type *,
637 +                                            callback_t callback,
638 +                                            void *data);
639 +
640 +struct lang_wild_statement_struct
641  {
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;
649 +
650 +  walk_wild_section_handler_t walk_wild_section_handler;
651 +  struct wildcard_list *handler_data[4];
652 +};
653  
654  typedef struct lang_address_statement_struct
655  {
This page took 0.118167 seconds and 3 git commands to generate.