From 09675b4f911fc6e251a5584c76dc70ac5bbf5fd4 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Fri, 3 Aug 2001 01:11:21 +0000 Subject: [PATCH] * ld.texinfo (Input Section Basics): Clarify ordering of output sections. * ldlang.c (callback_t): Add wildcard_list param. (walk_wild_section): Remove "section" param. Rewrite for lang_wild_statement_type change. Remove unique_section_p test. (walk_wild_file): Remove "section" param. (walk_wild): Remove "section" and "file" params. (lang_gc_wild): Likewise. (wild): Likewise. Modify for lang_wild_statement_type change. (wild_sort): Likewise. Add "sec" param. (gc_section_callback): Likewise. (output_section_callback): Likewise. Do unique_section_p test. (map_input_to_output_sections): Modify call to wild. (lang_gc_sections_1): Likewise. (print_wild_statement): Modify for lang_wild_statement_type change. (lang_add_wild): Replace filename, filenames_sorted param with filespec. Replace section_name, sections_sorted, exclude_filename_list with section_list. * ldlang.h (lang_add_wild): Here too. (lang_wild_statement_type): Replace section_name, sections_sorted, and exclude_filename_list with section_list. * ldgram.y (current_file): Delete. (%union): Add wildcard_list. (file_NAME_list): Set type to wildcard_list. Build a linked list rather than calling lang_add_wild for each entry. (input_section_spec_no_keep): Call lang_add_wild here instead. * ld.h (struct wildcard_list): Declare. * mri.c (mri_draw_tree): Modify to suit new lang_add_wild. --- ld/ChangeLog | 94 +++++++++++++------ ld/ld.h | 5 + ld/ld.texinfo | 3 +- ld/ldgram.y | 49 +++++----- ld/ldlang.c | 297 +++++++++++++++++++++++++++++++--------------------------- ld/ldlang.h | 6 +- ld/mri.c | 17 +++- 7 files changed, 269 insertions(+), 202 deletions(-) diff --git a/ld/ChangeLog b/ld/ChangeLog index 26ea897cc..956682c69 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,50 +1,82 @@ +2001-08-03 Alan Modra + + * ld.texinfo (Input Section Basics): Clarify ordering of output + sections. + * ldlang.c (callback_t): Add wildcard_list param. + (walk_wild_section): Remove "section" param. Rewrite for + lang_wild_statement_type change. Remove unique_section_p test. + (walk_wild_file): Remove "section" param. + (walk_wild): Remove "section" and "file" params. + (lang_gc_wild): Likewise. + (wild): Likewise. Modify for lang_wild_statement_type change. + (wild_sort): Likewise. Add "sec" param. + (gc_section_callback): Likewise. + (output_section_callback): Likewise. Do unique_section_p test. + (map_input_to_output_sections): Modify call to wild. + (lang_gc_sections_1): Likewise. + (print_wild_statement): Modify for lang_wild_statement_type + change. + (lang_add_wild): Replace filename, filenames_sorted param with + filespec. Replace section_name, sections_sorted, + exclude_filename_list with section_list. + * ldlang.h (lang_add_wild): Here too. + (lang_wild_statement_type): Replace section_name, sections_sorted, + and exclude_filename_list with section_list. + * ldgram.y (current_file): Delete. + (%union): Add wildcard_list. + (file_NAME_list): Set type to wildcard_list. Build a linked list + rather than calling lang_add_wild for each entry. + (input_section_spec_no_keep): Call lang_add_wild here instead. + * ld.h (struct wildcard_list): Declare. + * mri.c (mri_draw_tree): Modify to suit new lang_add_wild. + 2001-08-02 Charles Wilson * ldmain.c (main): initialize link_info.pei386_auto_import * pe-dll.c: new tables for auto-export filtering (auto_export): change API, pass abfd for contextual filtering. - Loop thru tables of excluded symbols instead of comparing + Loop thru tables of excluded symbols instead of comparing "by hand". 2001-08-02 Paul Sokolovsky - * pe-dll.c: new variable pe_dll_enable_extra_debug. New - static variable current_sec (static struct sec *). Add + * pe-dll.c: new variable pe_dll_enable_extra_debug. New + static variable current_sec (static struct sec *). Add forward declaration for add_bfd_to_link. - (process_def_file): Don't export undefined symbols. Do not - export symbols starting with "_imp__". Call auto_export() + (process_def_file): Don't export undefined symbols. Do not + export symbols starting with "_imp__". Call auto_export() with new API. (pe_walk_relocs_of_symbol): New function. (generate_reloc): add optional extra debugging - (pe_dll_generate_def_file): eliminate extraneous initial blank + (pe_dll_generate_def_file): eliminate extraneous initial blank line in output - (make_one): enlarge symtab to make room for __nm__ symbols + (make_one): enlarge symtab to make room for __nm__ symbols (DATA auto-import support). (make_singleton_name_thunk): New function. (make_import_fixup_mark): New function. (make_import_fixup_entry): New function. (pe_create_import_fixup): New function. - (add_bfd_to_link): Specify that 'name' argument is a CONST + (add_bfd_to_link): Specify that 'name' argument is a CONST char *. - * pe-dll.h: declare new variable pe_dll_extra_pe_debug; - declare new functions pe_walk_relocs_of_symbol and + * pe-dll.h: declare new variable pe_dll_extra_pe_debug; + declare new functions pe_walk_relocs_of_symbol and pe_create_import_fixup. * emultempl/pe.em: add new options --enable-auto-import, --disable-auto-import, and --enable-extra-pe-debug. (make_import_fixup): New function. (pe_find_data_imports): New function. (pr_sym): New function. - (gld_${EMULATION_NAME}_after_open): Add optional extra pe + (gld_${EMULATION_NAME}_after_open): Add optional extra pe debugging. Call pe_find_data_imports. Mark .idata as DATA, not CODE. 2001-08-02 Charles Wilson - + * ld.texinfo: add additional documentation for --export-all-symbols. Document --out-implib, --enable-auto-image-base, --disable-auto-image-base, - --dll-search-prefix, --enable-auto-import, and - --disable-auto-import. + --dll-search-prefix, --enable-auto-import, and + --disable-auto-import. * ldint.texinfo: Add detailed documentation on auto-import implementation. @@ -166,11 +198,11 @@ 2001-06-18 H.J. Lu - * Makefile.am (ld.1): Remove the prefix `$(srcdir)/'. - (diststuff): Add $(MANS). - * Makefile.in: Regenerated. + * Makefile.am (ld.1): Remove the prefix `$(srcdir)/'. + (diststuff): Add $(MANS). + * Makefile.in: Regenerated. - * ld.1: Removed. + * ld.1: Removed. 2001-06-18 Hans-Peter Nilsson @@ -208,9 +240,9 @@ * ldlang.c (walk_wild): Only call walk_wild_file if lookup_name returns something. - (lookup_name): If load_symbols fails, return NULL. - (load_symbols): Chnage to a boolean function. - (open_input_bfds): If load_symbols fails then do not make the + (lookup_name): If load_symbols fails, return NULL. + (load_symbols): Chnage to a boolean function. + (open_input_bfds): If load_symbols fails then do not make the executable. 2001-06-08 Alan Modra @@ -388,12 +420,12 @@ 2001-05-02 Johan Rydberg - * emulparams/elf32openrisc.sh: New file. + * emulparams/elf32openrisc.sh: New file. - * Makefile.am: Add OpenRISC target. - * Makefile.in: Regenerated. + * Makefile.am: Add OpenRISC target. + * Makefile.in: Regenerated. - * configure.tgt: Add openrisc-*-* mapping. + * configure.tgt: Add openrisc-*-* mapping. 2001-05-02 Nick Clifton @@ -422,9 +454,9 @@ 2001-04-28 Paul Sokolovsky - * ldlang.c (load_symbols): Give emulation a chance - to process unrecognized file before fatal error is - reported, not after. + * ldlang.c (load_symbols): Give emulation a chance + to process unrecognized file before fatal error is + reported, not after. 2001-04-27 Sean McNeil @@ -558,9 +590,9 @@ 2001-02-26 H.J. Lu * ldlang.c (open_input_bfds): Set the bfd error handler so - that problems can be caught whilst loading symbols. - (record_bfd_errors): New function: Report BFD errors and mark - the executable output as being invalid. + that problems can be caught whilst loading symbols. + (record_bfd_errors): New function: Report BFD errors and mark + the executable output as being invalid. 2001-02-22 Timothy Wall diff --git a/ld/ld.h b/ld/ld.h index 3d64e5658..71ac5c930 100644 --- a/ld/ld.h +++ b/ld/ld.h @@ -73,6 +73,11 @@ struct wildcard_spec { boolean sorted; }; +struct wildcard_list { + struct wildcard_list *next; + struct wildcard_spec spec; +}; + /* Extra information we hold on sections */ typedef struct user_section_struct { /* Pointer to the section where this data will go */ diff --git a/ld/ld.texinfo b/ld/ld.texinfo index 634ce6496..a8778d994 100644 --- a/ld/ld.texinfo +++ b/ld/ld.texinfo @@ -2539,7 +2539,8 @@ There are two ways to include more than one section: @noindent The difference between these is the order in which the @samp{.text} and @samp{.rdata} input sections will appear in the output section. In the -first example, they will be intermingled. In the second example, all +first example, they will be intermingled, appearing in the same order as +they are found in the linker input. In the second example, all @samp{.text} input sections will appear first, followed by all @samp{.rdata} input sections. diff --git a/ld/ldgram.y b/ld/ldgram.y index e7f4a590d..5e9fd6218 100644 --- a/ld/ldgram.y +++ b/ld/ldgram.y @@ -49,7 +49,6 @@ static enum section_type sectype; lang_memory_region_type *region; -struct wildcard_spec current_file; boolean ldgram_want_filename = true; boolean had_script = false; boolean force_make_executable = false; @@ -70,6 +69,7 @@ static int error_index; char *name; const char *cname; struct wildcard_spec wildcard; + struct wildcard_list *wildcard_list; struct name_list *name_list; int token; union etree_union *etree; @@ -91,6 +91,7 @@ static int error_index; %type opt_exp_without_type %type fill_opt %type exclude_name_list +%type file_NAME_list %type memspec_opt casesymlist %type memspec_at_opt %type wildcard_name @@ -417,8 +418,6 @@ wildcard_spec: } ; - - exclude_name_list: exclude_name_list wildcard_name { @@ -440,42 +439,42 @@ exclude_name_list: ; file_NAME_list: - wildcard_spec + file_NAME_list opt_comma wildcard_spec { - lang_add_wild ($1.name, $1.sorted, - current_file.name, - current_file.sorted, - ldgram_had_keep, $1.exclude_name_list); + struct wildcard_list *tmp; + tmp = (struct wildcard_list *) xmalloc (sizeof *tmp); + tmp->next = $1; + tmp->spec = $3; + $$ = tmp; } - | file_NAME_list opt_comma wildcard_spec + | + wildcard_spec { - lang_add_wild ($3.name, $3.sorted, - current_file.name, - current_file.sorted, - ldgram_had_keep, $3.exclude_name_list); + struct wildcard_list *tmp; + tmp = (struct wildcard_list *) xmalloc (sizeof *tmp); + tmp->next = NULL; + tmp->spec = $1; + $$ = tmp; } ; input_section_spec_no_keep: NAME { - lang_add_wild (NULL, false, $1, false, - ldgram_had_keep, NULL); + struct wildcard_spec tmp; + tmp.name = $1; + tmp.exclude_name_list = NULL; + tmp.sorted = false; + lang_add_wild (&tmp, NULL, ldgram_had_keep); } - | '[' + | '[' file_NAME_list ']' { - current_file.name = NULL; - current_file.sorted = false; + lang_add_wild (NULL, $2, ldgram_had_keep); } - file_NAME_list ']' - | wildcard_spec + | wildcard_spec '(' file_NAME_list ')' { - current_file = $1; - /* '*' matches any file name. */ - if (strcmp (current_file.name, "*") == 0) - current_file.name = NULL; + lang_add_wild (&$1, $3, ldgram_had_keep); } - '(' file_NAME_list ')' ; input_section_spec: diff --git a/ld/ldlang.c b/ld/ldlang.c index 3f3c1fe7e..968144a9d 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -78,16 +78,16 @@ static void already_linked_table_init PARAMS ((void)); static void already_linked_table_free PARAMS ((void)); static boolean wildcardp PARAMS ((const char *)); static lang_statement_union_type *wild_sort - PARAMS ((lang_wild_statement_type *, lang_input_statement_type *, - asection *)); + PARAMS ((lang_wild_statement_type *, struct wildcard_list *, + lang_input_statement_type *, asection *)); static void output_section_callback - PARAMS ((lang_wild_statement_type *, asection *, + PARAMS ((lang_wild_statement_type *, struct wildcard_list *, asection *, lang_input_statement_type *, PTR)); static lang_input_statement_type *lookup_name PARAMS ((const char *)); static boolean load_symbols PARAMS ((lang_input_statement_type *, lang_statement_list_type *)); static void wild - PARAMS ((lang_wild_statement_type *, const char *, const char *, + PARAMS ((lang_wild_statement_type *, const char *, lang_output_section_statement_type *)); static bfd *open_output PARAMS ((const char *)); static void ldlang_open_output PARAMS ((lang_statement_union_type *)); @@ -135,11 +135,10 @@ static int topower PARAMS ((int)); static void lang_set_startof PARAMS ((void)); static void reset_memory_regions PARAMS ((void)); static void gc_section_callback - PARAMS ((lang_wild_statement_type *, asection *, + PARAMS ((lang_wild_statement_type *, struct wildcard_list *, asection *, lang_input_statement_type *, PTR)); static void lang_record_phdrs PARAMS ((void)); -static void lang_gc_wild - PARAMS ((lang_wild_statement_type *, const char *, const char *)); +static void lang_gc_wild PARAMS ((lang_wild_statement_type *)); static void lang_gc_sections_1 PARAMS ((lang_statement_union_type *)); static void lang_gc_sections PARAMS ((void)); static int lang_vers_match_lang_c @@ -155,17 +154,18 @@ static void os_region_check struct memory_region_struct *, etree_type *, bfd_vma)); typedef void (*callback_t) PARAMS ((lang_wild_statement_type *, - asection *, lang_input_statement_type *, + struct wildcard_list *, + asection *, + lang_input_statement_type *, PTR)); static void walk_wild - PARAMS ((lang_wild_statement_type *, const char *, const char *, - callback_t, PTR)); + PARAMS ((lang_wild_statement_type *, callback_t, PTR)); static void walk_wild_section - PARAMS ((lang_wild_statement_type *, const char *, - lang_input_statement_type *, callback_t, PTR)); + PARAMS ((lang_wild_statement_type *, lang_input_statement_type *, + callback_t, PTR)); static void walk_wild_file - PARAMS ((lang_wild_statement_type *, const char *, - lang_input_statement_type *, callback_t, PTR)); + PARAMS ((lang_wild_statement_type *, lang_input_statement_type *, + callback_t, PTR)); static int get_target PARAMS ((const bfd_target *, PTR)); static void stricpy PARAMS ((char *, char *)); @@ -236,74 +236,78 @@ unique_section_p (secnam) /* Generic traversal routines for finding matching sections. */ static void -walk_wild_section (ptr, section, file, callback, data) +walk_wild_section (ptr, file, callback, data) lang_wild_statement_type *ptr; - const char *section; lang_input_statement_type *file; callback_t callback; PTR data; { - /* Don't process sections from files which were excluded. */ - if (ptr->exclude_filename_list != NULL) + asection *s; + + if (file->just_syms_flag) + return; + + for (s = file->the_bfd->sections; s != NULL; s = s->next) { - struct name_list *list_tmp; - for (list_tmp = ptr->exclude_filename_list; - list_tmp; - list_tmp = list_tmp->next) + struct wildcard_list *sec; + + sec = ptr->section_list; + do { - boolean match; + boolean skip = false; - if (wildcardp (list_tmp->name)) - match = fnmatch (list_tmp->name, file->filename, 0) == 0; - else - match = strcmp (list_tmp->name, file->filename) == 0; + if (sec != NULL) + { + struct name_list *list_tmp; - if (match) - return; - } - } + /* Don't process sections from files which were + excluded. */ + for (list_tmp = sec->spec.exclude_name_list; + list_tmp; + list_tmp = list_tmp->next) + { + if (wildcardp (list_tmp->name)) + skip = fnmatch (list_tmp->name, file->filename, 0) == 0; + else + skip = strcmp (list_tmp->name, file->filename) == 0; - if (file->just_syms_flag == false) - { - register asection *s; - boolean wildcard = false; + if (skip) + break; + } - if (section != NULL) - wildcard = wildcardp (section); + if (!skip && sec->spec.name != NULL) + { + const char *sname = bfd_get_section_name (file->the_bfd, s); - for (s = file->the_bfd->sections; s != NULL; s = s->next) - { - boolean match; - const char *sname = bfd_get_section_name (file->the_bfd, s); + if (wildcardp (sec->spec.name)) + skip = fnmatch (sec->spec.name, sname, 0) != 0; + else + skip = strcmp (sec->spec.name, sname) != 0; + } + } - if (section == NULL) - match = true; - else if (wildcard) - match = fnmatch (section, sname, 0) == 0; - else - match = strcmp (section, sname) == 0; + if (!skip) + (*callback) (ptr, sec, s, file, data); - /* If this is a wild-card output section statement, exclude - sections that match UNIQUE_SECTION_LIST. */ - if (match && (data == NULL || !unique_section_p (sname))) - (*callback) (ptr, s, file, data); + if (sec != NULL) + sec = sec->next; } + while (sec != NULL); } } /* Handle a wild statement for a single file F. */ static void -walk_wild_file (s, section, f, callback, data) +walk_wild_file (s, f, callback, data) lang_wild_statement_type *s; - const char *section; lang_input_statement_type *f; callback_t callback; PTR data; { if (f->the_bfd == NULL || ! bfd_check_format (f->the_bfd, bfd_archive)) - walk_wild_section (s, section, f, callback, data); + walk_wild_section (s, f, callback, data); else { bfd *member; @@ -320,7 +324,7 @@ walk_wild_file (s, section, f, callback, data) lang_input_statement. */ if (member->usrdata != NULL) { - walk_wild_section (s, section, + walk_wild_section (s, (lang_input_statement_type *) member->usrdata, callback, data); } @@ -331,27 +335,27 @@ walk_wild_file (s, section, f, callback, data) } static void -walk_wild (s, section, file, callback, data) +walk_wild (s, callback, data) lang_wild_statement_type *s; - const char *section; - const char *file; callback_t callback; PTR data; { - if (file == (char *) NULL) + const char *file_spec = s->filename; + + if (file_spec == NULL) { /* Perform the iteration over all files in the list. */ LANG_FOR_EACH_INPUT_STATEMENT (f) { - walk_wild_file (s, section, f, callback, data); + walk_wild_file (s, f, callback, data); } } - else if (wildcardp (file)) + else if (wildcardp (file_spec)) { LANG_FOR_EACH_INPUT_STATEMENT (f) { - if (fnmatch (file, f->filename, FNM_FILE_NAME) == 0) - walk_wild_file (s, section, f, callback, data); + if (fnmatch (file_spec, f->filename, FNM_FILE_NAME) == 0) + walk_wild_file (s, f, callback, data); } } else @@ -359,9 +363,9 @@ walk_wild (s, section, file, callback, data) lang_input_statement_type *f; /* Perform the iteration over a single file. */ - f = lookup_name (file); + f = lookup_name (file_spec); if (f) - walk_wild_file (s, section, f, callback, data); + walk_wild_file (s, f, callback, data); } } @@ -1242,15 +1246,16 @@ wild_doit (ptr, section, output, file) new section should just go at the end of the current list. */ static lang_statement_union_type * -wild_sort (wild, file, section) +wild_sort (wild, sec, file, section) lang_wild_statement_type *wild; + struct wildcard_list *sec; lang_input_statement_type *file; asection *section; { const char *section_name; lang_statement_union_type *l; - if (! wild->filenames_sorted && ! wild->sections_sorted) + if (!wild->filenames_sorted && (sec == NULL || !sec->spec.sorted)) return NULL; section_name = bfd_get_section_name (file->the_bfd, section); @@ -1324,7 +1329,7 @@ wild_sort (wild, file, section) /* Here either the files are not sorted by name, or we are looking at the sections for this file. */ - if (wild->sections_sorted) + if (sec != NULL && sec->spec.sorted) { if (strcmp (section_name, bfd_get_section_name (ls->ifile->the_bfd, @@ -1341,20 +1346,25 @@ wild_sort (wild, file, section) NULL, in which case it is a wild card. */ static void -output_section_callback (ptr, section, file, output) +output_section_callback (ptr, sec, section, file, output) lang_wild_statement_type *ptr; + struct wildcard_list *sec; asection *section; lang_input_statement_type *file; PTR output; { lang_statement_union_type *before; + /* Exclude sections that match UNIQUE_SECTION_LIST. */ + if (unique_section_p (bfd_get_section_name (file->the_bfd, section))) + return; + /* If the wild pattern was marked KEEP, the member sections should be as well. */ if (ptr->keep_sections) section->flags |= SEC_KEEP; - before = wild_sort (ptr, file, section); + before = wild_sort (ptr, sec, file, section); /* Here BEFORE points to the lang_input_section which should follow the one we are about to add. If BEFORE @@ -1557,28 +1567,32 @@ load_symbols (entry, place) return entry->loaded; } -/* Handle a wild statement. SECTION or FILE or both may be NULL, - indicating that it is a wildcard. Separate lang_input_section - statements are created for each part of the expansion; they are - added after the wild statement S. OUTPUT is the output section. */ +/* Handle a wild statement. S->FILENAME or S->SECTION_LIST or both + may be NULL, indicating that it is a wildcard. Separate + lang_input_section statements are created for each part of the + expansion; they are added after the wild statement S. OUTPUT is + the output section. */ static void -wild (s, section, file, target, output) +wild (s, target, output) lang_wild_statement_type *s; - const char *section; - const char *file; const char *target ATTRIBUTE_UNUSED; lang_output_section_statement_type *output; { - walk_wild (s, section, file, output_section_callback, (PTR) output); + struct wildcard_list *sec; + + walk_wild (s, output_section_callback, (PTR) output); - if (section != (char *) NULL - && strcmp (section, "COMMON") == 0 - && default_common_section == NULL) + for (sec = s->section_list; sec != NULL; sec = sec->next) { - /* Remember the section that common is going to in case we later - get something which doesn't know where to put it. */ - default_common_section = output; + if (default_common_section != NULL) + break; + if (sec->spec.name != NULL && strcmp (sec->spec.name, "COMMON") == 0) + { + /* Remember the section that common is going to in case we + later get something which doesn't know where to put it. */ + default_common_section = output; + } } } @@ -2052,13 +2066,8 @@ map_input_to_output_sections (s, target, output_section_statement) { switch (s->header.type) { - case lang_wild_statement_enum: - wild (&s->wild_statement, s->wild_statement.section_name, - s->wild_statement.filename, target, - output_section_statement); - - break; + wild (&s->wild_statement, target, output_section_statement); case lang_constructors_statement_enum: map_input_to_output_sections (constructor_list.head, target, @@ -2441,18 +2450,12 @@ print_wild_statement (w, os) lang_wild_statement_type *w; lang_output_section_statement_type *os; { + struct wildcard_list *sec; + print_space (); if (w->filenames_sorted) minfo ("SORT("); - if (w->exclude_filename_list != NULL) - { - name_list *tmp; - minfo ("EXCLUDE_FILE ( %s", w->exclude_filename_list->name); - for (tmp = w->exclude_filename_list->next; tmp; tmp = tmp->next) - minfo (", %s", tmp->name); - minfo (")"); - } if (w->filename != NULL) minfo ("%s", w->filename); else @@ -2461,14 +2464,25 @@ print_wild_statement (w, os) minfo (")"); minfo ("("); - if (w->sections_sorted) - minfo ("SORT("); - if (w->section_name != NULL) - minfo ("%s", w->section_name); - else - minfo ("*"); - if (w->sections_sorted) - minfo (")"); + for (sec = w->section_list; sec; sec = sec->next) + { + if (sec->spec.sorted) + minfo ("SORT("); + if (sec->spec.exclude_name_list != NULL) + { + name_list *tmp; + minfo ("EXCLUDE_FILE ( %s", sec->spec.exclude_name_list->name); + for (tmp = sec->spec.exclude_name_list->next; tmp; tmp = tmp->next) + minfo (", %s", tmp->name); + minfo (")"); + } + if (sec->spec.name != NULL) + minfo ("%s", sec->spec.name); + else + minfo ("*"); + if (sec->spec.sorted) + minfo (")"); + } minfo (")"); print_nl (); @@ -3978,32 +3992,28 @@ reset_memory_regions () } } -/* Expand a wild statement for a particular FILE, marking its sections KEEP - as needed. SECTION may be NULL, in which case it is a wild card. */ +/* If the wild pattern was marked KEEP, the member sections + should be as well. */ static void -gc_section_callback (ptr, section, file, data) +gc_section_callback (ptr, sec, section, file, data) lang_wild_statement_type *ptr; + struct wildcard_list *sec ATTRIBUTE_UNUSED; asection *section; lang_input_statement_type *file ATTRIBUTE_UNUSED; PTR data ATTRIBUTE_UNUSED; { - /* If the wild pattern was marked KEEP, the member sections - should be as well. */ if (ptr->keep_sections) section->flags |= SEC_KEEP; } -/* Handle a wild statement, marking it against GC. SECTION or FILE or both - may be NULL, indicating that it is a wildcard. */ +/* Handle a wild statement, marking it against GC. */ static void -lang_gc_wild (s, section, file) +lang_gc_wild (s) lang_wild_statement_type *s; - const char *section; - const char *file; { - walk_wild (s, section, file, gc_section_callback, NULL); + walk_wild (s, gc_section_callback, NULL); } /* Iterate over sections marking them against GC. */ @@ -4017,10 +4027,7 @@ lang_gc_sections_1 (s) switch (s->header.type) { case lang_wild_statement_enum: - lang_gc_wild (&s->wild_statement, - s->wild_statement.section_name, - s->wild_statement.filename); - break; + lang_gc_wild (&s->wild_statement); case lang_constructors_statement_enum: lang_gc_sections_1 (constructor_list.head); break; @@ -4211,32 +4218,44 @@ lang_process () /* EXPORTED TO YACC */ void -lang_add_wild (section_name, sections_sorted, filename, filenames_sorted, - keep_sections, exclude_filename_list) - const char *const section_name; - boolean sections_sorted; - const char *const filename; - boolean filenames_sorted; +lang_add_wild (filespec, section_list, keep_sections) + struct wildcard_spec *filespec; + struct wildcard_list *section_list; boolean keep_sections; - struct name_list *exclude_filename_list; { - lang_wild_statement_type *new = new_stat (lang_wild_statement, - stat_ptr); + struct wildcard_list *curr, *next; + lang_wild_statement_type *new; + + /* Reverse the list as the parser puts it back to front. */ + for (curr = section_list, section_list = NULL; + curr != NULL; + section_list = curr, curr = next) + { + if (curr->spec.name != NULL && strcmp (curr->spec.name, "COMMON") == 0) + placed_commons = true; - if (section_name != (char *) NULL && strcmp (section_name, "COMMON") == 0) + next = curr->next; + curr->next = section_list; + } + + if (filespec != NULL && filespec->name != NULL) { - placed_commons = true; + if (strcmp (filespec->name, "*") == 0) + filespec->name = NULL; + else if (! wildcardp (filespec->name)) + lang_has_input_file = true; } - if (filename != NULL && ! wildcardp (filename)) + + new = new_stat (lang_wild_statement, stat_ptr); + new->filename = NULL; + new->filenames_sorted = false; + if (filespec != NULL) { - lang_has_input_file = true; + new->filename = filespec->name; + new->filenames_sorted = filespec->sorted; } - new->section_name = section_name; - new->sections_sorted = sections_sorted; - new->filename = filename; - new->filenames_sorted = filenames_sorted; + new->section_list = section_list; new->keep_sections = keep_sections; - new->exclude_filename_list = exclude_filename_list; lang_list_init (&new->children); } diff --git a/ld/ldlang.h b/ld/ldlang.h index 348529ab5..ad1cf62f4 100644 --- a/ld/ldlang.h +++ b/ld/ldlang.h @@ -257,12 +257,10 @@ typedef struct { typedef struct lang_wild_statement_struct { lang_statement_header_type header; - const char *section_name; - boolean sections_sorted; const char *filename; boolean filenames_sorted; + struct wildcard_list *section_list; boolean keep_sections; - struct name_list *exclude_filename_list; lang_statement_list_type children; } lang_wild_statement_type; @@ -385,7 +383,7 @@ extern void lang_section_start PARAMS ((const char *, union etree_union *)); extern void lang_add_entry PARAMS ((const char *, boolean)); extern void lang_add_target PARAMS ((const char *)); extern void lang_add_wild - PARAMS ((const char *, boolean, const char *, boolean, boolean, name_list *)); + PARAMS ((struct wildcard_spec *, struct wildcard_list *, boolean)); extern void lang_add_map PARAMS ((const char *)); extern void lang_add_fill PARAMS ((int)); extern lang_assignment_statement_type * lang_add_assignment PARAMS ((union etree_union *)); diff --git a/ld/mri.c b/ld/mri.c index f4094cb4c..6ec0ab8f8 100644 --- a/ld/mri.c +++ b/ld/mri.c @@ -220,6 +220,7 @@ mri_draw_tree () struct section_name_struct *aptr; etree_type *align = 0; etree_type *subalign = 0; + struct wildcard_list *tmp; /* See if an alignment has been specified. */ for (aptr = alignment; aptr; aptr = aptr->next) @@ -238,12 +239,24 @@ mri_draw_tree () 1, align, subalign, (etree_type *) NULL); base = 0; - lang_add_wild (p->name, false, (char *) NULL, false, false, NULL); + tmp = (struct wildcard_list *) xmalloc (sizeof *tmp); + tmp->next = NULL; + tmp->spec.name = p->name; + tmp->spec.exclude_name_list = NULL; + tmp->spec.sorted = false; + lang_add_wild (NULL, tmp, false); /* If there is an alias for this section, add it too. */ for (aptr = alias; aptr; aptr = aptr->next) if (strcmp (aptr->alias, p->name) == 0) - lang_add_wild (aptr->name, false, (char *) NULL, false, false, NULL); + { + tmp = (struct wildcard_list *) xmalloc (sizeof *tmp); + tmp->next = NULL; + tmp->spec.name = aptr->name; + tmp->spec.exclude_name_list = NULL; + tmp->spec.sorted = false; + lang_add_wild (NULL, tmp, false); + } lang_leave_output_section_statement (0, "*default*", (struct lang_output_section_phdr_list *) NULL, -- 2.11.4.GIT