diff options
-rw-r--r-- | ld/ChangeLog | 9 | ||||
-rw-r--r-- | ld/ldlang.c | 59 |
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); |