Handle symbol defined in IR and referenced in DSO
We need to make an IR symbol visible if it is defined in an IR object and referenced in a dynamic object. When --as-needed is used, since linker removes the IR symbol reference of the dynamic object if the dynamic object isn't needed in the first pass, the IR definition isn't visible to the dynamic object even if the dynamic object becomes needed in the second pass. Add dynamic_ref_after_ir_def to bfd_link_hash_entry to track IR symbol which is defined in an IR object and later referenced in a dynamic object. dynamic_ref_after_ir_def is preserved when restoring the symbol table for unneeded dynamic object. bfd/ PR ld/21382 * elflink.c (elf_link_add_object_symbols): Preserve dynamic_ref_after_ir_def when restoring the symbol table for unneeded dynamic object. include/ PR ld/21382 * bfdlink.h (bfd_link_hash_entry): Add dynamic_ref_after_ir_def. ld/ PR ld/21382 * plugin.c (is_visible_from_outside): Symbol may be visible from outside if dynamic_ref_after_ir_def is set. (plugin_notice): Set dynamic_ref_after_ir_def if the symbol is defined in an IR object and referenced in a dynamic object. * testsuite/ld-plugin/lto.exp: Run PR ld/21382 tests. * testsuite/ld-plugin/pr21382a.c: New file. * testsuite/ld-plugin/pr21382b.c: Likewise.
This commit is contained in:
parent
c768868859
commit
59fa66c538
@ -1,3 +1,10 @@
|
||||
2017-04-20 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
PR ld/21382
|
||||
* elflink.c (elf_link_add_object_symbols): Preserve
|
||||
dynamic_ref_after_ir_def when restoring the symbol table for
|
||||
unneeded dynamic object.
|
||||
|
||||
2017-04-19 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
PR ld/21401
|
||||
|
@ -4932,6 +4932,7 @@ error_free_dyn:
|
||||
struct elf_link_hash_entry *h;
|
||||
bfd_size_type size;
|
||||
unsigned int alignment_power;
|
||||
unsigned int dynamic_ref_after_ir_def;
|
||||
|
||||
for (p = htab->root.table.table[i]; p != NULL; p = p->next)
|
||||
{
|
||||
@ -4953,6 +4954,10 @@ error_free_dyn:
|
||||
size = 0;
|
||||
alignment_power = 0;
|
||||
}
|
||||
/* Preserve dynamic_ref_after_ir_def so that this symbol
|
||||
will be exported when the dynamic lib becomes needed
|
||||
in the second pass. */
|
||||
dynamic_ref_after_ir_def = h->root.dynamic_ref_after_ir_def;
|
||||
memcpy (p, old_ent, htab->root.table.entsize);
|
||||
old_ent = (char *) old_ent + htab->root.table.entsize;
|
||||
h = (struct elf_link_hash_entry *) p;
|
||||
@ -4969,6 +4974,7 @@ error_free_dyn:
|
||||
if (alignment_power > h->root.u.c.p->alignment_power)
|
||||
h->root.u.c.p->alignment_power = alignment_power;
|
||||
}
|
||||
h->root.dynamic_ref_after_ir_def = dynamic_ref_after_ir_def;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,8 @@
|
||||
2017-04-20 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
PR ld/21382
|
||||
* bfdlink.h (bfd_link_hash_entry): Add dynamic_ref_after_ir_def.
|
||||
|
||||
2017-04-19 Alan Modra <amodra@gmail.com>
|
||||
|
||||
* bfdlink.h (struct bfd_link_info <dynamic_undefined_weak>):
|
||||
|
@ -104,6 +104,10 @@ struct bfd_link_hash_entry
|
||||
IR object file. */
|
||||
unsigned int non_ir_ref : 1;
|
||||
|
||||
/* Symbol is referenced in a dynamic object after it has been defined
|
||||
in an IR object. */
|
||||
unsigned int dynamic_ref_after_ir_def : 1;
|
||||
|
||||
/* Symbol is a built-in define. These will be overridden by PROVIDE
|
||||
in a linker script. */
|
||||
unsigned int linker_def : 1;
|
||||
|
11
ld/ChangeLog
11
ld/ChangeLog
@ -1,3 +1,14 @@
|
||||
2017-04-20 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
PR ld/21382
|
||||
* plugin.c (is_visible_from_outside): Symbol may be visible
|
||||
from outside if dynamic_ref_after_ir_def is set.
|
||||
(plugin_notice): Set dynamic_ref_after_ir_def if the symbol is
|
||||
defined in an IR object and referenced in a dynamic object.
|
||||
* testsuite/ld-plugin/lto.exp: Run PR ld/21382 tests.
|
||||
* testsuite/ld-plugin/pr21382a.c: New file.
|
||||
* testsuite/ld-plugin/pr21382b.c: Likewise.
|
||||
|
||||
2017-04-19 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
PR ld/21401
|
||||
|
23
ld/plugin.c
23
ld/plugin.c
@ -629,7 +629,9 @@ is_visible_from_outside (struct ld_plugin_symbol *lsym,
|
||||
|
||||
if (bfd_link_relocatable (&link_info))
|
||||
return TRUE;
|
||||
if (link_info.export_dynamic || bfd_link_dll (&link_info))
|
||||
if (blhe->dynamic_ref_after_ir_def
|
||||
|| link_info.export_dynamic
|
||||
|| bfd_link_dll (&link_info))
|
||||
{
|
||||
/* Check if symbol is hidden by version script. */
|
||||
if (bfd_hide_sym_by_version (link_info.version_info,
|
||||
@ -1316,12 +1318,21 @@ plugin_notice (struct bfd_link_info *info,
|
||||
/* If this is a ref, set non_ir_ref. */
|
||||
else if (bfd_is_und_section (section))
|
||||
{
|
||||
if (h->type == bfd_link_hash_defweak
|
||||
|| h->type == bfd_link_hash_defined)
|
||||
{
|
||||
/* Check if the symbol is referenced in a dynamic object
|
||||
after it has been defined in an IR object. */
|
||||
if ((abfd->flags & DYNAMIC) != 0
|
||||
&& is_ir_dummy_bfd (h->u.def.section->owner))
|
||||
h->dynamic_ref_after_ir_def = TRUE;
|
||||
}
|
||||
/* Replace the undefined dummy bfd with the real one. */
|
||||
if ((h->type == bfd_link_hash_undefined
|
||||
|| h->type == bfd_link_hash_undefweak)
|
||||
&& (h->u.undef.abfd == NULL
|
||||
|| (h->u.undef.abfd->flags & BFD_PLUGIN) != 0))
|
||||
h->u.undef.abfd = abfd;
|
||||
else if ((h->type == bfd_link_hash_undefined
|
||||
|| h->type == bfd_link_hash_undefweak)
|
||||
&& (h->u.undef.abfd == NULL
|
||||
|| (h->u.undef.abfd->flags & BFD_PLUGIN) != 0))
|
||||
h->u.undef.abfd = abfd;
|
||||
h->non_ir_ref = TRUE;
|
||||
}
|
||||
|
||||
|
@ -289,6 +289,12 @@ set lto_link_elf_tests [list \
|
||||
[list "PR ld/14918" \
|
||||
"-flto" "-flto" \
|
||||
{pr14918.c} {{"readelf" {-d --wide} "pr14918.d"}} "pr14918.exe" "c"] \
|
||||
[list "Build pr21382a.o" \
|
||||
"" "-O2 -flto" \
|
||||
{pr21382a.c} {} "" "c"] \
|
||||
[list "Build pr21382.so" \
|
||||
"-shared" "-O2 -fpic" \
|
||||
{pr21382b.c} {} "pr21382.so" "c"] \
|
||||
]
|
||||
|
||||
# Check final symbols in executables.
|
||||
@ -387,6 +393,9 @@ set lto_run_elf_shared_tests [list \
|
||||
[list "LTO 7" \
|
||||
"-O2 -flto -fuse-linker-plugin tmpdir/lto-7b.o tmpdir/lto-7c.o tmpdir/lto-7a.o -Wl,--no-as-needed tmpdir/liblto-7.so" "" \
|
||||
{dummy.c} "lto-7.exe" "lto-7.out" "" "c"] \
|
||||
[list "Run pr21382" \
|
||||
"-O2 -flto -fuse-linker-plugin -Wl,--as-needed tmpdir/pr21382a.o tmpdir/pr21382.so" "" \
|
||||
{dummy.c} "pr21382.exe" "pass.out" "" "c"] \
|
||||
]
|
||||
|
||||
# LTO run-time tests for ELF
|
||||
|
17
ld/testsuite/ld-plugin/pr21382a.c
Normal file
17
ld/testsuite/ld-plugin/pr21382a.c
Normal file
@ -0,0 +1,17 @@
|
||||
#include <stdio.h>
|
||||
|
||||
extern void y (void);
|
||||
|
||||
void
|
||||
x (void)
|
||||
{
|
||||
printf ("PASS\n");
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
y ();
|
||||
return 0;
|
||||
}
|
7
ld/testsuite/ld-plugin/pr21382b.c
Normal file
7
ld/testsuite/ld-plugin/pr21382b.c
Normal file
@ -0,0 +1,7 @@
|
||||
extern void x (void);
|
||||
|
||||
void
|
||||
y (void)
|
||||
{
|
||||
x ();
|
||||
}
|
Loading…
Reference in New Issue
Block a user