Reload --as-needed libraries inside groups
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.
This commit is contained in:
parent
fd48cee009
commit
d215621ebe
10
ld/ChangeLog
10
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>
|
2014-07-01 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
* emultempl/ppc64elf.em (stub_added): Delete.
|
* emultempl/ppc64elf.em (stub_added): Delete.
|
||||||
|
28
ld/ldlang.c
28
ld/ldlang.c
@ -2790,9 +2790,7 @@ load_symbols (lang_input_statement_type *entry,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case bfd_object:
|
case bfd_object:
|
||||||
#ifdef ENABLE_PLUGINS
|
|
||||||
if (!entry->flags.reload)
|
if (!entry->flags.reload)
|
||||||
#endif
|
|
||||||
ldlang_add_file (entry);
|
ldlang_add_file (entry);
|
||||||
if (trace_files || verbose)
|
if (trace_files || verbose)
|
||||||
info_msg ("%I\n", entry);
|
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_union_type **os_tail;
|
||||||
lang_statement_list_type add;
|
lang_statement_list_type add;
|
||||||
|
bfd *abfd;
|
||||||
|
|
||||||
s->input_statement.target = current_target;
|
s->input_statement.target = current_target;
|
||||||
|
|
||||||
/* If we are being called from within a group, and this
|
/* If we are being called from within a group, and this
|
||||||
is an archive which has already been searched, then
|
is an archive which has already been searched, then
|
||||||
force it to be researched unless the whole archive
|
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
|
if (mode != OPEN_BFD_NORMAL
|
||||||
#ifdef ENABLE_PLUGINS
|
#ifdef ENABLE_PLUGINS
|
||||||
&& ((mode & OPEN_BFD_RESCAN) == 0
|
&& ((mode & OPEN_BFD_RESCAN) == 0
|
||||||
|| plugin_insert == NULL)
|
|| plugin_insert == NULL)
|
||||||
#endif
|
#endif
|
||||||
&& !s->input_statement.flags.whole_archive
|
|
||||||
&& s->input_statement.flags.loaded
|
&& s->input_statement.flags.loaded
|
||||||
&& s->input_statement.the_bfd != NULL
|
&& (abfd = s->input_statement.the_bfd) != NULL
|
||||||
&& bfd_check_format (s->input_statement.the_bfd,
|
&& ((bfd_get_format (abfd) == bfd_archive
|
||||||
bfd_archive))
|
&& !s->input_statement.flags.whole_archive)
|
||||||
s->input_statement.flags.loaded = FALSE;
|
|| (bfd_get_format (abfd) == bfd_object
|
||||||
#ifdef ENABLE_PLUGINS
|
&& ((abfd->flags) & DYNAMIC) != 0
|
||||||
/* When rescanning, reload --as-needed shared libs. */
|
&& s->input_statement.flags.add_DT_NEEDED_for_regular
|
||||||
else if ((mode & OPEN_BFD_RESCAN) != 0
|
&& plugin_should_reload (abfd))))
|
||||||
&& 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))
|
|
||||||
{
|
{
|
||||||
s->input_statement.flags.loaded = FALSE;
|
s->input_statement.flags.loaded = FALSE;
|
||||||
s->input_statement.flags.reload = TRUE;
|
s->input_statement.flags.reload = TRUE;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
os_tail = lang_output_section_statement.tail;
|
os_tail = lang_output_section_statement.tail;
|
||||||
lang_list_init (&add);
|
lang_list_init (&add);
|
||||||
|
@ -279,7 +279,7 @@ struct lang_input_statement_flags
|
|||||||
/* Set if the file was claimed from an archive. */
|
/* Set if the file was claimed from an archive. */
|
||||||
unsigned int claim_archive : 1;
|
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;
|
unsigned int reload : 1;
|
||||||
#endif /* ENABLE_PLUGINS */
|
#endif /* ENABLE_PLUGINS */
|
||||||
};
|
};
|
||||||
|
@ -1029,13 +1029,11 @@ plugin_notice (struct bfd_link_info *info,
|
|||||||
return TRUE;
|
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
|
bfd_boolean
|
||||||
plugin_should_reload (bfd *abfd)
|
plugin_should_reload (bfd *abfd)
|
||||||
{
|
{
|
||||||
return ((abfd->flags & DYNAMIC) != 0
|
return (bfd_get_flavour (abfd) == bfd_target_elf_flavour
|
||||||
&& bfd_get_flavour (abfd) == bfd_target_elf_flavour
|
|
||||||
&& bfd_get_format (abfd) == bfd_object
|
|
||||||
&& (elf_dyn_lib_class (abfd) & DYN_AS_NEEDED) != 0);
|
&& (elf_dyn_lib_class (abfd) & DYN_AS_NEEDED) != 0);
|
||||||
}
|
}
|
||||||
|
@ -66,7 +66,7 @@ extern void plugin_call_cleanup (void);
|
|||||||
add_symbols hook has been called so that it can be read when linking. */
|
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);
|
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 *);
|
extern bfd_boolean plugin_should_reload (bfd *);
|
||||||
|
|
||||||
#endif /* !def GLD_PLUGIN_H */
|
#endif /* !def GLD_PLUGIN_H */
|
||||||
|
@ -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>
|
2014-07-02 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
* ld-powerpc/ambiguousv1.d: Match symbol table too.
|
* ld-powerpc/ambiguousv1.d: Match symbol table too.
|
||||||
|
@ -77,13 +77,12 @@ if { ![istarget hppa64*-hpux*] } {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Run a test to check linking a shared library with a broken linker
|
# Only run these tests on targets thats support creating shared libraries.
|
||||||
# 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.
|
|
||||||
if { [check_shared_lib_support] } then {
|
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-*-*"
|
setup_xfail "tic6x-*-*"
|
||||||
run_ld_link_tests {
|
run_ld_link_tests {
|
||||||
{"Build shared library for next test"
|
{"Build shared library for next test"
|
||||||
@ -93,6 +92,21 @@ if { [check_shared_lib_support] } then {
|
|||||||
{ { ld "note-3.l" } }
|
{ { ld "note-3.l" } }
|
||||||
"a.out" }
|
"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]]
|
set test_list [lsort [glob -nocomplain $srcdir/$subdir/*.d]]
|
||||||
|
2
ld/testsuite/ld-elf/pr17068.s
Normal file
2
ld/testsuite/ld-elf/pr17068.s
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
.data
|
||||||
|
.dc.a a
|
4
ld/testsuite/ld-elf/pr17068a.s
Normal file
4
ld/testsuite/ld-elf/pr17068a.s
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
.data
|
||||||
|
.globl a
|
||||||
|
a:
|
||||||
|
.dc.a b
|
4
ld/testsuite/ld-elf/pr17068b.s
Normal file
4
ld/testsuite/ld-elf/pr17068b.s
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
.data
|
||||||
|
.globl b
|
||||||
|
b:
|
||||||
|
.dc.a c
|
4
ld/testsuite/ld-elf/pr17068c.s
Normal file
4
ld/testsuite/ld-elf/pr17068c.s
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
.data
|
||||||
|
.globl c
|
||||||
|
c:
|
||||||
|
.dc.a d
|
6
ld/testsuite/ld-elf/pr17068d.s
Normal file
6
ld/testsuite/ld-elf/pr17068d.s
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
.data
|
||||||
|
.globl d
|
||||||
|
.type d,%object
|
||||||
|
d:
|
||||||
|
.dc.a e
|
||||||
|
.size d,.-d
|
3
ld/testsuite/ld-elf/pr17068e.s
Normal file
3
ld/testsuite/ld-elf/pr17068e.s
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
.data
|
||||||
|
.globl e
|
||||||
|
e:
|
4
ld/testsuite/ld-elf/pr17068ez.s
Normal file
4
ld/testsuite/ld-elf/pr17068ez.s
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
.data
|
||||||
|
.globl e
|
||||||
|
e:
|
||||||
|
.dc.a z
|
Loading…
x
Reference in New Issue
Block a user