LTO object insertion point
[deliverable/binutils-gdb.git] / ld / ldlang.c
index b88c8418102e6b3b7175570a05bb36467af72320..8119cfc45bf95ea8949ecab19639ad75f13382a3 100644 (file)
@@ -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);
This page took 0.025065 seconds and 4 git commands to generate.