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;
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;
/* 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;
}
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. */
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);