X-Git-Url: http://drtracing.org/?a=blobdiff_plain;ds=sidebyside;f=ld%2Fldlang.c;h=0a224d4473491956fe285e878544db9c41fc32f7;hb=9ef7906f20e81faa4498761002e6376f4d35c865;hp=aee87207773d5cad72601f71d6b98a5d083b4ee6;hpb=4212b42d795628dcc36bcffc7cf16175f7698305;p=deliverable%2Fbinutils-gdb.git diff --git a/ld/ldlang.c b/ld/ldlang.c index aee8720777..0a224d4473 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -223,23 +223,16 @@ unique_section_p (const asection *sec, /* Generic traversal routines for finding matching sections. */ -/* Try processing a section against a wildcard. This just calls - the callback unless the filename exclusion list is present - and excludes the file. It's hardly ever present so this - function is very fast. */ +/* Return true if FILE matches a pattern in EXCLUDE_LIST, otherwise return + false. */ -static void -walk_wild_consider_section (lang_wild_statement_type *ptr, - lang_input_statement_type *file, - asection *s, - struct wildcard_list *sec, - callback_t callback, - void *data) +static bfd_boolean +walk_wild_file_in_exclude_list (struct name_list *exclude_list, + lang_input_statement_type *file) { struct name_list *list_tmp; - /* Don't process sections from files which were excluded. */ - for (list_tmp = sec->spec.exclude_name_list; + for (list_tmp = exclude_list; list_tmp; list_tmp = list_tmp->next) { @@ -248,11 +241,11 @@ walk_wild_consider_section (lang_wild_statement_type *ptr, if (p != NULL) { if (input_statement_is_archive_path (list_tmp->name, p, file)) - return; + return TRUE; } else if (name_match (list_tmp->name, file->filename) == 0) - return; + return TRUE; /* FIXME: Perhaps remove the following at some stage? Matching unadorned archives like this was never documented and has @@ -261,9 +254,29 @@ walk_wild_consider_section (lang_wild_statement_type *ptr, && file->the_bfd->my_archive != NULL && name_match (list_tmp->name, file->the_bfd->my_archive->filename) == 0) - return; + return TRUE; } + return FALSE; +} + +/* Try processing a section against a wildcard. This just calls + the callback unless the filename exclusion list is present + and excludes the file. It's hardly ever present so this + function is very fast. */ + +static void +walk_wild_consider_section (lang_wild_statement_type *ptr, + lang_input_statement_type *file, + asection *s, + struct wildcard_list *sec, + callback_t callback, + void *data) +{ + /* Don't process sections from files which were excluded. */ + if (walk_wild_file_in_exclude_list (sec->spec.exclude_name_list, file)) + return; + (*callback) (ptr, sec, s, ptr->section_flag_list, file, data); } @@ -860,6 +873,9 @@ walk_wild_file (lang_wild_statement_type *s, callback_t callback, void *data) { + if (walk_wild_file_in_exclude_list (s->exclude_name_list, f)) + return; + if (f->the_bfd == NULL || !bfd_check_format (f->the_bfd, bfd_archive)) walk_wild_section (s, f, callback, data); @@ -2294,6 +2310,12 @@ section_already_linked (bfd *abfd, asection *sec, void *data) return; } + /* Deal with SHF_EXCLUDE ELF sections. */ + if (!bfd_link_relocatable (&link_info) + && (abfd->flags & BFD_PLUGIN) == 0 + && (sec->flags & (SEC_GROUP | SEC_KEEP | SEC_EXCLUDE)) == SEC_EXCLUDE) + sec->output_section = bfd_abs_section_ptr; + if (!(abfd->flags & DYNAMIC)) bfd_section_already_linked (abfd, sec, &link_info); } @@ -3682,7 +3704,7 @@ map_input_to_output_sections processed the segment marker. Originally, the linker treated segment directives (like -Ttext on the command-line) as section directives. We honor the - section directive semantics for backwards compatibilty; + section directive semantics for backwards compatibility; linker scripts that do not specifically check for SEGMENT_START automatically get the old semantics. */ if (!s->address_statement.segment @@ -4413,6 +4435,15 @@ print_wild_statement (lang_wild_statement_type *w, print_space (); + if (w->exclude_name_list) + { + name_list *tmp; + minfo ("EXCLUDE_FILE(%s", w->exclude_name_list->name); + for (tmp = w->exclude_name_list->next; tmp; tmp = tmp->next) + minfo (" %s", tmp->name); + minfo (") "); + } + if (w->filenames_sorted) minfo ("SORT("); if (w->filename != NULL) @@ -4643,7 +4674,8 @@ size_input_section if (i->sec_info_type == SEC_INFO_TYPE_JUST_SYMS) i->output_offset = i->vma - o->vma; - else if ((i->flags & SEC_EXCLUDE) != 0) + else if (((i->flags & SEC_EXCLUDE) != 0) + || output_section_statement->ignored) i->output_offset = dot - o->vma; else { @@ -5612,6 +5644,7 @@ lang_do_assignments_1 (lang_statement_union_type *s, case lang_output_section_statement_enum: { lang_output_section_statement_type *os; + bfd_vma newdot; os = &(s->output_section_statement); os->after_end = *found_end; @@ -5623,18 +5656,24 @@ lang_do_assignments_1 (lang_statement_union_type *s, prefer_next_section = FALSE; } dot = os->bfd_section->vma; - - lang_do_assignments_1 (os->children.head, - os, os->fill, dot, found_end); - - /* .tbss sections effectively have zero size. */ - if (!IS_TBSS (os->bfd_section) - || bfd_link_relocatable (&link_info)) - dot += TO_ADDR (os->bfd_section->size); - - if (os->update_dot_tree != NULL) - exp_fold_tree (os->update_dot_tree, bfd_abs_section_ptr, - &dot); + } + newdot = lang_do_assignments_1 (os->children.head, + os, os->fill, dot, found_end); + if (!os->ignored) + { + if (os->bfd_section != NULL) + { + /* .tbss sections effectively have zero size. */ + if (!IS_TBSS (os->bfd_section) + || bfd_link_relocatable (&link_info)) + dot += TO_ADDR (os->bfd_section->size); + + if (os->update_dot_tree != NULL) + exp_fold_tree (os->update_dot_tree, + bfd_abs_section_ptr, &dot); + } + else + dot = newdot; } } break; @@ -5658,7 +5697,7 @@ lang_do_assignments_1 (lang_statement_union_type *s, if (expld.result.section != NULL) s->data_statement.value += expld.result.section->vma; } - else + else if (expld.phase == lang_final_phase_enum) einfo (_("%F%P: invalid data statement\n")); { unsigned int size; @@ -5691,7 +5730,7 @@ lang_do_assignments_1 (lang_statement_union_type *s, bfd_abs_section_ptr, &dot); if (expld.result.valid_p) s->reloc_statement.addend_value = expld.result.value; - else + else if (expld.phase == lang_final_phase_enum) einfo (_("%F%P: invalid reloc statement\n")); dot += TO_ADDR (bfd_get_reloc_size (s->reloc_statement.howto)); break; @@ -5727,7 +5766,8 @@ lang_do_assignments_1 (lang_statement_union_type *s, *found_end = TRUE; } exp_fold_tree (s->assignment_statement.exp, - current_os->bfd_section, + (current_os->bfd_section != NULL + ? current_os->bfd_section : bfd_und_section_ptr), &dot); break; @@ -5978,7 +6018,8 @@ lang_end (void) BFD. */ static void -ignore_bfd_errors (const char *s ATTRIBUTE_UNUSED, ...) +ignore_bfd_errors (const char *fmt ATTRIBUTE_UNUSED, + va_list ap ATTRIBUTE_UNUSED) { /* Don't do anything. */ } @@ -6048,7 +6089,7 @@ lang_check (void) information which is needed in the output file. */ if (!command_line.warn_mismatch) pfn = bfd_set_error_handler (ignore_bfd_errors); - if (!bfd_merge_private_bfd_data (input_bfd, link_info.output_bfd)) + if (!bfd_merge_private_bfd_data (input_bfd, &link_info)) { if (command_line.warn_mismatch) einfo (_("%P%X: failed to merge target specific data" @@ -6840,7 +6881,7 @@ lang_process (void) are any more to be added to the link before we call the emulation's after_open hook. We create a private list of input statements for this purpose, which we will eventually - insert into the global statment list after the first claimed + insert into the global statement list after the first claimed file. */ added = *stat_ptr; /* We need to manipulate all three chains in synchrony. */ @@ -7058,11 +7099,13 @@ lang_add_wild (struct wildcard_spec *filespec, new_stmt->filename = NULL; new_stmt->filenames_sorted = FALSE; new_stmt->section_flag_list = NULL; + new_stmt->exclude_name_list = NULL; if (filespec != NULL) { new_stmt->filename = filespec->name; new_stmt->filenames_sorted = filespec->sorted == by_name; new_stmt->section_flag_list = filespec->section_flag_list; + new_stmt->exclude_name_list = filespec->exclude_name_list; } new_stmt->section_list = section_list; new_stmt->keep_sections = keep_sections;