]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
ld: Properly override the IR definition
authorH.J. Lu <hjl.tools@gmail.com>
Wed, 22 Jul 2020 10:49:07 +0000 (03:49 -0700)
committerH.J. Lu <hjl.tools@gmail.com>
Wed, 22 Jul 2020 12:47:43 +0000 (05:47 -0700)
We change the previous definition in the IR object to undefweak only
after all LTO symbols have been read.

include/

PR ld/26262
PR ld/26267
* bfdlink.h (bfd_link_info): Add lto_all_symbols_read.

ld/

PR ld/26262
PR ld/26267
* ldlang.c (lang_process): Set lto_all_symbols_read after all
LTO IR symbols have been read.
* plugin.c (plugin_notice): Override the IR definition only if
all LTO IR symbols have been read or the new definition is
non-weak and the the IR definition is weak
* testsuite/ld-plugin/lto.exp: Run PR ld/26262 and ld/26267
tests.
* testsuite/ld-plugin/pr26262a.c: New file.
* testsuite/ld-plugin/pr26262b.c: Likewise.
* testsuite/ld-plugin/pr26262c.c: Likewise.
* testsuite/ld-plugin/pr26267.err: Likewise.
* testsuite/ld-plugin/pr26267a.c: Likewise.
* testsuite/ld-plugin/pr26267b.c: Likewise.
* testsuite/ld-plugin/pr26267c.c: Likewise.

(cherry picked from commit 0e6a3f07f50723d1831291492b96fdf74bcbdc11)

13 files changed:
include/ChangeLog
include/bfdlink.h
ld/ChangeLog
ld/ldlang.c
ld/plugin.c
ld/testsuite/ld-plugin/lto.exp
ld/testsuite/ld-plugin/pr26262a.c [new file with mode: 0644]
ld/testsuite/ld-plugin/pr26262b.c [new file with mode: 0644]
ld/testsuite/ld-plugin/pr26262c.c [new file with mode: 0644]
ld/testsuite/ld-plugin/pr26267.err [new file with mode: 0644]
ld/testsuite/ld-plugin/pr26267a.c [new file with mode: 0644]
ld/testsuite/ld-plugin/pr26267b.c [new file with mode: 0644]
ld/testsuite/ld-plugin/pr26267c.c [new file with mode: 0644]

index 000dfe5034c369ef400318aef91c6c0c86a02a03..acdd85fc4df7a46d38f1ca8c4cc48a9ec69fcd10 100644 (file)
@@ -1,3 +1,9 @@
+2020-07-22  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR ld/26262
+       PR ld/26267
+       * bfdlink.h (bfd_link_info): Add lto_all_symbols_read.
+
 2020-07-04  Nick Clifton  <nickc@redhat.com>
 
        Binutils 2.35 branch created.
index 716343338302708f0331289fe526fe9aef67a32c..3badfbdb19f017358065f4dee2dfc60e65c2f2c2 100644 (file)
@@ -361,6 +361,9 @@ struct bfd_link_info
   /* TRUE if the LTO plugin is active.  */
   unsigned int lto_plugin_active: 1;
 
+  /* TRUE if all LTO IR symbols have been read.  */
+  unsigned int lto_all_symbols_read : 1;
+
   /* TRUE if global symbols in discarded sections should be stripped.  */
   unsigned int strip_discarded: 1;
 
index 047c5780d4ec63c50759d87a4b13ccb11f8004af..9a865f4a18b1d8822278a994ed87c0b558e34564 100644 (file)
@@ -1,3 +1,22 @@
+2020-07-22  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR ld/26262
+       PR ld/26267
+       * ldlang.c (lang_process): Set lto_all_symbols_read after all
+       LTO IR symbols have been read.
+       * plugin.c (plugin_notice): Override the IR definition only if
+       all LTO IR symbols have been read or the new definition is
+       non-weak and the the IR definition is weak
+       * testsuite/ld-plugin/lto.exp: Run PR ld/26262 and ld/26267
+       tests.
+       * testsuite/ld-plugin/pr26262a.c: New file.
+       * testsuite/ld-plugin/pr26262b.c: Likewise.
+       * testsuite/ld-plugin/pr26262c.c: Likewise.
+       * testsuite/ld-plugin/pr26267.err: Likewise.
+       * testsuite/ld-plugin/pr26267a.c: Likewise.
+       * testsuite/ld-plugin/pr26267b.c: Likewise.
+       * testsuite/ld-plugin/pr26267c.c: Likewise.
+
 2020-07-20  Nick Clifton  <nickc@redhat.com>
 
        * testsuite/ld-powerpc/powerpc.exp (ppcelftests): Use section name
index 23e787a3b22d0fa83ea7ec4245a4046865dc2bcc..9977195074a01da2cde264790fc95cd577e41ca8 100644 (file)
@@ -7874,6 +7874,7 @@ lang_process (void)
       if (plugin_call_all_symbols_read ())
        einfo (_("%F%P: %s: plugin reported error after all symbols read\n"),
               plugin_error_plugin ());
+      link_info.lto_all_symbols_read = TRUE;
       /* Open any newly added files, updating the file chains.  */
       plugin_undefs = link_info.hash->undefs_tail;
       open_input_bfds (*added.tail, OPEN_BFD_NORMAL);
index b455af6d6762321200f37a7103619271b99779b2..d709ee10fe74628cb5bd3a6b81bbf77884744970 100644 (file)
@@ -1433,12 +1433,16 @@ plugin_notice (struct bfd_link_info *info,
         new value from a real BFD.  Weak symbols are not normally
         overridden by a new weak definition, and strong symbols
         will normally cause multiple definition errors.  Avoid
-        this by making the symbol appear to be undefined.  */
-      else if (((h->type == bfd_link_hash_defweak
-                || h->type == bfd_link_hash_defined)
-               && is_ir_dummy_bfd (sym_bfd = h->u.def.section->owner))
-              || (h->type == bfd_link_hash_common
-                  && is_ir_dummy_bfd (sym_bfd = h->u.c.p->section->owner)))
+        this by making the symbol appear to be undefined.
+
+        NB: We change the previous definition in the IR object to
+        undefweak only after all LTO symbols have been read.  */
+      else if (info->lto_all_symbols_read
+              && (((h->type == bfd_link_hash_defweak
+                    || h->type == bfd_link_hash_defined)
+                   && is_ir_dummy_bfd (sym_bfd = h->u.def.section->owner))
+                  || (h->type == bfd_link_hash_common
+                      && is_ir_dummy_bfd (sym_bfd = h->u.c.p->section->owner))))
        {
          h->type = bfd_link_hash_undefweak;
          h->u.undef.abfd = sym_bfd;
index 2d6ca6888b4c1078c3a46349ea099d04413f3bfb..a44b6cf4b0d7de63490acbd3d901efa0fa3ee17c 100644 (file)
@@ -210,6 +210,36 @@ set lto_link_tests [list \
   [list "Build pr26163a.o" \
    "" "-O2 -fno-lto" \
    {pr26163a.c}] \
+  [list "Build pr26262b.o" \
+   "" "-O2" \
+   {pr26262b.c} {} "" "c"] \
+  [list "Build pr26262c.o" \
+   "" "-O2" \
+   {pr26262c.c} {} "" "c"] \
+  [list "Build pr26267a.o" \
+   "" "-O2 -flto $lto_no_fat" \
+   {pr26267a.c} {} "" "c"] \
+  [list "Build pr26267b.o" \
+   "" "-O2" \
+   {pr26267b.c} {} "" "c"] \
+  [list "Build pr26267c.o" \
+   "" "-O2" \
+   {pr26267c.c} {} "" "c"] \
+  [list "Build pr26267a" \
+   "" "-O2" \
+   {pr26267a.c} {} "" "c"] \
+  [list "Build pr26267a" \
+   "-flto tmpdir/pr26267a.o tmpdir/pr26267b.o tmpdir/pr26267c.o" \
+   "-flto $lto_no_fat" \
+   {dummy.c} \
+   {{error_output "pr26267.err"}} \
+   "pr26267a"] \
+  [list "Build pr26267b" \
+   "-flto tmpdir/pr26267b.o tmpdir/pr26267c.o tmpdir/pr26267a.o" \
+   "-flto $lto_no_fat" \
+   {dummy.c} \
+   {{error_output "pr26267.err"}} \
+   "pr26267b"] \
 ]
 
 if { [at_least_gcc_version 10 0] } {
@@ -510,6 +540,16 @@ set lto_run_tests [list \
    {pr26163b.c} "pr24406-2" "pass.out" \
    "-flto -O2" "c" "" \
    "tmpdir/pr26163a.o -Wl,--defsym,g=real_g"] \
+  [list "Run pr26262a" \
+   "-O2 -flto" "" \
+   {pr26262a.c} "pr26262a" "pass.out" \
+   "-flto -O2" "c" "" \
+   "tmpdir/pr26262b.o tmpdir/pr26262c.o"] \
+  [list "Run pr26262b" \
+   "-flto -O2 tmpdir/pr26262b.o tmpdir/pr26262c.o" "" \
+   {pr26262a.c} "pr26262b" "pass.out" \
+   "-flto -O2" "c" "" \
+   ""] \
 ]
 
 if { [at_least_gcc_version 4 7] } {
diff --git a/ld/testsuite/ld-plugin/pr26262a.c b/ld/testsuite/ld-plugin/pr26262a.c
new file mode 100644 (file)
index 0000000..488470f
--- /dev/null
@@ -0,0 +1,21 @@
+#include <stdio.h>
+
+int counter;
+extern void foo (void);
+extern void xxx (void);
+
+void
+bar (void)
+{
+}
+
+int
+main(void)
+{
+  bar ();
+  foo ();
+  xxx ();
+  if (counter == 1)
+    printf ("PASS\n");
+  return 0;
+}
diff --git a/ld/testsuite/ld-plugin/pr26262b.c b/ld/testsuite/ld-plugin/pr26262b.c
new file mode 100644 (file)
index 0000000..91ec492
--- /dev/null
@@ -0,0 +1,16 @@
+#include <stdlib.h>
+
+extern int counter;
+
+void
+foo (void)
+{
+  counter++;
+}
+
+__attribute__((weak))
+void
+bar (void)
+{
+  abort ();
+}
diff --git a/ld/testsuite/ld-plugin/pr26262c.c b/ld/testsuite/ld-plugin/pr26262c.c
new file mode 100644 (file)
index 0000000..fcc4941
--- /dev/null
@@ -0,0 +1,6 @@
+extern void bar (void);
+void
+xxx (void)
+{
+  bar ();
+}
diff --git a/ld/testsuite/ld-plugin/pr26267.err b/ld/testsuite/ld-plugin/pr26267.err
new file mode 100644 (file)
index 0000000..b1b1c3a
--- /dev/null
@@ -0,0 +1,3 @@
+#...
+.*: multiple definition of `bar'; .*
+#...
diff --git a/ld/testsuite/ld-plugin/pr26267a.c b/ld/testsuite/ld-plugin/pr26267a.c
new file mode 100644 (file)
index 0000000..488470f
--- /dev/null
@@ -0,0 +1,21 @@
+#include <stdio.h>
+
+int counter;
+extern void foo (void);
+extern void xxx (void);
+
+void
+bar (void)
+{
+}
+
+int
+main(void)
+{
+  bar ();
+  foo ();
+  xxx ();
+  if (counter == 1)
+    printf ("PASS\n");
+  return 0;
+}
diff --git a/ld/testsuite/ld-plugin/pr26267b.c b/ld/testsuite/ld-plugin/pr26267b.c
new file mode 100644 (file)
index 0000000..f1e32e2
--- /dev/null
@@ -0,0 +1,15 @@
+#include <stdlib.h>
+
+extern int counter;
+
+void
+foo (void)
+{
+  counter++;
+}
+
+void
+bar (void)
+{
+  abort ();
+}
diff --git a/ld/testsuite/ld-plugin/pr26267c.c b/ld/testsuite/ld-plugin/pr26267c.c
new file mode 100644 (file)
index 0000000..fcc4941
--- /dev/null
@@ -0,0 +1,6 @@
+extern void bar (void);
+void
+xxx (void)
+{
+  bar ();
+}