[binutils-gdb] lto: Set resolution to LDPR_PREVAILING_DEF for regular common symbol
H.J. Lu
hjl@sourceware.org
Fri Aug 28 06:29:17 GMT 2026
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=163028070ec223bae0bf752b3a1385efb86e0539
commit 163028070ec223bae0bf752b3a1385efb86e0539
Author: H.J. Lu <hjl.tools@gmail.com>
Date: Thu Aug 27 15:49:08 2026 +0800
lto: Set resolution to LDPR_PREVAILING_DEF for regular common symbol
Since size or alignment of common symbol may be overridden by another
common symbol, set symbol resolution to LDPR_PREVAILING_DEF, instead of
LDPR_RESOLVED_EXEC, for common symbol in regular object when seeing an
undefined or common symbol from an IR object.
PR ld/34570
* plugin.c (get_symbols): Set resolution to LDPR_PREVAILING_DEF
for common symbol in regular object.
* testsuite/ld-plugin/pr34570a.c: New file.
* testsuite/ld-plugin/pr34570a.d: Likewise.
* testsuite/ld-plugin/pr34570b.c: Likewise.
* testsuite/ld-plugin/pr34570b.d: Likewise.
* testsuite/ld-plugin/pr34570c.c: Likewise.
* testsuite/ld-plugin/pr34570c.d: Likewise.
Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
Diff:
---
ld/plugin.c | 4 +--
ld/testsuite/ld-plugin/lto.exp | 67 +++++++++++++++++++++++++++++++++++++++
ld/testsuite/ld-plugin/pr34570a.c | 9 ++++++
ld/testsuite/ld-plugin/pr34570a.d | 6 ++++
ld/testsuite/ld-plugin/pr34570b.c | 1 +
ld/testsuite/ld-plugin/pr34570b.d | 6 ++++
ld/testsuite/ld-plugin/pr34570c.c | 9 ++++++
ld/testsuite/ld-plugin/pr34570c.d | 6 ++++
8 files changed, 106 insertions(+), 2 deletions(-)
diff --git a/ld/plugin.c b/ld/plugin.c
index 1cf5c915b00..30066b2a318 100644
--- a/ld/plugin.c
+++ b/ld/plugin.c
@@ -860,6 +860,8 @@ get_symbols (const void *handle, int nsyms, struct ld_plugin_symbol *syms,
else if (owner_sec->owner != NULL
&& (owner_sec->owner->flags & DYNAMIC) != 0)
res = LDPR_RESOLVED_DYN;
+ else if (blhe->type == bfd_link_hash_common)
+ res = LDPR_PREVAILING_DEF;
else
res = LDPR_RESOLVED_EXEC;
}
@@ -871,8 +873,6 @@ get_symbols (const void *handle, int nsyms, struct ld_plugin_symbol *syms,
res = LDPR_PREEMPTED_REG;
else if (owner_sec->owner == abfd)
res = LDPR_PREVAILING_DEF_IRONLY;
-
- /* Was originally def, weakdef, or common, but has been pre-empted. */
else if (is_ir_dummy_bfd (owner_sec->owner))
res = LDPR_PREEMPTED_IR;
else
diff --git a/ld/testsuite/ld-plugin/lto.exp b/ld/testsuite/ld-plugin/lto.exp
index 1e3fe182e14..8ad341293b5 100644
--- a/ld/testsuite/ld-plugin/lto.exp
+++ b/ld/testsuite/ld-plugin/lto.exp
@@ -275,6 +275,73 @@ set lto_link_tests [list \
{} \
"libcommon-2.a" \
] \
+ [list \
+ "Build pr34570a.exe" \
+ "-flto" \
+ "-flto -fcommon" \
+ {pr34570a.c pr34570b.c} \
+ {{readelf {-s --wide} pr34570a.d}} \
+ "pr34570a.exe" \
+ ] \
+ [list \
+ "Build pr34570b.exe" \
+ "-flto" \
+ "-flto -fcommon" \
+ {pr34570b.c pr34570a.c} \
+ {{readelf {-s --wide} pr34570a.d}} \
+ "pr34570b.exe" \
+ ] \
+ [list \
+ "Build pr34570a.o" \
+ "" \
+ "-O2 -fcommon -flto $lto_no_fat" \
+ {pr34570a.c} \
+ {} \
+ "" \
+ "c" \
+ ] \
+ [list \
+ "Build pr34570b.o" \
+ "" \
+ "-O2 -fcommon -fno-lto" \
+ {pr34570b.c} \
+ {} \
+ "" \
+ "c" \
+ ] \
+ [list \
+ "Build pr34570c.o" \
+ "" \
+ "-O2 -fcommon -flto $lto_no_fat" \
+ {pr34570c.c} \
+ {} \
+ "" \
+ "c" \
+ ] \
+ [list \
+ "Build pr34570c.exe" \
+ "-flto tmpdir/pr34570a.o tmpdir/pr34570b.o" \
+ "" \
+ {dummy.c} \
+ {{readelf {-s --wide} pr34570b.d}} \
+ "pr34570c.exe" \
+ ] \
+ [list \
+ "Build pr34570d.exe" \
+ "-flto tmpdir/pr34570b.o tmpdir/pr34570a.o" \
+ "" \
+ {dummy.c} \
+ {{readelf {-s --wide} pr34570b.d}} \
+ "pr34570d.exe" \
+ ] \
+ [list \
+ "Build pr34570e.exe" \
+ "-flto tmpdir/pr34570c.o tmpdir/pr34570b.o" \
+ "-flto -fcommon" \
+ {dummy.c} \
+ {{readelf {-s --wide} pr34570c.d}} \
+ "pr34570e.exe" \
+ ] \
]
if { [at_least_gcc_version 10 0] && [check_lto_shared_available] } {
diff --git a/ld/testsuite/ld-plugin/pr34570a.c b/ld/testsuite/ld-plugin/pr34570a.c
new file mode 100644
index 00000000000..d3ad433e52f
--- /dev/null
+++ b/ld/testsuite/ld-plugin/pr34570a.c
@@ -0,0 +1,9 @@
+#include <stdint.h>
+
+char foo[8];
+
+int
+main ()
+{
+ return (uintptr_t) &foo == 0x12345678 ? 0 : 1;
+}
diff --git a/ld/testsuite/ld-plugin/pr34570a.d b/ld/testsuite/ld-plugin/pr34570a.d
new file mode 100644
index 00000000000..6bbc399bf77
--- /dev/null
+++ b/ld/testsuite/ld-plugin/pr34570a.d
@@ -0,0 +1,6 @@
+#...
+Symbol table '\.symtab' contains [0-9]+ entries:
+ +Num: +Value +Size Type +Bind +Vis +Ndx Name
+#...
+ +[0-9]+: +[0-9a-f]+ +8 +OBJECT +LOCAL +DEFAULT .*[0-9]+ _?foo
+#pass
diff --git a/ld/testsuite/ld-plugin/pr34570b.c b/ld/testsuite/ld-plugin/pr34570b.c
new file mode 100644
index 00000000000..e308af97111
--- /dev/null
+++ b/ld/testsuite/ld-plugin/pr34570b.c
@@ -0,0 +1 @@
+char foo[1];
diff --git a/ld/testsuite/ld-plugin/pr34570b.d b/ld/testsuite/ld-plugin/pr34570b.d
new file mode 100644
index 00000000000..39d9d7315cb
--- /dev/null
+++ b/ld/testsuite/ld-plugin/pr34570b.d
@@ -0,0 +1,6 @@
+#...
+Symbol table '\.symtab' contains [0-9]+ entries:
+ +Num: +Value +Size Type +Bind +Vis +Ndx Name
+#...
+ +[0-9]+: +[0-9a-f]+ +8 +OBJECT +GLOBAL +DEFAULT .*[0-9]+ _?foo
+#pass
diff --git a/ld/testsuite/ld-plugin/pr34570c.c b/ld/testsuite/ld-plugin/pr34570c.c
new file mode 100644
index 00000000000..ae3ce725e34
--- /dev/null
+++ b/ld/testsuite/ld-plugin/pr34570c.c
@@ -0,0 +1,9 @@
+#include <stdint.h>
+
+extern char foo[];
+
+int
+main ()
+{
+ return (uintptr_t) &foo == 0x12345678 ? 0 : 1;
+}
diff --git a/ld/testsuite/ld-plugin/pr34570c.d b/ld/testsuite/ld-plugin/pr34570c.d
new file mode 100644
index 00000000000..c512064fbeb
--- /dev/null
+++ b/ld/testsuite/ld-plugin/pr34570c.d
@@ -0,0 +1,6 @@
+#...
+Symbol table '\.symtab' contains [0-9]+ entries:
+ +Num: +Value +Size Type +Bind +Vis +Ndx Name
+#...
+ +[0-9]+: +[0-9a-f]+ +1 +OBJECT +GLOBAL +DEFAULT .*[0-9]+ _?foo
+#pass
More information about the Binutils-cvs
mailing list