From: Alan Modra Date: Fri, 30 Oct 2020 04:26:35 +0000 (+1030) Subject: PR26806, Suspected linker bug with LTO X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=b1a92c635c1ec10fd703302ce1fc4ab3a8515a04;p=binutils-gdb.git 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. --- diff --git a/bfd/ChangeLog b/bfd/ChangeLog index a12ba7de337..e632282a71c 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,12 @@ +2020-11-02 Alan Modra + + 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 PR gas/26703 diff --git a/bfd/elflink.c b/bfd/elflink.c index e23d189b983..4b035a2cd56 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), diff --git a/ld/ChangeLog b/ld/ChangeLog index 3f39eb462e7..f980e623944 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,14 @@ +2020-11-02 Alan Modra + + 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 PR gas/26703 diff --git a/ld/testsuite/ld-plugin/lto-19.h b/ld/testsuite/ld-plugin/lto-19.h new file mode 100644 index 00000000000..0ca48d1f1aa --- /dev/null +++ b/ld/testsuite/ld-plugin/lto-19.h @@ -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 *); diff --git a/ld/testsuite/ld-plugin/lto-19a.c b/ld/testsuite/ld-plugin/lto-19a.c new file mode 100644 index 00000000000..6213f79144d --- /dev/null +++ b/ld/testsuite/ld-plugin/lto-19a.c @@ -0,0 +1,19 @@ +#include +#include +#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"); +} diff --git a/ld/testsuite/ld-plugin/lto-19b.c b/ld/testsuite/ld-plugin/lto-19b.c new file mode 100644 index 00000000000..b784f84ce06 --- /dev/null +++ b/ld/testsuite/ld-plugin/lto-19b.c @@ -0,0 +1,7 @@ +#include "lto-19.h" + +struct re_dfa_t * +xregcomp (void) +{ + return rpl_regcomp (); +} diff --git a/ld/testsuite/ld-plugin/lto-19c.c b/ld/testsuite/ld-plugin/lto-19c.c new file mode 100644 index 00000000000..0d231ba5725 --- /dev/null +++ b/ld/testsuite/ld-plugin/lto-19c.c @@ -0,0 +1,9 @@ +#include "lto-19.h" + +int +main () +{ + struct re_dfa_t *dfa = xregcomp (); + rpl_regfree (dfa); + return 0; +} diff --git a/ld/testsuite/ld-plugin/lto.exp b/ld/testsuite/ld-plugin/lto.exp index 9f9f2d13ced..23c948cc643 100644 --- a/ld/testsuite/ld-plugin/lto.exp +++ b/ld/testsuite/ld-plugin/lto.exp @@ -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 diff --git a/ld/testsuite/ld-plugin/pr26806.c b/ld/testsuite/ld-plugin/pr26806.c new file mode 100644 index 00000000000..8bb29316f58 --- /dev/null +++ b/ld/testsuite/ld-plugin/pr26806.c @@ -0,0 +1,2 @@ +#include +int foo (int x) { if (__builtin_constant_p (x)) return getpid (); return 0; } diff --git a/ld/testsuite/ld-plugin/pr26806.d b/ld/testsuite/ld-plugin/pr26806.d new file mode 100644 index 00000000000..16fa828e136 --- /dev/null +++ b/ld/testsuite/ld-plugin/pr26806.d @@ -0,0 +1,4 @@ +#failif +#... +.* _*getpid[@ ].* +#...