aboutsummaryrefslogtreecommitdiff
path: root/ld
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2024-04-04 18:46:40 -0700
committerH.J. Lu <hjl.tools@gmail.com>2024-04-05 05:02:38 -0700
commitc0419c024bf922128131671e40de0aed736e38ed (patch)
treed3d57c0080c27f60f9505c90f80c30e0c2e8bb3b /ld
parenteac88f3298491fdf2caa0d7dd97a3dde954b8b74 (diff)
downloadgdb-c0419c024bf922128131671e40de0aed736e38ed.zip
gdb-c0419c024bf922128131671e40de0aed736e38ed.tar.gz
gdb-c0419c024bf922128131671e40de0aed736e38ed.tar.bz2
elf: Always honor the first definition in shared object and archive
GCC doesn't put builtin function symbol references, which are defined in the shared C library, in the IR symbol table. When linker rescans shared objects and archives for newly added symbol references generated from the IR inputs, it skips definitions of the builtin functions in shared objects and archives. Add first_hash to elf_link_hash_table to track unreferenced definitions defined first in shared objects and archives. Always use them to resolve any references. bfd/ PR ld/31482 PR ld/31489 * elf-bfd.h (elf_link_hash_table): Add first_hash. * elflink.c (elf_link_add_to_first_hash): New function. (elf_link_add_object_symbols): Initialize first_hash for an IR input. Always use the first definition in shared object. Add the first unreferenced dynamic definition to first_hash. (_bfd_elf_archive_symbol_lookup): Add the first unreferenced definition to first_hash.. (elf_link_add_archive_symbols): Use the symbol definition in archive if symbol is defined first in this archive. (_bfd_elf_link_hash_table_free): Also free first_hash. ld/ PR ld/31482 PR ld/31489 * testsuite/ld-plugin/lto.exp: Add PR ld/31482 and PR ld/31489 tests. * testsuite/ld-elf/pr31482a-no-lto.c: New file. * testsuite/ld-elf/pr31482b-no-lto.c: Likewise. * testsuite/ld-elf/pr31482c-no-lto.c: Likewise. * testsuite/ld-elf/pr31482d-no-lto.c: Likewise. * testsuite/ld-plugin/pass1.out: Likewise. * testsuite/ld-plugin/pr31482a.c: Likewise. * testsuite/ld-plugin/pr31482b.c: Likewise. * testsuite/ld-plugin/pr31482c.c: Likewise.
Diffstat (limited to 'ld')
-rw-r--r--ld/testsuite/ld-elf/pr31482a-no-lto.c8
-rw-r--r--ld/testsuite/ld-elf/pr31482b-no-lto.c10
-rw-r--r--ld/testsuite/ld-elf/pr31482c-no-lto.c15
-rw-r--r--ld/testsuite/ld-elf/pr31482d-no-lto.c9
-rw-r--r--ld/testsuite/ld-elf/shared.exp36
-rw-r--r--ld/testsuite/ld-plugin/lto.exp32
-rw-r--r--ld/testsuite/ld-plugin/pass1.out1
-rw-r--r--ld/testsuite/ld-plugin/pr31482a.c8
-rw-r--r--ld/testsuite/ld-plugin/pr31482b.c9
-rw-r--r--ld/testsuite/ld-plugin/pr31482c.c9
10 files changed, 137 insertions, 0 deletions
diff --git a/ld/testsuite/ld-elf/pr31482a-no-lto.c b/ld/testsuite/ld-elf/pr31482a-no-lto.c
new file mode 100644
index 0000000..abc23be
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr31482a-no-lto.c
@@ -0,0 +1,8 @@
+extern void foo (void);
+
+int
+main()
+{
+ foo ();
+ return 0;
+}
diff --git a/ld/testsuite/ld-elf/pr31482b-no-lto.c b/ld/testsuite/ld-elf/pr31482b-no-lto.c
new file mode 100644
index 0000000..f88254d
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr31482b-no-lto.c
@@ -0,0 +1,10 @@
+void
+func (void)
+{
+}
+
+void
+bar (void)
+{
+ func ();
+}
diff --git a/ld/testsuite/ld-elf/pr31482c-no-lto.c b/ld/testsuite/ld-elf/pr31482c-no-lto.c
new file mode 100644
index 0000000..bf326dd
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr31482c-no-lto.c
@@ -0,0 +1,15 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+void
+abort (void)
+{
+ printf ("PASS\n");
+ exit (0);
+}
+
+void
+foo (void)
+{
+ abort ();
+}
diff --git a/ld/testsuite/ld-elf/pr31482d-no-lto.c b/ld/testsuite/ld-elf/pr31482d-no-lto.c
new file mode 100644
index 0000000..7cdaff0
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr31482d-no-lto.c
@@ -0,0 +1,9 @@
+void
+func (void)
+{
+}
+
+void
+foo (void)
+{
+}
diff --git a/ld/testsuite/ld-elf/shared.exp b/ld/testsuite/ld-elf/shared.exp
index 277dc7b..9e89077 100644
--- a/ld/testsuite/ld-elf/shared.exp
+++ b/ld/testsuite/ld-elf/shared.exp
@@ -912,6 +912,30 @@ run_cc_link_tests [list \
{{readelf {--dyn-syms --wide} pr28348.rd}} \
"pr28348" \
] \
+ [list \
+ "Build pr31482b-no-lto.so" \
+ "-shared" \
+ "-fPIC" \
+ {pr31482b-no-lto.c} \
+ {} \
+ "pr31482b-no-lto.so" \
+ ] \
+ [list \
+ "Build pr31482c-no-lto.a" \
+ "" \
+ "" \
+ {pr31482c-no-lto.c} \
+ {} \
+ "pr31482c-no-lto.a" \
+ ] \
+ [list \
+ "Build pr31482d-no-lto.a" \
+ "" \
+ "" \
+ {pr31482d-no-lto.c} \
+ {} \
+ "pr31482d-no-lto.a" \
+ ] \
]
# pr19073.s uses .set, which has a different meaning on alpha.
@@ -1165,6 +1189,18 @@ set run_tests [list \
"" "" \
{pr26590c.c pr26590d.c} "pr26590" "pass.out" "" "c" "" \
"-Wl,--as-needed tmpdir/libpr26590a.so tmpdir/libpr26590b.so" ] \
+ [list "Run pr31482 (no-lto)" \
+ "-Wl,--no-as-needed" \
+ "" \
+ {pr31482a-no-lto.c} \
+ "pr31482-no-lto" \
+ "pass.out" \
+ "" \
+ "c" \
+ "" \
+ "tmpdir/pr31482b-no-lto.so tmpdir/pr31482c-no-lto.a \
+ tmpdir/pr31482d-no-lto.a" \
+ ] \
]
# NetBSD ELF systems do not currently support the .*_array sections.
diff --git a/ld/testsuite/ld-plugin/lto.exp b/ld/testsuite/ld-plugin/lto.exp
index 259a064..b56d71a 100644
--- a/ld/testsuite/ld-plugin/lto.exp
+++ b/ld/testsuite/ld-plugin/lto.exp
@@ -539,6 +539,22 @@ set lto_link_elf_tests [list \
"" \
"pr30281.so" \
] \
+ [list \
+ "Build pr31482b.a" \
+ "" \
+ "" \
+ {pr31482b.c} \
+ "" \
+ "pr31482b.a" \
+ ] \
+ [list \
+ "Build pr31482c.so" \
+ "-shared" \
+ "-fPIC" \
+ {pr31482c.c} \
+ "" \
+ "pr31482c.so" \
+ ] \
]
# PR 14918 checks that libgcc is not spuriously included in a shared link of
@@ -722,6 +738,22 @@ set lto_run_elf_shared_tests [list \
{-Wl,--as-needed,-R,tmpdir} {} \
{lto-19c.c} {lto-19.exe} {pass.out} {-flto -O2} {c} {} \
{tmpdir/liblto-19.so tmpdir/liblto-19.a}] \
+ [list {pr31482a} \
+ {-Wl,--no-as-needed,-R,tmpdir} {} \
+ {pr31482a.c} {pr31482a.exe} {pass.out} {-flto} {c} {} \
+ {tmpdir/pr31482b.a tmpdir/pr31482c.so}] \
+ [list {pr31482b} \
+ {-Wl,--no-as-needed,-R,tmpdir} {} \
+ {pr31482a.c} {pr31482b.exe} {pass1.out} {-flto} {c} {} \
+ {tmpdir/pr31482c.so tmpdir/pr31482b.a}] \
+ [list {pr31489a} \
+ {-Wl,--as-needed,-R,tmpdir} {} \
+ {pr31482a.c} {pr31489a.exe} {pass.out} {-flto} {c} {} \
+ {tmpdir/pr31482b.a tmpdir/pr31482c.so}] \
+ [list {pr31489b} \
+ {-Wl,--as-needed,-R,tmpdir} {} \
+ {pr31482a.c} {pr31489b.exe} {pass1.out} {-flto} {c} {} \
+ {tmpdir/pr31482c.so tmpdir/pr31482b.a}] \
]
# LTO run-time tests for ELF
diff --git a/ld/testsuite/ld-plugin/pass1.out b/ld/testsuite/ld-plugin/pass1.out
new file mode 100644
index 0000000..8e5c818
--- /dev/null
+++ b/ld/testsuite/ld-plugin/pass1.out
@@ -0,0 +1 @@
+PASS1
diff --git a/ld/testsuite/ld-plugin/pr31482a.c b/ld/testsuite/ld-plugin/pr31482a.c
new file mode 100644
index 0000000..0693e47
--- /dev/null
+++ b/ld/testsuite/ld-plugin/pr31482a.c
@@ -0,0 +1,8 @@
+#include <stdlib.h>
+
+int
+main()
+{
+ abort ();
+ return 0;
+}
diff --git a/ld/testsuite/ld-plugin/pr31482b.c b/ld/testsuite/ld-plugin/pr31482b.c
new file mode 100644
index 0000000..3c24173
--- /dev/null
+++ b/ld/testsuite/ld-plugin/pr31482b.c
@@ -0,0 +1,9 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+void
+abort (void)
+{
+ printf ("PASS\n");
+ exit (0);
+}
diff --git a/ld/testsuite/ld-plugin/pr31482c.c b/ld/testsuite/ld-plugin/pr31482c.c
new file mode 100644
index 0000000..5c3b509
--- /dev/null
+++ b/ld/testsuite/ld-plugin/pr31482c.c
@@ -0,0 +1,9 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+void
+abort (void)
+{
+ printf ("PASS1\n");
+ exit (0);
+}