[binutils-gdb] lto: Set resolution to LDPR_PREVAILING_DEF for regular common symbol
"H.J. Lu via Binutils-cvs" <[email protected]>
| Newsgroups | gmane.comp.gnu.binutils.cvs |
|---|---|
| Message-ID | <[email protected]> |
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=163028070ec223bae0bf752b3a1385efb86e0539 commit 163028070ec223bae0bf752b3a1385efb86e0539 Author: H.J. Lu <[email protected]> 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 <[email protected]> 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