aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ChangeLog7
-rw-r--r--bfd/elfxx-x86.c12
-rw-r--r--ld/ChangeLog9
-rw-r--r--ld/testsuite/ld-i386/i386.exp2
-rw-r--r--ld/testsuite/ld-i386/pr27998a.d7
-rw-r--r--ld/testsuite/ld-i386/pr27998a.s22
-rw-r--r--ld/testsuite/ld-i386/pr27998b.d7
-rw-r--r--ld/testsuite/ld-i386/pr27998b.s20
8 files changed, 84 insertions, 2 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 5211e98..212fe33 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,5 +1,12 @@
2021-06-19 H.J. Lu <hongjiu.lu@intel.com>
+ PR ld/27998
+ * elfxx-x86.c (elf_x86_allocate_dynrelocs): Count PLT for GOTOFF
+ relocation against IFUNC symbols.
+ (_bfd_x86_elf_adjust_dynamic_symbol): Likewise.
+
+2021-06-19 H.J. Lu <hongjiu.lu@intel.com>
+
* elflink.c (bfd_elf_final_link): Correct DT_TEXTREL warning in
PDE.
diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c
index 62d516a..088f6e5 100644
--- a/bfd/elfxx-x86.c
+++ b/bfd/elfxx-x86.c
@@ -131,6 +131,10 @@ elf_x86_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
if (h->type == STT_GNU_IFUNC
&& h->def_regular)
{
+ /* GOTOFF relocation needs PLT. */
+ if (eh->gotoff_ref)
+ h->plt.refcount = 1;
+
if (_bfd_elf_allocate_ifunc_dyn_relocs (info, h, &h->dyn_relocs,
plt_entry_size,
(htab->plt.has_plt0
@@ -1818,6 +1822,8 @@ _bfd_x86_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
const struct elf_backend_data *bed
= get_elf_backend_data (info->output_bfd);
+ eh = (struct elf_x86_link_hash_entry *) h;
+
/* STT_GNU_IFUNC symbol must go through PLT. */
if (h->type == STT_GNU_IFUNC)
{
@@ -1856,6 +1862,10 @@ _bfd_x86_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
h->plt.refcount += 1;
}
}
+
+ /* GOTOFF relocation needs PLT. */
+ if (eh->gotoff_ref)
+ h->plt.refcount = 1;
}
if (h->plt.refcount <= 0)
@@ -1896,8 +1906,6 @@ _bfd_x86_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
the link may change h->type. So fix it now. */
h->plt.offset = (bfd_vma) -1;
- eh = (struct elf_x86_link_hash_entry *) h;
-
/* If this is a weak symbol, and there is a real definition, the
processor independent code will have arranged for us to see the
real definition first, and we can just use the same value. */
diff --git a/ld/ChangeLog b/ld/ChangeLog
index 36f8d4b..dc08ec9 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,5 +1,14 @@
2021-06-19 H.J. Lu <hongjiu.lu@intel.com>
+ PR ld/27998
+ * testsuite/ld-i386/i386.exp: Run PR ld/27998 tests.
+ * testsuite/ld-i386/pr27998a.d: New file.
+ * testsuite/ld-i386/pr27998a.s: Likewise.
+ * testsuite/ld-i386/pr27998b.d: Likewise.
+ * testsuite/ld-i386/pr27998b.s: Likewise.
+
+2021-06-19 H.J. Lu <hongjiu.lu@intel.com>
+
* testsuite/ld-x86-64/textrel-1.err: New file.
* testsuite/ld-x86-64/textrel-1a.s: Likewise.
* testsuite/ld-x86-64/textrel-1b.s: Likewise.
diff --git a/ld/testsuite/ld-i386/i386.exp b/ld/testsuite/ld-i386/i386.exp
index 3d6047b..ceb6000 100644
--- a/ld/testsuite/ld-i386/i386.exp
+++ b/ld/testsuite/ld-i386/i386.exp
@@ -519,6 +519,8 @@ run_dump_test "pr19939a"
run_dump_test "pr19939b"
run_dump_test "tlsdesc2"
run_dump_test "report-reloc-1"
+run_dump_test "pr27998a"
+run_dump_test "pr27998b"
proc undefined_weak {cflags ldflags} {
set testname "Undefined weak symbol"
diff --git a/ld/testsuite/ld-i386/pr27998a.d b/ld/testsuite/ld-i386/pr27998a.d
new file mode 100644
index 0000000..ca3c920
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr27998a.d
@@ -0,0 +1,7 @@
+#as: --32
+#ld: -shared -melf_i386
+#readelf: -r --wide
+
+Relocation section '.rel.plt' at offset 0x[0-9a-f]+ contains 1 entry:
+ Offset Info Type Sym. Value Symbol's Name
+[0-9a-f]+ +[0-9a-f]+ +R_386_IRELATIVE +
diff --git a/ld/testsuite/ld-i386/pr27998a.s b/ld/testsuite/ld-i386/pr27998a.s
new file mode 100644
index 0000000..ec55cd6
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr27998a.s
@@ -0,0 +1,22 @@
+ .text
+ .p2align 4
+ .type my_foo, @function
+my_foo:
+ ret
+ .size my_foo, .-my_foo
+ .p2align 4
+ .type resolve_foo, @function
+resolve_foo:
+ leal my_foo@GOTOFF(%eax), %eax
+ ret
+ .size resolve_foo, .-resolve_foo
+ .globl foo
+ .hidden foo
+ .type foo, @gnu_indirect_function
+ .set foo,resolve_foo
+ .p2align 4
+ .globl bar
+ .type bar, @function
+bar:
+ leal foo@GOTOFF(%eax), %eax
+ ret
diff --git a/ld/testsuite/ld-i386/pr27998b.d b/ld/testsuite/ld-i386/pr27998b.d
new file mode 100644
index 0000000..ca3c920
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr27998b.d
@@ -0,0 +1,7 @@
+#as: --32
+#ld: -shared -melf_i386
+#readelf: -r --wide
+
+Relocation section '.rel.plt' at offset 0x[0-9a-f]+ contains 1 entry:
+ Offset Info Type Sym. Value Symbol's Name
+[0-9a-f]+ +[0-9a-f]+ +R_386_IRELATIVE +
diff --git a/ld/testsuite/ld-i386/pr27998b.s b/ld/testsuite/ld-i386/pr27998b.s
new file mode 100644
index 0000000..8b023e9
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr27998b.s
@@ -0,0 +1,20 @@
+ .text
+ .p2align 4
+ .type my_foo, @function
+my_foo:
+ ret
+ .size my_foo, .-my_foo
+ .p2align 4
+ .type resolve_foo, @function
+resolve_foo:
+ leal my_foo@GOTOFF(%eax), %eax
+ ret
+ .size resolve_foo, .-resolve_foo
+ .type foo, @gnu_indirect_function
+ .set foo,resolve_foo
+ .p2align 4
+ .globl bar
+ .type bar, @function
+bar:
+ leal foo@GOTOFF(%eax), %eax
+ ret