aboutsummaryrefslogtreecommitdiff
path: root/bfd/elflink.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2020-10-30 14:56:35 +1030
committerAlan Modra <amodra@gmail.com>2020-11-02 09:39:53 +1030
commitb1a92c635c1ec10fd703302ce1fc4ab3a8515a04 (patch)
tree80c9f60d71a1d360f6a223b8d3ee4c330a5af55d /bfd/elflink.c
parentae7754b256f1f230baec364d90561c3ca34f7e64 (diff)
downloadfsf-binutils-gdb-b1a92c635c1ec10fd703302ce1fc4ab3a8515a04.zip
fsf-binutils-gdb-b1a92c635c1ec10fd703302ce1fc4ab3a8515a04.tar.gz
fsf-binutils-gdb-b1a92c635c1ec10fd703302ce1fc4ab3a8515a04.tar.bz2
PR26806, Suspected linker bug with LTO
This patch reverts most of git commit 1e3b96fd6cf, so IR symbols are again not marked def_regular or ref_regular. That should be enough to stop IR symbols from becoming dynamic. To mark as-needed shared libraries referenced by IR symbols, use the referencing BFD rather than the ref flags. bfd/ PR 15146 PR 26314 PR 26530 PR 26806 * elflink.c (elf_link_add_object_symbols): Don't set def/ref flags for plugin syms. Do allow plugin syms to mark as-needed libs. ld/ PR 26806 * testsuite/ld-plugin/lto-19.h, * testsuite/ld-plugin/lto-19a.c, * testsuite/ld-plugin/lto-19b.c, * testsuite/ld-plugin/lto-19c.c: New test. * testsuite/ld-plugin/pr26806.c, * testsuite/ld-plugin/pr26806.d: New test. * testsuite/ld-plugin/lto.exp: Run them.
Diffstat (limited to 'bfd/elflink.c')
-rw-r--r--bfd/elflink.c47
1 files changed, 30 insertions, 17 deletions
diff --git a/bfd/elflink.c b/bfd/elflink.c
index e23d189..4b035a2 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -4989,7 +4989,10 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
object and a shared object. */
bfd_boolean dynsym = FALSE;
- if (! dynamic)
+ /* Plugin symbols aren't normal. Don't set def/ref flags. */
+ if ((abfd->flags & BFD_PLUGIN) != 0)
+ ;
+ else if (!dynamic)
{
if (! definition)
{
@@ -5006,14 +5009,6 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
h->ref_dynamic = 1;
}
}
-
- /* If the indirect symbol has been forced local, don't
- make the real symbol dynamic. */
- if ((h == hi || !hi->forced_local)
- && (bfd_link_dll (info)
- || h->def_dynamic
- || h->ref_dynamic))
- dynsym = TRUE;
}
else
{
@@ -5027,14 +5022,25 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
h->def_dynamic = 1;
hi->def_dynamic = 1;
}
+ }
- /* If the indirect symbol has been forced local, don't
- make the real symbol dynamic. */
- if ((h == hi || !hi->forced_local)
- && (h->def_regular
- || h->ref_regular
- || (h->is_weakalias
- && weakdef (h)->dynindx != -1)))
+ /* If an indirect symbol has been forced local, don't
+ make the real symbol dynamic. */
+ if (h != hi && hi->forced_local)
+ ;
+ else if (!dynamic)
+ {
+ if (bfd_link_dll (info)
+ || h->def_dynamic
+ || h->ref_dynamic)
+ dynsym = TRUE;
+ }
+ else
+ {
+ if (h->def_regular
+ || h->ref_regular
+ || (h->is_weakalias
+ && weakdef (h)->dynindx != -1))
dynsym = TRUE;
}
@@ -5170,6 +5176,10 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
&& !bfd_link_relocatable (info))
dynsym = FALSE;
+ /* Nor should we make plugin symbols dynamic. */
+ if ((abfd->flags & BFD_PLUGIN) != 0)
+ dynsym = FALSE;
+
if (definition)
{
h->target_internal = isym->st_target_internal;
@@ -5196,7 +5206,7 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
}
}
- if (dynsym && (abfd->flags & BFD_PLUGIN) == 0 && h->dynindx == -1)
+ if (dynsym && h->dynindx == -1)
{
if (! bfd_elf_link_record_dynamic_symbol (info, h))
goto error_free_vers;
@@ -5225,6 +5235,9 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
&& definition
&& ((dynsym
&& h->ref_regular_nonweak)
+ || (old_bfd != NULL
+ && (old_bfd->flags & BFD_PLUGIN) != 0
+ && bind != STB_WEAK)
|| (h->ref_dynamic_nonweak
&& (elf_dyn_lib_class (abfd) & DYN_AS_NEEDED) != 0
&& !on_needed_list (elf_dt_name (abfd),