[binutils-gdb] PR24873, gcc -flto objects result in --start-group .. --end-group failure to include --as-needed lib

Alan Modra amodra@sourceware.org
Tue Aug 6 06:43:00 GMT 2019


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=b02c4f162335ed055964f603ba3aca18b0e5c5bf

commit b02c4f162335ed055964f603ba3aca18b0e5c5bf
Author: Alan Modra <amodra@gmail.com>
Date:   Tue Aug 6 15:23:28 2019 +0930

    PR24873, gcc -flto objects result in --start-group .. --end-group failure to include --as-needed libraries
    
    Reloading of archives (and checking --as-needed DSOs again) is
    disabled until we hit the plugin insert point.  It's necessary to do
    that because in a case like lib1.a lto.o lib2.a where lib1.a and
    lib2.a contain duplicate symbols, we want the lto.o recompiled object
    to pull in objects from lib2.a as necessary, but not from lib1.a.
    Unfortunately this heuristic fails when the insert point is inside a
    group, because ld actually loads the symbols from the recompiled
    object before running over the contours of the script, thus missing
    the fact that new undefs appeared in the group.
    
    	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.
    	(lang_process <lto_plugin_active>): Set plugin_undefs.

Diff:
---
 ld/ChangeLog |  8 ++++++++
 ld/ldlang.c  | 19 ++++++++++++++++++-
 2 files changed, 26 insertions(+), 1 deletion(-)

diff --git a/ld/ChangeLog b/ld/ChangeLog
index 8015427..8f9d1f0 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,11 @@
+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.
+	(lang_process <lto_plugin_active>): Set plugin_undefs.
+
 2019-08-02  Alan Modra  <amodra@gmail.com>
 
 	* testsuite/ld-powerpc/tlsie.s: Correct medium model ELF sequence.
diff --git a/ld/ldlang.c b/ld/ldlang.c
index 96daf0e..b88c841 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -3444,6 +3444,7 @@ enum open_bfd_mode
   };
 #ifdef ENABLE_PLUGINS
 static lang_input_statement_type *plugin_insert = NULL;
+static struct bfd_link_hash_entry *plugin_undefs = NULL;
 #endif
 
 static void
@@ -3471,6 +3472,9 @@ open_input_bfds (lang_statement_union_type *s, enum open_bfd_mode mode)
 	case lang_group_statement_enum:
 	  {
 	    struct bfd_link_hash_entry *undefs;
+#ifdef ENABLE_PLUGINS
+	    lang_input_statement_type *plugin_insert_save;
+#endif
 
 	    /* We must continually search the entries in the group
 	       until no new symbols are added to the list of undefined
@@ -3478,11 +3482,21 @@ open_input_bfds (lang_statement_union_type *s, enum open_bfd_mode mode)
 
 	    do
 	      {
+#ifdef ENABLE_PLUGINS
+		plugin_insert_save = plugin_insert;
+#endif
 		undefs = link_info.hash->undefs_tail;
 		open_input_bfds (s->group_statement.children.head,
 				 mode | OPEN_BFD_FORCE);
 	      }
-	    while (undefs != link_info.hash->undefs_tail);
+	    while (undefs != link_info.hash->undefs_tail
+#ifdef ENABLE_PLUGINS
+		   /* Objects inserted by a plugin, which are loaded
+		      before we hit this loop, may have added new
+		      undefs.  */
+		   || (plugin_insert != plugin_insert_save && plugin_undefs)
+#endif
+		   );
 	  }
 	  break;
 	case lang_target_statement_enum:
@@ -7420,7 +7434,10 @@ lang_process (void)
 	einfo (_("%F%P: %s: plugin reported error after all symbols read\n"),
 	       plugin_error_plugin ());
       /* Open any newly added files, updating the file chains.  */
+      plugin_undefs = link_info.hash->undefs_tail;
       open_input_bfds (*added.tail, OPEN_BFD_NORMAL);
+      if (plugin_undefs == link_info.hash->undefs_tail)
+	plugin_undefs = NULL;
       /* Restore the global list pointer now they have all been added.  */
       lang_list_remove_tail (stat_ptr, &added);
       /* And detach the fresh ends of the file lists.  */



More information about the Binutils-cvs mailing list