119 lines
3.4 KiB
Diff
119 lines
3.4 KiB
Diff
|
commit 14d96265dd8fd934d868c0b8e1991e2fefbe9fc8
|
||
|
Author: Will Newton <will.newton@linaro.org>
|
||
|
Date: Mon Nov 25 14:44:59 2013 +0000
|
||
|
|
||
|
bfd/elfnn-aarch64.c: Handle static links with ifunc correctly.
|
||
|
|
||
|
The code for handling GOT references to ifunc symbols in static links
|
||
|
was missing.
|
||
|
|
||
|
bfd/ChangeLog:
|
||
|
|
||
|
2013-11-26 Will Newton <will.newton@linaro.org>
|
||
|
|
||
|
* elfnn-aarch64.c (elfNN_aarch64_finish_dynamic_symbol):
|
||
|
Handle STT_GNU_IFUNC symbols correctly in static links.
|
||
|
|
||
|
ld/testsuite/ChangeLog:
|
||
|
|
||
|
2013-11-26 Will Newton <will.newton@linaro.org>
|
||
|
|
||
|
* ld-aarch64/aarch64-elf.exp: Add ifunc-22.
|
||
|
* ld-aarch64/ifunc-22.d: New file.
|
||
|
* ld-aarch64/ifunc-22.s: Likewise.
|
||
|
|
||
|
diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c
|
||
|
index 3cd3a18..9053635 100644
|
||
|
--- a/bfd/elfnn-aarch64.c
|
||
|
+++ b/bfd/elfnn-aarch64.c
|
||
|
@@ -6824,7 +6824,34 @@ elfNN_aarch64_finish_dynamic_symbol (bfd *output_bfd,
|
||
|
+ htab->root.sgot->output_offset
|
||
|
+ (h->got.offset & ~(bfd_vma) 1));
|
||
|
|
||
|
- if (info->shared && SYMBOL_REFERENCES_LOCAL (info, h))
|
||
|
+ if (h->def_regular
|
||
|
+ && h->type == STT_GNU_IFUNC)
|
||
|
+ {
|
||
|
+ if (info->shared)
|
||
|
+ {
|
||
|
+ /* Generate R_AARCH64_GLOB_DAT. */
|
||
|
+ goto do_glob_dat;
|
||
|
+ }
|
||
|
+ else
|
||
|
+ {
|
||
|
+ asection *plt;
|
||
|
+
|
||
|
+ if (!h->pointer_equality_needed)
|
||
|
+ abort ();
|
||
|
+
|
||
|
+ /* For non-shared object, we can't use .got.plt, which
|
||
|
+ contains the real function address if we need pointer
|
||
|
+ equality. We load the GOT entry with the PLT entry. */
|
||
|
+ plt = htab->root.splt ? htab->root.splt : htab->root.iplt;
|
||
|
+ bfd_put_NN (output_bfd, (plt->output_section->vma
|
||
|
+ + plt->output_offset
|
||
|
+ + h->plt.offset),
|
||
|
+ htab->root.sgot->contents
|
||
|
+ + (h->got.offset & ~(bfd_vma) 1));
|
||
|
+ return TRUE;
|
||
|
+ }
|
||
|
+ }
|
||
|
+ else if (info->shared && SYMBOL_REFERENCES_LOCAL (info, h))
|
||
|
{
|
||
|
if (!h->def_regular)
|
||
|
return FALSE;
|
||
|
@@ -6837,6 +6864,7 @@ elfNN_aarch64_finish_dynamic_symbol (bfd *output_bfd,
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
+do_glob_dat:
|
||
|
BFD_ASSERT ((h->got.offset & 1) == 0);
|
||
|
bfd_put_NN (output_bfd, (bfd_vma) 0,
|
||
|
htab->root.sgot->contents + h->got.offset);
|
||
|
diff --git a/ld/testsuite/ld-aarch64/aarch64-elf.exp b/ld/testsuite/ld-aarch64/aarch64-elf.exp
|
||
|
index a6b3ea2..692bf34 100644
|
||
|
--- a/ld/testsuite/ld-aarch64/aarch64-elf.exp
|
||
|
+++ b/ld/testsuite/ld-aarch64/aarch64-elf.exp
|
||
|
@@ -156,3 +156,4 @@ run_dump_test "ifunc-19a"
|
||
|
run_dump_test "ifunc-19b"
|
||
|
run_dump_test "ifunc-20"
|
||
|
run_dump_test "ifunc-21"
|
||
|
+run_dump_test "ifunc-22"
|
||
|
diff --git a/ld/testsuite/ld-aarch64/ifunc-22.d b/ld/testsuite/ld-aarch64/ifunc-22.d
|
||
|
new file mode 100644
|
||
|
index 0000000..f28b039
|
||
|
--- /dev/null
|
||
|
+++ b/ld/testsuite/ld-aarch64/ifunc-22.d
|
||
|
@@ -0,0 +1,11 @@
|
||
|
+#source: ifunc-22.s
|
||
|
+#objdump: -s -j .got
|
||
|
+#ld: -static
|
||
|
+#target: aarch64*-*-*
|
||
|
+
|
||
|
+# Ensure GOT is populated correctly in static link
|
||
|
+
|
||
|
+.*: file format elf64-(little|big)aarch64
|
||
|
+
|
||
|
+Contents of section \.got:
|
||
|
+ 4100f0 00000000 00000000 d0004000 00000000 ..........@.....
|
||
|
diff --git a/ld/testsuite/ld-aarch64/ifunc-22.s b/ld/testsuite/ld-aarch64/ifunc-22.s
|
||
|
new file mode 100644
|
||
|
index 0000000..69a87bb
|
||
|
--- /dev/null
|
||
|
+++ b/ld/testsuite/ld-aarch64/ifunc-22.s
|
||
|
@@ -0,0 +1,14 @@
|
||
|
+ .text
|
||
|
+ .type ifunc, @gnu_indirect_function
|
||
|
+ .global ifunc
|
||
|
+ifunc:
|
||
|
+ ret
|
||
|
+ .size ifunc, .-ifunc
|
||
|
+ .type _start, @function
|
||
|
+ .globl _start
|
||
|
+_start:
|
||
|
+ adrp x0, :got:ifunc
|
||
|
+ ldr x0, [x0, #:got_lo12:ifunc]
|
||
|
+ .size _start, .-_start
|
||
|
+ .data
|
||
|
+ .xword ifunc
|