aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/ChangeLog6
-rw-r--r--include/bfdlink.h3
-rw-r--r--ld/ChangeLog19
-rw-r--r--ld/ldlang.c1
-rw-r--r--ld/plugin.c16
-rw-r--r--ld/testsuite/ld-plugin/lto.exp40
-rw-r--r--ld/testsuite/ld-plugin/pr26262a.c21
-rw-r--r--ld/testsuite/ld-plugin/pr26262b.c16
-rw-r--r--ld/testsuite/ld-plugin/pr26262c.c6
-rw-r--r--ld/testsuite/ld-plugin/pr26267.err3
-rw-r--r--ld/testsuite/ld-plugin/pr26267a.c21
-rw-r--r--ld/testsuite/ld-plugin/pr26267b.c15
-rw-r--r--ld/testsuite/ld-plugin/pr26267c.c6
13 files changed, 167 insertions, 6 deletions
diff --git a/include/ChangeLog b/include/ChangeLog
index 6a69a74..211d545 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -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-11 H.J. Lu <hongjiu.lu@intel.com>
* elf/common.h (GNU_PROPERTY_X86_FEATURE_2_TMM): New.
diff --git a/include/bfdlink.h b/include/bfdlink.h
index 7163433..3badfbdb 100644
--- a/include/bfdlink.h
+++ b/include/bfdlink.h
@@ -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;
diff --git a/ld/ChangeLog b/ld/ChangeLog
index c495128..aef3d97 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -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
diff --git a/ld/ldlang.c b/ld/ldlang.c
index 2b3a5f9..d3ed5d4 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -7886,6 +7886,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);
diff --git a/ld/plugin.c b/ld/plugin.c
index b455af6..d709ee1 100644
--- a/ld/plugin.c
+++ b/ld/plugin.c
@@ -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;
diff --git a/ld/testsuite/ld-plugin/lto.exp b/ld/testsuite/ld-plugin/lto.exp
index 2d6ca68..a44b6cf 100644
--- a/ld/testsuite/ld-plugin/lto.exp
+++ b/ld/testsuite/ld-plugin/lto.exp
@@ -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
index 0000000..488470f
--- /dev/null
+++ b/ld/testsuite/ld-plugin/pr26262a.c
@@ -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
index 0000000..91ec492
--- /dev/null
+++ b/ld/testsuite/ld-plugin/pr26262b.c
@@ -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
index 0000000..fcc4941
--- /dev/null
+++ b/ld/testsuite/ld-plugin/pr26262c.c
@@ -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
index 0000000..b1b1c3a
--- /dev/null
+++ b/ld/testsuite/ld-plugin/pr26267.err
@@ -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
index 0000000..488470f
--- /dev/null
+++ b/ld/testsuite/ld-plugin/pr26267a.c
@@ -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
index 0000000..f1e32e2
--- /dev/null
+++ b/ld/testsuite/ld-plugin/pr26267b.c
@@ -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
index 0000000..fcc4941
--- /dev/null
+++ b/ld/testsuite/ld-plugin/pr26267c.c
@@ -0,0 +1,6 @@
+extern void bar (void);
+void
+xxx (void)
+{
+ bar ();
+}