/* Forward declarations. */
static void exp_init_os (etree_type *);
static lang_input_statement_type *lookup_name (const char *);
+static bool wont_add_section_p (asection *,
+ lang_output_section_statement_type *);
static void insert_undefined (const char *);
static bool sort_def_symbol (struct bfd_link_hash_entry *, void *);
static lang_statement_union_type *new_statement (enum statement_enum type,
}
else
{
- lang_input_statement_type *f;
- /* Perform the iteration over a single file. */
- f = lookup_name (file_spec);
- if (f != file)
+ /* XXX Matching against non-wildcard filename in wild statements
+ was done by going through lookup_name, which uses
+ ->local_sym_name to compare against, not ->filename. We retain
+ this behaviour even though the above code paths use filename.
+ It would be more logical to use it here as well, in which
+ case the above wildcard() arm could be folded into this by using
+ name_match. This would also solve the worry of what to do
+ about unset local_sym_name (in which case lookup_name simply adds
+ the input file again). */
+ const char *filename = file->local_sym_name;
+ lang_input_statement_type *arch_is;
+ if (filename && filename_cmp (filename, file_spec) == 0)
+ ;
+ /* FIXME: see also walk_wild_file_in_exclude_list for why we
+ also check parents BFD (local_sym_)name to match input statements
+ with unadorned archive names. */
+ else if (file->the_bfd
+ && file->the_bfd->my_archive
+ && (arch_is = bfd_usrdata (file->the_bfd->my_archive))
+ && arch_is->local_sym_name
+ && filename_cmp (arch_is->local_sym_name, file_spec) == 0)
+ ;
+ else
return;
}
if (unique_section_p (section, os))
return;
+ /* Don't add sections to the tree when we already know that
+ lang_add_section won't do anything with it. */
+ if (wont_add_section_p (section, os))
+ return;
+
node = (lang_section_bst_type *) xmalloc (sizeof (lang_section_bst_type));
node->left = 0;
node->right = 0;
lang_has_input_file = true;
+ /* PR 30632: It is OK for name to be NULL. For example
+ see the initialization of first_file in lang_init(). */
+ if (name != NULL)
+ {
+ name = ldfile_possibly_remap_input (name);
+ /* But if a name is remapped to NULL, it should be ignored. */
+ if (name == NULL)
+ return NULL;
+ }
+
p = new_stat (lang_input_statement, stat_ptr);
memset (&p->the_bfd, 0,
sizeof (*p) - offsetof (lang_input_statement_type, the_bfd));
lang_finish (void)
{
output_section_statement_table_free ();
+ ldfile_remap_input_free ();
}
/*----------------------------------------------------------------------
lang_memory_region_type *m;
bool dis_header_printed = false;
+ ldfile_print_input_remaps ();
+
LANG_FOR_EACH_INPUT_STATEMENT (file)
{
asection *s;
{
if (! dis_header_printed)
{
- fprintf (config.map_file, _("\nDiscarded input sections\n\n"));
+ minfo (_("\nDiscarded input sections\n\n"));
dis_header_printed = true;
}
print_input_section (s, true);
}
}
+ if (config.print_map_discarded && ! dis_header_printed)
+ minfo (_("\nThere are no discarded input sections\n"));
minfo (_("\nMemory Configuration\n\n"));
fprintf (config.map_file, "%-16s %-18s %-18s %s\n",
print_nl ();
}
- fprintf (config.map_file, _("\nLinker script and memory map\n\n"));
+ minfo (_("\nLinker script and memory map\n\n"));
if (!link_info.reduce_memory_overheads)
{
&& (flags & SEC_DEBUGGING) != 0)
discard = true;
+ /* Discard non-alloc sections if we are stripping section headers. */
+ else if (config.no_section_header && (flags & SEC_ALLOC) == 0)
+ discard = true;
+
return discard;
}
-/* The wild routines.
-
- These expand statements like *(.text) and foo.o to a list of
- explicit actions, like foo.o(.text), bar.o(.text) and
- foo.o(.text, .data). */
+/* Return TRUE if SECTION is never going to be added to output statement
+ OUTPUT. lang_add_section() definitely won't do anything with SECTION
+ if this returns TRUE. It may do something (or not) if this returns FALSE.
-/* Add SECTION to the output section OUTPUT. Do this by creating a
- lang_input_section statement which is placed at PTR. */
+ Can be used as early-out to filter matches. This may set
+ output_section of SECTION, if it was unset, to the abs section in case
+ we discover SECTION to be always discarded. This may also give
+ warning messages. */
-void
-lang_add_section (lang_statement_list_type *ptr,
- asection *section,
- struct wildcard_list *pattern,
- struct flag_info *sflag_info,
- lang_output_section_statement_type *output)
+static bool
+wont_add_section_p (asection *section,
+ lang_output_section_statement_type *output)
{
- flagword flags = section->flags;
-
bool discard;
- lang_input_section_type *new_section;
- bfd *abfd = link_info.output_bfd;
/* Is this section one we know should be discarded? */
discard = lang_discard_section_p (section);
{
if (section->output_section == NULL)
{
- /* This prevents future calls from assigning this section. */
+ /* This prevents future calls from assigning this section or
+ warning about it again. */
section->output_section = bfd_abs_section_ptr;
}
+ else if (bfd_is_abs_section (section->output_section))
+ ;
else if (link_info.non_contiguous_regions_warnings)
einfo (_("%P:%pS: warning: --enable-non-contiguous-regions makes "
"section `%pA' from `%pB' match /DISCARD/ clause.\n"),
NULL, section, section->owner);
- return;
- }
-
- if (sflag_info)
- {
- bool keep;
-
- keep = bfd_lookup_section_flags (&link_info, sflag_info, section);
- if (!keep)
- return;
+ return true;
}
if (section->output_section != NULL)
{
if (!link_info.non_contiguous_regions)
- return;
+ return true;
/* SECTION has already been handled in a special way
(eg. LINK_ONCE): skip it. */
if (bfd_is_abs_section (section->output_section))
- return;
+ return true;
/* Already assigned to the same output section, do not process
it again, to avoid creating loops between duplicate sections
later. */
if (section->output_section == output->bfd_section)
- return;
+ return true;
if (link_info.non_contiguous_regions_warnings && output->bfd_section)
einfo (_("%P:%pS: warning: --enable-non-contiguous-regions may "
size_input_section as appropriate. */
}
+ return false;
+}
+
+/* The wild routines.
+
+ These expand statements like *(.text) and foo.o to a list of
+ explicit actions, like foo.o(.text), bar.o(.text) and
+ foo.o(.text, .data). */
+
+/* Add SECTION to the output section OUTPUT. Do this by creating a
+ lang_input_section statement which is placed at PTR. */
+
+void
+lang_add_section (lang_statement_list_type *ptr,
+ asection *section,
+ struct wildcard_list *pattern,
+ struct flag_info *sflag_info,
+ lang_output_section_statement_type *output)
+{
+ flagword flags = section->flags;
+
+ lang_input_section_type *new_section;
+ bfd *abfd = link_info.output_bfd;
+
+ if (wont_add_section_p (section, output))
+ return;
+
+ if (sflag_info)
+ {
+ bool keep;
+
+ keep = bfd_lookup_section_flags (&link_info, sflag_info, section);
+ if (!keep)
+ return;
+ }
+
/* We don't copy the SEC_NEVER_LOAD flag from an input section
to an output section, because we want to be able to include a
SEC_NEVER_LOAD section in the middle of an otherwise loaded
link_info.output_bfd->flags |= BFD_TRADITIONAL_FORMAT;
else
link_info.output_bfd->flags &= ~BFD_TRADITIONAL_FORMAT;
+ if (config.no_section_header)
+ link_info.output_bfd->flags |= BFD_NO_SECTION_HEADER;
+ else
+ link_info.output_bfd->flags &= ~BFD_NO_SECTION_HEADER;
break;
case lang_target_statement_enum:
obstack_free (&map_obstack, entries);
}
+/* Returns TRUE if SYM is a symbol suitable for printing
+ in a linker map as a local symbol. */
+
+static bool
+ld_is_local_symbol (asymbol * sym)
+{
+ const char * name = bfd_asymbol_name (sym);
+
+ if (name == NULL || *name == 0)
+ return false;
+
+ if (strcmp (name, "(null)") == 0)
+ return false;
+
+ /* Skip .Lxxx and such like. */
+ if (bfd_is_local_label (link_info.output_bfd, sym))
+ return false;
+
+ /* FIXME: This is intended to skip ARM mapping symbols,
+ which for some reason are not excluded by bfd_is_local_label,
+ but maybe it is wrong for other architectures.
+ It would be better to fix bfd_is_local_label. */
+ if (*name == '$')
+ return false;
+
+ /* Some local symbols, eg _GLOBAL_OFFSET_TABLE_, are present
+ in the hash table, so do not print duplicates here. */
+ struct bfd_link_hash_entry * h;
+ h = bfd_link_hash_lookup (link_info.hash, name, false /* create */,
+ false /* copy */, true /* follow */);
+ if (h == NULL)
+ return true;
+
+ /* Symbols from the plugin owned BFD will not get their own
+ iteration of this function, but can be on the link_info
+ list. So include them here. */
+ if (h->u.def.section->owner != NULL
+ && ((bfd_get_file_flags (h->u.def.section->owner) & (BFD_LINKER_CREATED | BFD_PLUGIN))
+ == (BFD_LINKER_CREATED | BFD_PLUGIN)))
+ return true;
+
+ return false;
+}
+
/* Print information about an input section to the map file. */
static void
later overlay is shorter than an earier one. */
if (addr + TO_ADDR (size) > print_dot)
print_dot = addr + TO_ADDR (size);
+
+ if (config.print_map_locals)
+ {
+ long storage_needed;
+
+ /* FIXME: It would be better to cache this table, rather
+ than recreating it for each output section. */
+ /* FIXME: This call is not working for non-ELF based targets.
+ Find out why. */
+ storage_needed = bfd_get_symtab_upper_bound (link_info.output_bfd);
+ if (storage_needed > 0)
+ {
+ asymbol ** symbol_table;
+ long number_of_symbols;
+ long j;
+
+ symbol_table = xmalloc (storage_needed);
+ number_of_symbols = bfd_canonicalize_symtab (link_info.output_bfd, symbol_table);
+
+ for (j = 0; j < number_of_symbols; j++)
+ {
+ asymbol * sym = symbol_table[j];
+ bfd_vma sym_addr = sym->value + i->output_section->vma;
+
+ if (sym->section == i->output_section
+ && (sym->flags & BSF_LOCAL) != 0
+ && sym_addr >= addr
+ && sym_addr < print_dot
+ && ld_is_local_symbol (sym))
+ {
+ print_spaces (SECTION_NAME_MAP_LENGTH);
+ minfo ("0x%V (local) %s\n", sym_addr, bfd_asymbol_name (sym));
+ }
+ }
+
+ free (symbol_table);
+ }
+ }
}
}
statements we can give values to symbolic origin/length now. */
lang_do_memory_regions (true);
+ ldemul_before_plugin_all_symbols_read ();
+
#if BFD_SUPPORTS_PLUGINS
if (link_info.lto_plugin_active)
{
lang_statement_list_type added;
lang_statement_list_type files, inputfiles;
- ldemul_before_plugin_all_symbols_read ();
-
/* Now all files are read, let the plugin(s) decide if there
are any more to be added to the link before we call the
emulation's after_open hook. We create a private list of
}
#endif /* BFD_SUPPORTS_PLUGINS */
- /* Make sure that nobody has tried to add a symbol to this list
- before now. */
- ASSERT (link_info.gc_sym_list == NULL);
+ struct bfd_sym_chain **sym = &link_info.gc_sym_list;
+ while (*sym)
+ sym = &(*sym)->next;
- link_info.gc_sym_list = &entry_symbol;
+ *sym = &entry_symbol;
if (entry_symbol.name == NULL)
{
- link_info.gc_sym_list = ldlang_undef_chain_list_head;
+ *sym = ldlang_undef_chain_list_head;
- /* entry_symbol is normally initialied by a ENTRY definition in the
+ /* entry_symbol is normally initialised by an ENTRY definition in the
linker script or the -e command line option. But if neither of
these have been used, the target specific backend may still have
provided an entry symbol via a call to lang_default_entry().