summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ld/ldlang.c92
1 files changed, 61 insertions, 31 deletions
diff --git a/ld/ldlang.c b/ld/ldlang.c
index 9ad405aa06c..aa01c81e661 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -80,6 +80,8 @@ static unsigned int opb_shift = 0;
/* 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,
@@ -687,6 +689,11 @@ output_section_callback_sort (lang_wild_statement_type *ptr,
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;
@@ -2514,27 +2521,20 @@ lang_discard_section_p (asection *section)
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);
@@ -2548,41 +2548,35 @@ lang_add_section (lang_statement_list_type *ptr,
{
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 "
@@ -2597,6 +2591,42 @@ lang_add_section (lang_statement_list_type *ptr,
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