aboutsummaryrefslogtreecommitdiff
path: root/ld/ldlang.c
diff options
context:
space:
mode:
Diffstat (limited to 'ld/ldlang.c')
-rw-r--r--ld/ldlang.c111
1 files changed, 61 insertions, 50 deletions
diff --git a/ld/ldlang.c b/ld/ldlang.c
index 08bfa60..2c07fa4 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -86,13 +86,6 @@ static void print_statement_list (lang_statement_union_type *,
static void print_statements (void);
static void print_input_section (asection *, bfd_boolean);
static bfd_boolean lang_one_common (struct bfd_link_hash_entry *, void *);
-#ifdef ENABLE_PLUGINS
-static void lang_list_insert_after (lang_statement_list_type *destlist,
- lang_statement_list_type *srclist,
- lang_statement_union_type **field);
-static void lang_list_remove_tail (lang_statement_list_type *destlist,
- lang_statement_list_type *origlist);
-#endif /* ENABLE_PLUGINS */
static void lang_record_phdrs (void);
static void lang_do_version_exports_section (void);
static void lang_finalize_version_expr_head
@@ -3180,6 +3173,9 @@ enum open_bfd_mode
OPEN_BFD_FORCE = 1,
OPEN_BFD_RESCAN = 2
};
+#ifdef ENABLE_PLUGINS
+static lang_input_statement_type *plugin_insert = NULL;
+#endif
static void
open_input_bfds (lang_statement_union_type *s, enum open_bfd_mode mode)
@@ -3236,6 +3232,10 @@ open_input_bfds (lang_statement_union_type *s, enum open_bfd_mode mode)
force it to be researched unless the whole archive
has been loaded already. Do the same for a rescan. */
if (mode != OPEN_BFD_NORMAL
+#ifdef ENABLE_PLUGINS
+ && ((mode & OPEN_BFD_RESCAN) == 0
+ || plugin_insert == NULL)
+#endif
&& !s->input_statement.whole_archive
&& s->input_statement.loaded
&& bfd_check_format (s->input_statement.the_bfd,
@@ -3271,6 +3271,12 @@ open_input_bfds (lang_statement_union_type *s, enum open_bfd_mode mode)
}
}
}
+#ifdef ENABLE_PLUGINS
+ /* If we have found the point at which a plugin added new
+ files, clear plugin_insert to enable archive rescan. */
+ if (&s->input_statement == plugin_insert)
+ plugin_insert = NULL;
+#endif
break;
case lang_assignment_statement_enum:
if (s->assignment_statement.exp->assign.hidden)
@@ -6279,6 +6285,10 @@ lang_gc_sections (void)
LANG_FOR_EACH_INPUT_STATEMENT (f)
{
asection *sec;
+#ifdef ENABLE_PLUGINS
+ if (f->claimed)
+ continue;
+#endif
for (sec = f->the_bfd->sections; sec != NULL; sec = sec->next)
if ((sec->flags & SEC_DEBUGGING) == 0)
sec->flags &= ~SEC_EXCLUDE;
@@ -6452,6 +6462,38 @@ find_replacements_insert_point (void)
insert point. */
return lastobject;
}
+
+/* Insert SRCLIST into DESTLIST after given element by chaining
+ on FIELD as the next-pointer. (Counterintuitively does not need
+ a pointer to the actual after-node itself, just its chain field.) */
+
+static void
+lang_list_insert_after (lang_statement_list_type *destlist,
+ lang_statement_list_type *srclist,
+ lang_statement_union_type **field)
+{
+ *(srclist->tail) = *field;
+ *field = srclist->head;
+ if (destlist->tail == field)
+ destlist->tail = srclist->tail;
+}
+
+/* Detach new nodes added to DESTLIST since the time ORIGLIST
+ was taken as a copy of it and leave them in ORIGLIST. */
+
+static void
+lang_list_remove_tail (lang_statement_list_type *destlist,
+ lang_statement_list_type *origlist)
+{
+ union lang_statement_union **savetail;
+ /* Check that ORIGLIST really is an earlier state of DESTLIST. */
+ ASSERT (origlist->head == destlist->head);
+ savetail = origlist->tail;
+ origlist->head = *(savetail);
+ origlist->tail = destlist->tail;
+ destlist->tail = savetail;
+ *savetail = NULL;
+}
#endif /* ENABLE_PLUGINS */
void
@@ -6484,6 +6526,7 @@ lang_process (void)
{
lang_statement_list_type added;
lang_statement_list_type files, inputfiles;
+
/* 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
@@ -6509,27 +6552,29 @@ lang_process (void)
{
/* If so, we will insert them into the statement list immediately
after the first input file that was claimed by the plugin. */
- lang_input_statement_type *claim1 = find_replacements_insert_point ();
+ plugin_insert = find_replacements_insert_point ();
/* If a plugin adds input files without having claimed any, we
don't really have a good idea where to place them. Just putting
them at the start or end of the list is liable to leave them
outside the crtbegin...crtend range. */
- ASSERT (claim1 != NULL);
- /* Splice the new statement list into the old one after claim1. */
- lang_list_insert_after (stat_ptr, &added, &claim1->header.next);
+ ASSERT (plugin_insert != NULL);
+ /* Splice the new statement list into the old one. */
+ lang_list_insert_after (stat_ptr, &added,
+ &plugin_insert->header.next);
/* Likewise for the file chains. */
lang_list_insert_after (&input_file_chain, &inputfiles,
- &claim1->next_real_file);
+ &plugin_insert->next_real_file);
/* We must be careful when relinking file_chain; we may need to
insert the new files at the head of the list if the insert
point chosen is the dummy first input file. */
- if (claim1->filename)
- lang_list_insert_after (&file_chain, &files, &claim1->next);
+ if (plugin_insert->filename)
+ lang_list_insert_after (&file_chain, &files, &plugin_insert->next);
else
lang_list_insert_after (&file_chain, &files, &file_chain.head);
+
+ /* Rescan archives in case new undefined symbols have appeared. */
+ open_input_bfds (statement_list.head, OPEN_BFD_RESCAN);
}
- /* Rescan any archives in case new undefined symbols have appeared. */
- open_input_bfds (statement_list.head, OPEN_BFD_RESCAN);
}
#endif /* ENABLE_PLUGINS */
@@ -6952,40 +6997,6 @@ lang_statement_append (lang_statement_list_type *list,
list->tail = field;
}
-#ifdef ENABLE_PLUGINS
-/* Insert SRCLIST into DESTLIST after given element by chaining
- on FIELD as the next-pointer. (Counterintuitively does not need
- a pointer to the actual after-node itself, just its chain field.) */
-
-static void
-lang_list_insert_after (lang_statement_list_type *destlist,
- lang_statement_list_type *srclist,
- lang_statement_union_type **field)
-{
- *(srclist->tail) = *field;
- *field = srclist->head;
- if (destlist->tail == field)
- destlist->tail = srclist->tail;
-}
-
-/* Detach new nodes added to DESTLIST since the time ORIGLIST
- was taken as a copy of it and leave them in ORIGLIST. */
-
-static void
-lang_list_remove_tail (lang_statement_list_type *destlist,
- lang_statement_list_type *origlist)
-{
- union lang_statement_union **savetail;
- /* Check that ORIGLIST really is an earlier state of DESTLIST. */
- ASSERT (origlist->head == destlist->head);
- savetail = origlist->tail;
- origlist->head = *(savetail);
- origlist->tail = destlist->tail;
- destlist->tail = savetail;
- *savetail = NULL;
-}
-#endif /* ENABLE_PLUGINS */
-
/* Set the output format type. -oformat overrides scripts. */
void