aboutsummaryrefslogtreecommitdiff
path: root/ld
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2022-04-25 10:51:39 -0700
committerH.J. Lu <hjl.tools@gmail.com>2022-05-04 16:26:51 -0700
commitda422fa49d508e33b8f1b2bd9b8f719b831b199b (patch)
tree197586145f0c372bad5abda8d2032fd9eaf6db63 /ld
parent40ae4abe44fa4e0a53d1681bc48adf445df25822 (diff)
downloadgdb-da422fa49d508e33b8f1b2bd9b8f719b831b199b.zip
gdb-da422fa49d508e33b8f1b2bd9b8f719b831b199b.tar.gz
gdb-da422fa49d508e33b8f1b2bd9b8f719b831b199b.tar.bz2
LTO: Handle __real_SYM reference in IR
When an IR symbol SYM is referenced in IR via __real_SYM, its resolution should be LDPR_PREVAILING_DEF, not PREVAILING_DEF_IRONLY, since LTO doesn't know that __real_SYM should be resolved by SYM. bfd/ PR ld/29086 * linker.c (bfd_wrapped_link_hash_lookup): Mark SYM is referenced via __real_SYM. include/ PR ld/29086 * bfdlink.h (bfd_link_hash_entry): Add ref_real. ld/ PR ld/29086 * plugin.c (get_symbols): Resolve SYM definition to LDPR_PREVAILING_DEF for __real_SYM reference. * testsuite/ld-plugin/lto.exp: Run PR ld/29086 test. * testsuite/ld-plugin/pr29086.c: New file.
Diffstat (limited to 'ld')
-rw-r--r--ld/plugin.c7
-rw-r--r--ld/testsuite/ld-plugin/lto.exp8
-rw-r--r--ld/testsuite/ld-plugin/pr29086.c19
3 files changed, 32 insertions, 2 deletions
diff --git a/ld/plugin.c b/ld/plugin.c
index 6db52d1..fe20310 100644
--- a/ld/plugin.c
+++ b/ld/plugin.c
@@ -863,8 +863,11 @@ get_symbols (const void *handle, int nsyms, struct ld_plugin_symbol *syms,
/* We need to know if the sym is referenced from non-IR files. Or
even potentially-referenced, perhaps in a future final link if
this is a partial one, perhaps dynamically at load-time if the
- symbol is externally visible. Also check for wrapper symbol. */
- if (blhe->non_ir_ref_regular || wrap_status == wrapper)
+ symbol is externally visible. Also check for __real_SYM
+ reference and wrapper symbol. */
+ if (blhe->non_ir_ref_regular
+ || blhe->ref_real
+ || wrap_status == wrapper)
res = LDPR_PREVAILING_DEF;
else if (wrap_status == wrapped)
res = LDPR_RESOLVED_IR;
diff --git a/ld/testsuite/ld-plugin/lto.exp b/ld/testsuite/ld-plugin/lto.exp
index f4ea1d4..4e8e2dc 100644
--- a/ld/testsuite/ld-plugin/lto.exp
+++ b/ld/testsuite/ld-plugin/lto.exp
@@ -522,6 +522,14 @@ set lto_link_elf_tests [list \
{{"nm" {-D} "pr28849.d"}} \
"pr28849" \
] \
+ [list \
+ "PR ld/pr29086" \
+ "-Wl,--wrap=foo" \
+ "-O0 -flto" \
+ {pr29086.c} \
+ {} \
+ "pr29086" \
+ ] \
]
# PR 14918 checks that libgcc is not spuriously included in a shared link of
diff --git a/ld/testsuite/ld-plugin/pr29086.c b/ld/testsuite/ld-plugin/pr29086.c
new file mode 100644
index 0000000..d333d68
--- /dev/null
+++ b/ld/testsuite/ld-plugin/pr29086.c
@@ -0,0 +1,19 @@
+int
+foo (void)
+{
+ return 0;
+}
+
+int
+main ()
+{
+ return foo ();
+}
+
+extern int __real_foo (void);
+
+int
+__wrap_foo (void)
+{
+ return __real_foo ();
+}