aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ld/ChangeLog9
-rw-r--r--ld/ldlang.c59
2 files changed, 62 insertions, 6 deletions
diff --git a/ld/ChangeLog b/ld/ChangeLog
index 8f9d1f0..563e482 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,6 +1,15 @@
2019-08-06 Alan Modra <amodra@gmail.com>
PR 24873
+ * ldlang.c (find_replacements_insert_point): Return "before" flag.
+ (find_next_input_statement): New function.
+ (lang_process): When placing recompiled LTO objects before a
+ claimed archive, place them immediately before in the statement
+ list.
+
+2019-08-06 Alan Modra <amodra@gmail.com>
+
+ PR 24873
* ldlang.c (plugin_undefs): New static var.
(open_input_bfds <lang_group_statement_enum>): Loop on
plugin_undefs and hitting plugin_insert point.
diff --git a/ld/ldlang.c b/ld/ldlang.c
index b88c841..8119cfc 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -7226,7 +7226,7 @@ lang_relax_sections (bfd_boolean need_layout)
inserted at the head of the file_chain. */
static lang_input_statement_type *
-find_replacements_insert_point (void)
+find_replacements_insert_point (bfd_boolean *before)
{
lang_input_statement_type *claim1, *lastobject;
lastobject = &input_file_chain.head->input_statement;
@@ -7235,7 +7235,10 @@ find_replacements_insert_point (void)
claim1 = &claim1->next->input_statement)
{
if (claim1->flags.claimed)
- return claim1->flags.claim_archive ? lastobject : claim1;
+ {
+ *before = claim1->flags.claim_archive;
+ return claim1->flags.claim_archive ? lastobject : claim1;
+ }
/* Update lastobject if this is a real object file. */
if (claim1->the_bfd != NULL && claim1->the_bfd->my_archive == NULL)
lastobject = claim1;
@@ -7243,6 +7246,7 @@ find_replacements_insert_point (void)
/* No files were claimed by the plugin. Choose the last object
file found on the list (maybe the first, dummy entry) as the
insert point. */
+ *before = FALSE;
return lastobject;
}
@@ -7323,6 +7327,35 @@ lang_list_remove_tail (lang_statement_list_type *destlist,
destlist->tail = savetail;
*savetail = NULL;
}
+
+static lang_statement_union_type **
+find_next_input_statement (lang_statement_union_type **s)
+{
+ for ( ; *s; s = &(*s)->header.next)
+ {
+ lang_statement_union_type **t;
+ switch ((*s)->header.type)
+ {
+ case lang_input_statement_enum:
+ return s;
+ case lang_wild_statement_enum:
+ t = &(*s)->wild_statement.children.head;
+ break;
+ case lang_group_statement_enum:
+ t = &(*s)->group_statement.children.head;
+ break;
+ case lang_output_section_statement_enum:
+ t = &(*s)->output_section_statement.children.head;
+ break;
+ default:
+ continue;
+ }
+ t = find_next_input_statement (t);
+ if (*t)
+ return t;
+ }
+ return s;
+}
#endif /* ENABLE_PLUGINS */
/* Add NAME to the list of garbage collection entry points. */
@@ -7447,16 +7480,30 @@ lang_process (void)
if (added.head != NULL)
{
/* If so, we will insert them into the statement list immediately
- after the first input file that was claimed by the plugin. */
- plugin_insert = find_replacements_insert_point ();
+ after the first input file that was claimed by the plugin,
+ unless that file was an archive in which case it is inserted
+ immediately before. */
+ bfd_boolean before;
+ lang_statement_union_type **prev;
+ plugin_insert = find_replacements_insert_point (&before);
/* 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 (plugin_insert != NULL);
/* Splice the new statement list into the old one. */
- lang_list_insert_after (stat_ptr, &added,
- &plugin_insert->header.next);
+ prev = &plugin_insert->header.next;
+ if (before)
+ {
+ prev = find_next_input_statement (prev);
+ if (*prev != plugin_insert->next_real_file)
+ {
+ /* Huh? We didn't find the expected input statement. */
+ ASSERT (0);
+ prev = &plugin_insert->header.next;
+ }
+ }
+ lang_list_insert_after (stat_ptr, &added, prev);
/* Likewise for the file chains. */
lang_list_insert_after (&input_file_chain, &inputfiles,
&plugin_insert->next_real_file);