/* Linker command language support.
- Copyright (C) 1991-2016 Free Software Foundation, Inc.
+ Copyright (C) 1991-2017 Free Software Foundation, Inc.
This file is part of the GNU Binutils.
/* 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)
{
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
&& 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);
}
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);
lang_print_asneeded (void)
{
struct asneeded_minfo *m;
- char buf[100];
if (asneeded_list_head == NULL)
return;
- sprintf (buf, _("\nAs-needed library included "
- "to satisfy reference by file (symbol)\n\n"));
- minfo ("%s", buf);
+ minfo (_("\nAs-needed library included to satisfy reference by file (symbol)\n\n"));
for (m = asneeded_list_head; m != NULL; m = m->next)
{
#endif
break;
case lang_assignment_statement_enum:
- if (s->assignment_statement.exp->assign.defsym)
+ if (s->assignment_statement.exp->type.node_class != etree_assert
+ && s->assignment_statement.exp->assign.defsym)
/* This is from a --defsym on the command line. */
exp_fold_tree_no_dot (s->assignment_statement.exp);
break;
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
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)
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
{
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;
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;
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;
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;
*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;
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. */
}
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"
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. */
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;