This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[PATCH 2/9] Reload --as-needed libraries inside groups
- From: Pedro Alves <palves at redhat dot com>
- To: gdb-patches at sourceware dot org
- Cc: Alan Modra <amodra at gmail dot com>
- Date: Thu, 3 Jul 2014 16:13:12 +0100
- Subject: [PATCH 2/9] Reload --as-needed libraries inside groups
- Authentication-results: sourceware.org; auth=none
- References: <1404400406-16708-1-git-send-email-palves at redhat dot com>
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