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.
This commit is contained in:
Alan Modra
2020-10-30 14:56:35 +10:30
parent ae7754b256
commit b1a92c635c
10 changed files with 113 additions and 17 deletions

View File

@ -1,3 +1,12 @@
2020-11-02 Alan Modra <amodra@gmail.com>
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.
2020-10-30 H.J. Lu <hongjiu.lu@intel.com>
PR gas/26703

View File

@ -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),

View File

@ -1,3 +1,14 @@
2020-11-02 Alan Modra <amodra@gmail.com>
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.
2020-10-30 H.J. Lu <hongjiu.lu@intel.com>
PR gas/26703

View File

@ -0,0 +1,6 @@
struct re_dfa_t {
const int *sb_char;
};
struct re_dfa_t *xregcomp (void);
struct re_dfa_t *rpl_regcomp (void);
void rpl_regfree (struct re_dfa_t *);

View File

@ -0,0 +1,19 @@
#include <stdio.h>
#include <stdlib.h>
#include "lto-19.h"
static const int utf8_sb_map[4] = { 0x12, 0x34, 0x56, 0x78 };
struct re_dfa_t *
rpl_regcomp ()
{
struct re_dfa_t *dfa = malloc (sizeof (struct re_dfa_t));
dfa->sb_char = utf8_sb_map;
return dfa;
}
void
rpl_regfree (struct re_dfa_t *dfa)
{
puts (dfa->sb_char == utf8_sb_map ? "PASS" : "FAIL");
}

View File

@ -0,0 +1,7 @@
#include "lto-19.h"
struct re_dfa_t *
xregcomp (void)
{
return rpl_regcomp ();
}

View File

@ -0,0 +1,9 @@
#include "lto-19.h"
int
main ()
{
struct re_dfa_t *dfa = xregcomp ();
rpl_regfree (dfa);
return 0;
}

View File

@ -403,6 +403,18 @@ set lto_link_elf_tests [list \
[list {lto-18d.o} \
{} {-flto -O2} \
{lto-18d.c} {} {}] \
[list {liblto-19.a} \
"$plug_opt" {-flto -O2 -fPIC} \
{lto-19a.c} {} {liblto-19.a}] \
[list {compile lto-19b.c} \
"$plug_opt" {-flto -O2 -fPIC} \
{lto-19b.c} {} {} {c}] \
[list {liblto-19.so} \
{-shared tmpdir/lto-19b.o tmpdir/liblto-19.a} {-O2 -fPIC} \
{dummy.c} {} {liblto-19.so}] \
[list {pr26806.so} \
{-shared} {-fpic -O2 -flto} \
{pr26806.c} {{nm {-D} pr26806.d}} {pr26806.so}] \
]
# PR 14918 checks that libgcc is not spuriously included in a shared link of
@ -584,6 +596,10 @@ set lto_run_elf_shared_tests [list \
{-static -flto -fuse-linker-plugin} {} \
{lto-18a.c} {lto-18-4.exe} {lto-18.out} {-flto -O2} {c} {} \
{ -Ltmpdir -llto-18b -llto-18c tmpdir/lto-18d.o}] \
[list {lto-19} \
{-Wl,--as-needed,-R,tmpdir} {} \
{lto-19c.c} {lto-19.exe} {pass.out} {-flto -O2} {c} {} \
{tmpdir/liblto-19.so tmpdir/liblto-19.a}] \
]
# LTO run-time tests for ELF

View File

@ -0,0 +1,2 @@
#include <unistd.h>
int foo (int x) { if (__builtin_constant_p (x)) return getpid (); return 0; }

View File

@ -0,0 +1,4 @@
#failif
#...
.* _*getpid[@ ].*
#...