This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH 2/9] Reload --as-needed libraries inside groups


From: Alan Modra <amodra@gmail.com>

When a shared library appears within --start-group/--end-group ld may
only discover a need for loading the library on the second or
subsequent pass over archive libraries, as more objects are extracted.

ld/
	PR 17068
	* ldlang.c (load_symbols): Always check flags.reload.
	(open_input_bfds): Always reload --as-needed shared libraries,
	not just when rescanning.
	* ldlang.h (struct lang_input_statement_flags): Update reload comment.
	* plugin.c (plugin_should_reload): Assume shared library arg.
	* plugin.h (plugin_should_reload): Update comment.
ld/testsuite
	* ld-elf/pr17068.s: New.
	* ld-elf/pr17068a.s: New.
	* ld-elf/pr17068b.s: New.
	* ld-elf/pr17068c.s: New.
	* ld-elf/pr17068d.s: New.
	* ld-elf/pr17068e.s: New.
	* ld-elf/pr17068ez.s: New.
	* ld-elf/elf.exp: Run new test.
---
 ld/ChangeLog                    | 10 ++++++++++
 ld/testsuite/ChangeLog          | 11 +++++++++++
 ld/ldlang.c                     | 28 ++++++++++------------------
 ld/ldlang.h                     |  2 +-
 ld/plugin.c                     |  6 ++----
 ld/plugin.h                     |  2 +-
 ld/testsuite/ld-elf/elf.exp     | 26 ++++++++++++++++++++------
 ld/testsuite/ld-elf/pr17068.s   |  2 ++
 ld/testsuite/ld-elf/pr17068a.s  |  4 ++++
 ld/testsuite/ld-elf/pr17068b.s  |  4 ++++
 ld/testsuite/ld-elf/pr17068c.s  |  4 ++++
 ld/testsuite/ld-elf/pr17068d.s  |  6 ++++++
 ld/testsuite/ld-elf/pr17068e.s  |  3 +++
 ld/testsuite/ld-elf/pr17068ez.s |  4 ++++
 14 files changed, 82 insertions(+), 30 deletions(-)
 create mode 100644 ld/testsuite/ld-elf/pr17068.s
 create mode 100644 ld/testsuite/ld-elf/pr17068a.s
 create mode 100644 ld/testsuite/ld-elf/pr17068b.s
 create mode 100644 ld/testsuite/ld-elf/pr17068c.s
 create mode 100644 ld/testsuite/ld-elf/pr17068d.s
 create mode 100644 ld/testsuite/ld-elf/pr17068e.s
 create mode 100644 ld/testsuite/ld-elf/pr17068ez.s

diff --git a/ld/ChangeLog b/ld/ChangeLog
index bfddd80..f7dd212 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,13 @@
+2014-07-03  Alan Modra  <amodra@gmail.com>
+
+	PR 17068
+	* ldlang.c (load_symbols): Always check flags.reload.
+	(open_input_bfds): Always reload --as-needed shared libraries,
+	not just when rescanning.
+	* ldlang.h (struct lang_input_statement_flags): Update reload comment.
+	* plugin.c (plugin_should_reload): Assume shared library arg.
+	* plugin.h (plugin_should_reload): Update comment.
+
 2014-07-01  Alan Modra  <amodra@gmail.com>
 
 	* emultempl/ppc64elf.em (stub_added): Delete.
diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog
index b59f584..7d3a6e4 100644
--- a/ld/testsuite/ChangeLog
+++ b/ld/testsuite/ChangeLog
@@ -1,3 +1,14 @@
+2014-07-03  Alan Modra  <amodra@gmail.com>
+
+	* ld-elf/pr17068.s: New.
+	* ld-elf/pr17068a.s: New.
+	* ld-elf/pr17068b.s: New.
+	* ld-elf/pr17068c.s: New.
+	* ld-elf/pr17068d.s: New.
+	* ld-elf/pr17068e.s: New.
+	* ld-elf/pr17068ez.s: New.
+	* ld-elf/elf.exp: Run new test.
+
 2014-07-02  Alan Modra  <amodra@gmail.com>
 
 	* ld-powerpc/ambiguousv1.d: Match symbol table too.
diff --git a/ld/ldlang.c b/ld/ldlang.c
index 60877b8..5e10c4a 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -2790,9 +2790,7 @@ load_symbols (lang_input_statement_type *entry,
       break;
 
     case bfd_object:
-#ifdef ENABLE_PLUGINS
       if (!entry->flags.reload)
-#endif
 	ldlang_add_file (entry);
       if (trace_files || verbose)
 	info_msg ("%I\n", entry);
@@ -3268,38 +3266,32 @@ open_input_bfds (lang_statement_union_type *s, enum open_bfd_mode mode)
 	    {
 	      lang_statement_union_type **os_tail;
 	      lang_statement_list_type add;
+	      bfd *abfd;
 
 	      s->input_statement.target = current_target;
 
 	      /* If we are being called from within a group, and this
 		 is an archive which has already been searched, then
 		 force it to be researched unless the whole archive
-		 has been loaded already.  Do the same for a rescan.  */
+		 has been loaded already.  Do the same for a rescan.
+		 Likewise reload --as-needed shared libs.  */
 	      if (mode != OPEN_BFD_NORMAL
 #ifdef ENABLE_PLUGINS
 		  && ((mode & OPEN_BFD_RESCAN) == 0
 		      || plugin_insert == NULL)
 #endif
-		  && !s->input_statement.flags.whole_archive
 		  && s->input_statement.flags.loaded
-		  && s->input_statement.the_bfd != NULL
-		  && bfd_check_format (s->input_statement.the_bfd,
-				       bfd_archive))
-		s->input_statement.flags.loaded = FALSE;
-#ifdef ENABLE_PLUGINS
-	      /* When rescanning, reload --as-needed shared libs.  */
-	      else if ((mode & OPEN_BFD_RESCAN) != 0
-		       && plugin_insert == NULL
-		       && s->input_statement.flags.loaded
-		       && s->input_statement.flags.add_DT_NEEDED_for_regular
-		       && s->input_statement.the_bfd != NULL
-		       && ((s->input_statement.the_bfd->flags) & DYNAMIC) != 0
-		       && plugin_should_reload (s->input_statement.the_bfd))
+		  && (abfd = s->input_statement.the_bfd) != NULL
+		  && ((bfd_get_format (abfd) == bfd_archive
+		       && !s->input_statement.flags.whole_archive)
+		      || (bfd_get_format (abfd) == bfd_object
+			  && ((abfd->flags) & DYNAMIC) != 0
+			  && s->input_statement.flags.add_DT_NEEDED_for_regular
+			  && plugin_should_reload (abfd))))
 		{
 		  s->input_statement.flags.loaded = FALSE;
 		  s->input_statement.flags.reload = TRUE;
 		}
-#endif
 
 	      os_tail = lang_output_section_statement.tail;
 	      lang_list_init (&add);
diff --git a/ld/ldlang.h b/ld/ldlang.h
index 7d69c56..0f7fdd4 100644
--- a/ld/ldlang.h
+++ b/ld/ldlang.h
@@ -279,7 +279,7 @@ struct lang_input_statement_flags
   /* Set if the file was claimed from an archive.  */
   unsigned int claim_archive : 1;
 
-  /* Set if reloading an --as-needed lib.  */
+  /* Set if reloading an archive or --as-needed lib.  */
   unsigned int reload : 1;
 #endif /* ENABLE_PLUGINS */
 };
diff --git a/ld/plugin.c b/ld/plugin.c
index 2a6d7c5..cd6ae60 100644
--- a/ld/plugin.c
+++ b/ld/plugin.c
@@ -1029,13 +1029,11 @@ plugin_notice (struct bfd_link_info *info,
   return TRUE;
 }
 
-/* Return true if bfd is a dynamic library that should be reloaded.  */
+/* Return true if ABFD, a dynamic library, should be reloaded.  */
 
 bfd_boolean
 plugin_should_reload (bfd *abfd)
 {
-  return ((abfd->flags & DYNAMIC) != 0
-	  && bfd_get_flavour (abfd) == bfd_target_elf_flavour
-	  && bfd_get_format (abfd) == bfd_object
+  return (bfd_get_flavour (abfd) == bfd_target_elf_flavour
 	  && (elf_dyn_lib_class (abfd) & DYN_AS_NEEDED) != 0);
 }
diff --git a/ld/plugin.h b/ld/plugin.h
index beae7ab..1e239ca 100644
--- a/ld/plugin.h
+++ b/ld/plugin.h
@@ -66,7 +66,7 @@ extern void plugin_call_cleanup (void);
    add_symbols hook has been called so that it can be read when linking.  */
 extern bfd *plugin_get_ir_dummy_bfd (const char *name, bfd *template);
 
-/* Return true if bfd is a dynamic library that should be reloaded.  */
+/* Return true if ABFD, a dynamic library, should be reloaded.  */
 extern bfd_boolean plugin_should_reload (bfd *);
 
 #endif /* !def GLD_PLUGIN_H */
diff --git a/ld/testsuite/ld-elf/elf.exp b/ld/testsuite/ld-elf/elf.exp
index 4c8ca3a..839c931 100644
--- a/ld/testsuite/ld-elf/elf.exp
+++ b/ld/testsuite/ld-elf/elf.exp
@@ -77,13 +77,12 @@ if { ![istarget hppa64*-hpux*] } {
     }
 }
 
-# Run a test to check linking a shared library with a broken linker
-# script that accidentally marks dynamic sections as notes.  The
-# resulting executable is not expected to work, but the linker
-# should not seg-fault whilst creating the binary.
-#
-# Only run the test on targets thats support creating shared libraries.
+# Only run these tests on targets thats support creating shared libraries.
 if { [check_shared_lib_support] } then {
+    # Run a test to check linking a shared library with a broken linker
+    # script that accidentally marks dynamic sections as notes.  The
+    # resulting executable is not expected to work, but the linker
+    # should not seg-fault whilst creating the binary.
     setup_xfail "tic6x-*-*"
     run_ld_link_tests {
 	{"Build shared library for next test"
@@ -93,6 +92,21 @@ if { [check_shared_lib_support] } then {
 	    { { ld "note-3.l" } }
 	    "a.out" }
     }
+    setup_xfail "tic6x-*-*"
+    run_ld_link_tests {
+	{"Build pr17068.so"
+	    "-shared" "" ""
+	    {pr17068d.s} {} "pr17068.so"}
+	{"Build pr17068a.a"
+	    "" "" ""
+	    {pr17068a.s pr17068c.s pr17068ez.s} {} "pr17068a.a"}
+	{"Build pr17068b.a"
+	    "" "" ""
+	    {pr17068b.s pr17068e.s} {} "pr17068b.a"}
+	{"pr17068 link --as-needed lib in group"
+	    "--as-needed" "--start-group tmpdir/pr17068a.a tmpdir/pr17068.so tmpdir/pr17068b.a --end-group" ""
+	    {start.s pr17068.s} {} "pr17068"}
+    }
 }
 
 set test_list [lsort [glob -nocomplain $srcdir/$subdir/*.d]]
diff --git a/ld/testsuite/ld-elf/pr17068.s b/ld/testsuite/ld-elf/pr17068.s
new file mode 100644
index 0000000..9675ab4
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr17068.s
@@ -0,0 +1,2 @@
+ .data
+ .dc.a a
diff --git a/ld/testsuite/ld-elf/pr17068a.s b/ld/testsuite/ld-elf/pr17068a.s
new file mode 100644
index 0000000..552697c
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr17068a.s
@@ -0,0 +1,4 @@
+ .data
+ .globl a
+a:
+ .dc.a b
diff --git a/ld/testsuite/ld-elf/pr17068b.s b/ld/testsuite/ld-elf/pr17068b.s
new file mode 100644
index 0000000..aa536f2
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr17068b.s
@@ -0,0 +1,4 @@
+ .data
+ .globl b
+b:
+ .dc.a c
diff --git a/ld/testsuite/ld-elf/pr17068c.s b/ld/testsuite/ld-elf/pr17068c.s
new file mode 100644
index 0000000..1d78f6d
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr17068c.s
@@ -0,0 +1,4 @@
+ .data
+ .globl c
+c:
+ .dc.a d
diff --git a/ld/testsuite/ld-elf/pr17068d.s b/ld/testsuite/ld-elf/pr17068d.s
new file mode 100644
index 0000000..6165128
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr17068d.s
@@ -0,0 +1,6 @@
+ .data
+ .globl d
+ .type d,%object
+d:
+ .dc.a e
+ .size d,.-d
diff --git a/ld/testsuite/ld-elf/pr17068e.s b/ld/testsuite/ld-elf/pr17068e.s
new file mode 100644
index 0000000..095eb89
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr17068e.s
@@ -0,0 +1,3 @@
+ .data
+ .globl e
+e:
diff --git a/ld/testsuite/ld-elf/pr17068ez.s b/ld/testsuite/ld-elf/pr17068ez.s
new file mode 100644
index 0000000..70e040d
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr17068ez.s
@@ -0,0 +1,4 @@
+ .data
+ .globl e
+e:
+ .dc.a z
-- 
1.9.3


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]