aboutsummaryrefslogtreecommitdiff
path: root/ld
diff options
context:
space:
mode:
authorWill Newton <willnewton@sourceware.org>2013-10-03 14:46:09 +0000
committerWill Newton <willnewton@sourceware.org>2013-10-03 14:46:09 +0000
commit1419bbe5712af8a43f1d63feb32687649563426d (patch)
treefe399164ce85dcdd317dc7b53c678074932a1fa9 /ld
parent06ab7b19e0f364881cd4b0ef67b2064dd83ee1c6 (diff)
downloadgdb-1419bbe5712af8a43f1d63feb32687649563426d.zip
gdb-1419bbe5712af8a43f1d63feb32687649563426d.tar.gz
gdb-1419bbe5712af8a43f1d63feb32687649563426d.tar.bz2
aarch64: Add support for GNU indirect functions.
Add support for STT_GNU_IFUNC symbols to the AArch64 bfd backend. The tests are ported from the ld-ifunc tests but are enabled for cross builds so can be run easily without hardware or a simulator. bfd/ChangeLog: 2013-10-03 Will Newton <will.newton@linaro.org> * configure: Regenerate. * configure.in: Build elf-ifunc.o for AArch64. * elfnn-aarch64.c: Include objalloc.h. (elfNN_aarch64_local_htab_hash): New function. (elfNN_aarch64_local_htab_eq): New function. (elfNN_aarch64_get_local_sym_hash): New function. (elfNN_aarch64_link_hash_table_create): Initialize local STT_GNU_IFUNC symbol hash. (elfNN_aarch64_hash_table_free): Free local STT_GNU_IFUNC symbol hash. (elfNN_aarch64_final_link_relocate): Add sym argument. Add support for handling STT_GNU_IFUNC symbols. (elfNN_aarch64_gc_sweep_hook): Add support for garbage collecting references to STT_GNU_IFUNC symbols. (elfNN_aarch64_adjust_dynamic_symbol): Add support for handling STT_GNU_IFUNC symbols. (elfNN_aarch64_check_relocs): Add support for handling STT_GNU_IFUNC symbols. Ensure we don't increase plt.refcount from -1 to 0. (elfNN_aarch64_post_process_headers): Call _bfd_elf_set_osabi. (elfNN_aarch64_is_function_type): Remove function. (elfNN_aarch64_allocate_dynrelocs): Handle STT_GNU_IFUNC symbols. (elfNN_aarch64_allocate_ifunc_dynrelocs): New function. (elfNN_aarch64_allocate_local_dynrelocs): New function. (elfNN_aarch64_allocate_local_ifunc_dynrelocs): New function. (elfNN_aarch64_size_dynamic_sections): Call elfNN_aarch64_allocate_local_dynrelocs. (elfNN_aarch64_create_small_pltn_entry): Add info argument. Add support for creating .iplt entries for STT_GNU_IFUNC symbols. (elfNN_aarch64_finish_dynamic_symbol): Add support for handling STT_GNU_IFUNC symbols and .iplt. (elfNN_aarch64_finish_local_dynamic_symbol): New function. (elfNN_aarch64_finish_dynamic_sections): Call elfNN_aarch64_finish_local_dynamic_symbol. ld/ChangeLog: 2013-10-03 Will Newton <will.newton@linaro.org> * emulparams/aarch64elf.sh: Add IREL_IN_PLT. * emulparams/aarch64elf32.sh: Likewise. ld/testsuite/ChangeLog: 2013-10-03 Will Newton <will.newton@linaro.org> * ld-ifunc/ifunc.exp: Enable ifunc tests for AArch64. * ld-aarch64/aarch64-elf.exp: Run ifunc tests. * ld-aarch64/ifunc-1-local.d: New file. * ld-aarch64/ifunc-1-local.s: Likewise. * ld-aarch64/ifunc-1.d: Likewise. * ld-aarch64/ifunc-1.s: Likewise. * ld-aarch64/ifunc-10.d: Likewise. * ld-aarch64/ifunc-10.s: Likewise. * ld-aarch64/ifunc-11.d: Likewise. * ld-aarch64/ifunc-11.s: Likewise. * ld-aarch64/ifunc-12.d: Likewise. * ld-aarch64/ifunc-12.s: Likewise. * ld-aarch64/ifunc-13.d: Likewise. * ld-aarch64/ifunc-13a.s: Likewise. * ld-aarch64/ifunc-13b.s: Likewise. * ld-aarch64/ifunc-14a.d: Likewise. * ld-aarch64/ifunc-14a.s: Likewise. * ld-aarch64/ifunc-14b.d: Likewise. * ld-aarch64/ifunc-14b.s: Likewise. * ld-aarch64/ifunc-14c.d: Likewise. * ld-aarch64/ifunc-14c.s: Likewise. * ld-aarch64/ifunc-14d.d: Likewise. * ld-aarch64/ifunc-14e.d: Likewise. * ld-aarch64/ifunc-14f.d: Likewise. * ld-aarch64/ifunc-15.d: Likewise. * ld-aarch64/ifunc-15.s: Likewise. * ld-aarch64/ifunc-16.d: Likewise. * ld-aarch64/ifunc-16.s: Likewise. * ld-aarch64/ifunc-17a.d: Likewise. * ld-aarch64/ifunc-17a.s: Likewise. * ld-aarch64/ifunc-17b.d: Likewise. * ld-aarch64/ifunc-17b.s: Likewise. * ld-aarch64/ifunc-18a.d: Likewise. * ld-aarch64/ifunc-18a.s: Likewise. * ld-aarch64/ifunc-18b.d: Likewise. * ld-aarch64/ifunc-18b.s: Likewise. * ld-aarch64/ifunc-19a.d: Likewise. * ld-aarch64/ifunc-19a.s: Likewise. * ld-aarch64/ifunc-19b.d: Likewise. * ld-aarch64/ifunc-19b.s: Likewise. * ld-aarch64/ifunc-2-local.d: Likewise. * ld-aarch64/ifunc-2-local.s: Likewise. * ld-aarch64/ifunc-2.d: Likewise. * ld-aarch64/ifunc-2.s: Likewise. * ld-aarch64/ifunc-20.d: Likewise. * ld-aarch64/ifunc-20.s: Likewise. * ld-aarch64/ifunc-3.s: Likewise. * ld-aarch64/ifunc-3a.d: Likewise. * ld-aarch64/ifunc-3b.d: Likewise. * ld-aarch64/ifunc-4.d: Likewise. * ld-aarch64/ifunc-4.s: Likewise. * ld-aarch64/ifunc-4a.d: Likewise. * ld-aarch64/ifunc-5-local.s: Likewise. * ld-aarch64/ifunc-5.s: Likewise. * ld-aarch64/ifunc-5a-local.d: Likewise. * ld-aarch64/ifunc-5a.d: Likewise. * ld-aarch64/ifunc-5b-local.d: Likewise. * ld-aarch64/ifunc-5b.d: Likewise. * ld-aarch64/ifunc-5r-local.d: Likewise. * ld-aarch64/ifunc-6.s: Likewise. * ld-aarch64/ifunc-6a.d: Likewise. * ld-aarch64/ifunc-6b.d: Likewise. * ld-aarch64/ifunc-7.s: Likewise. * ld-aarch64/ifunc-7a.d: Likewise. * ld-aarch64/ifunc-7b.d: Likewise. * ld-aarch64/ifunc-7c.d: Likewise. * ld-aarch64/ifunc-8.d: Likewise. * ld-aarch64/ifunc-8a.s: Likewise. * ld-aarch64/ifunc-8b.s: Likewise. * ld-aarch64/ifunc-9.d: Likewise. * ld-aarch64/ifunc-9.s: Likewise.
Diffstat (limited to 'ld')
-rw-r--r--ld/ChangeLog5
-rw-r--r--ld/emulparams/aarch64elf.sh1
-rw-r--r--ld/emulparams/aarch64elf32.sh1
-rw-r--r--ld/testsuite/ChangeLog74
-rw-r--r--ld/testsuite/ld-aarch64/aarch64-elf.exp41
-rw-r--r--ld/testsuite/ld-aarch64/ifunc-1-local.d7
-rw-r--r--ld/testsuite/ld-aarch64/ifunc-1-local.s13
-rw-r--r--ld/testsuite/ld-aarch64/ifunc-1.d7
-rw-r--r--ld/testsuite/ld-aarch64/ifunc-1.s16
-rw-r--r--ld/testsuite/ld-aarch64/ifunc-10.d5
-rw-r--r--ld/testsuite/ld-aarch64/ifunc-10.s25
-rw-r--r--ld/testsuite/ld-aarch64/ifunc-11.d5
-rw-r--r--ld/testsuite/ld-aarch64/ifunc-11.s26
-rw-r--r--ld/testsuite/ld-aarch64/ifunc-12.d5
-rw-r--r--ld/testsuite/ld-aarch64/ifunc-12.s24
-rw-r--r--ld/testsuite/ld-aarch64/ifunc-13.d13
-rw-r--r--ld/testsuite/ld-aarch64/ifunc-13a.s11
-rw-r--r--ld/testsuite/ld-aarch64/ifunc-13b.s5
-rw-r--r--ld/testsuite/ld-aarch64/ifunc-14a.d10
-rw-r--r--ld/testsuite/ld-aarch64/ifunc-14a.s7
-rw-r--r--ld/testsuite/ld-aarch64/ifunc-14b.d10
-rw-r--r--ld/testsuite/ld-aarch64/ifunc-14b.s5
-rw-r--r--ld/testsuite/ld-aarch64/ifunc-14c.d10
-rw-r--r--ld/testsuite/ld-aarch64/ifunc-14c.s7
-rw-r--r--ld/testsuite/ld-aarch64/ifunc-14d.d10
-rw-r--r--ld/testsuite/ld-aarch64/ifunc-14e.d11
-rw-r--r--ld/testsuite/ld-aarch64/ifunc-14f.d11
-rw-r--r--ld/testsuite/ld-aarch64/ifunc-15.d12
-rw-r--r--ld/testsuite/ld-aarch64/ifunc-15.s11
-rw-r--r--ld/testsuite/ld-aarch64/ifunc-16.d9
-rw-r--r--ld/testsuite/ld-aarch64/ifunc-16.s17
-rw-r--r--ld/testsuite/ld-aarch64/ifunc-17a.d9
-rw-r--r--ld/testsuite/ld-aarch64/ifunc-17a.s11
-rw-r--r--ld/testsuite/ld-aarch64/ifunc-17b.d9
-rw-r--r--ld/testsuite/ld-aarch64/ifunc-17b.s6
-rw-r--r--ld/testsuite/ld-aarch64/ifunc-18a.d14
-rw-r--r--ld/testsuite/ld-aarch64/ifunc-18a.s5
-rw-r--r--ld/testsuite/ld-aarch64/ifunc-18b.d14
-rw-r--r--ld/testsuite/ld-aarch64/ifunc-18b.s15
-rw-r--r--ld/testsuite/ld-aarch64/ifunc-19a.d13
-rw-r--r--ld/testsuite/ld-aarch64/ifunc-19a.s5
-rw-r--r--ld/testsuite/ld-aarch64/ifunc-19b.d13
-rw-r--r--ld/testsuite/ld-aarch64/ifunc-19b.s15
-rw-r--r--ld/testsuite/ld-aarch64/ifunc-2-local.d9
-rw-r--r--ld/testsuite/ld-aarch64/ifunc-2-local.s15
-rw-r--r--ld/testsuite/ld-aarch64/ifunc-2.d9
-rw-r--r--ld/testsuite/ld-aarch64/ifunc-2.s18
-rw-r--r--ld/testsuite/ld-aarch64/ifunc-20.d12
-rw-r--r--ld/testsuite/ld-aarch64/ifunc-20.s16
-rw-r--r--ld/testsuite/ld-aarch64/ifunc-3.s16
-rw-r--r--ld/testsuite/ld-aarch64/ifunc-3a.d8
-rw-r--r--ld/testsuite/ld-aarch64/ifunc-3b.d8
-rw-r--r--ld/testsuite/ld-aarch64/ifunc-4.d7
-rw-r--r--ld/testsuite/ld-aarch64/ifunc-4.s18
-rw-r--r--ld/testsuite/ld-aarch64/ifunc-4a.d8
-rw-r--r--ld/testsuite/ld-aarch64/ifunc-5-local.s19
-rw-r--r--ld/testsuite/ld-aarch64/ifunc-5.s20
-rw-r--r--ld/testsuite/ld-aarch64/ifunc-5a-local.d8
-rw-r--r--ld/testsuite/ld-aarch64/ifunc-5a.d8
-rw-r--r--ld/testsuite/ld-aarch64/ifunc-5b-local.d8
-rw-r--r--ld/testsuite/ld-aarch64/ifunc-5b.d12
-rw-r--r--ld/testsuite/ld-aarch64/ifunc-5r-local.d10
-rw-r--r--ld/testsuite/ld-aarch64/ifunc-6.s21
-rw-r--r--ld/testsuite/ld-aarch64/ifunc-6a.d8
-rw-r--r--ld/testsuite/ld-aarch64/ifunc-6b.d12
-rw-r--r--ld/testsuite/ld-aarch64/ifunc-7.s21
-rw-r--r--ld/testsuite/ld-aarch64/ifunc-7a.d8
-rw-r--r--ld/testsuite/ld-aarch64/ifunc-7b.d8
-rw-r--r--ld/testsuite/ld-aarch64/ifunc-7c.d19
-rw-r--r--ld/testsuite/ld-aarch64/ifunc-8.d9
-rw-r--r--ld/testsuite/ld-aarch64/ifunc-8a.s13
-rw-r--r--ld/testsuite/ld-aarch64/ifunc-8b.s7
-rw-r--r--ld/testsuite/ld-aarch64/ifunc-9.d3
-rw-r--r--ld/testsuite/ld-aarch64/ifunc-9.s23
-rw-r--r--ld/testsuite/ld-ifunc/ifunc.exp3
75 files changed, 926 insertions, 1 deletions
diff --git a/ld/ChangeLog b/ld/ChangeLog
index 87f8343..75f21fd 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,8 @@
+2013-10-03 Will Newton <will.newton@linaro.org>
+
+ * emulparams/aarch64elf.sh: Add IREL_IN_PLT.
+ * emulparams/aarch64elf32.sh: Likewise.
+
2013-09-30 Nick Clifton <nickc@redhat.com>
* emulparams/msp430all.sh: Update ARCH names.
diff --git a/ld/emulparams/aarch64elf.sh b/ld/emulparams/aarch64elf.sh
index 53ccd6a..6864d65 100644
--- a/ld/emulparams/aarch64elf.sh
+++ b/ld/emulparams/aarch64elf.sh
@@ -18,6 +18,7 @@ MAXPAGESIZE="CONSTANT (MAXPAGESIZE)"
ENTRY=_start
EMBEDDED=yes
SEPARATE_GOTPLT=24
+IREL_IN_PLT=
TEXT_START_ADDR=0x00400000
DATA_START_SYMBOLS='__data_start = . ;';
diff --git a/ld/emulparams/aarch64elf32.sh b/ld/emulparams/aarch64elf32.sh
index 5fe08e2..68a4d80 100644
--- a/ld/emulparams/aarch64elf32.sh
+++ b/ld/emulparams/aarch64elf32.sh
@@ -18,6 +18,7 @@ MAXPAGESIZE="CONSTANT (MAXPAGESIZE)"
ENTRY=_start
EMBEDDED=yes
SEPARATE_GOTPLT=24
+IREL_IN_PLT=
TEXT_START_ADDR=0x00400000
DATA_START_SYMBOLS='__data_start = . ;';
diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog
index da06c70..6beeb25 100644
--- a/ld/testsuite/ChangeLog
+++ b/ld/testsuite/ChangeLog
@@ -1,3 +1,77 @@
+2013-10-03 Will Newton <will.newton@linaro.org>
+
+ * ld-ifunc/ifunc.exp: Enable ifunc tests for AArch64.
+ * ld-aarch64/aarch64-elf.exp: Run ifunc tests.
+ * ld-aarch64/ifunc-1-local.d: New file.
+ * ld-aarch64/ifunc-1-local.s: Likewise.
+ * ld-aarch64/ifunc-1.d: Likewise.
+ * ld-aarch64/ifunc-1.s: Likewise.
+ * ld-aarch64/ifunc-10.d: Likewise.
+ * ld-aarch64/ifunc-10.s: Likewise.
+ * ld-aarch64/ifunc-11.d: Likewise.
+ * ld-aarch64/ifunc-11.s: Likewise.
+ * ld-aarch64/ifunc-12.d: Likewise.
+ * ld-aarch64/ifunc-12.s: Likewise.
+ * ld-aarch64/ifunc-13.d: Likewise.
+ * ld-aarch64/ifunc-13a.s: Likewise.
+ * ld-aarch64/ifunc-13b.s: Likewise.
+ * ld-aarch64/ifunc-14a.d: Likewise.
+ * ld-aarch64/ifunc-14a.s: Likewise.
+ * ld-aarch64/ifunc-14b.d: Likewise.
+ * ld-aarch64/ifunc-14b.s: Likewise.
+ * ld-aarch64/ifunc-14c.d: Likewise.
+ * ld-aarch64/ifunc-14c.s: Likewise.
+ * ld-aarch64/ifunc-14d.d: Likewise.
+ * ld-aarch64/ifunc-14e.d: Likewise.
+ * ld-aarch64/ifunc-14f.d: Likewise.
+ * ld-aarch64/ifunc-15.d: Likewise.
+ * ld-aarch64/ifunc-15.s: Likewise.
+ * ld-aarch64/ifunc-16.d: Likewise.
+ * ld-aarch64/ifunc-16.s: Likewise.
+ * ld-aarch64/ifunc-17a.d: Likewise.
+ * ld-aarch64/ifunc-17a.s: Likewise.
+ * ld-aarch64/ifunc-17b.d: Likewise.
+ * ld-aarch64/ifunc-17b.s: Likewise.
+ * ld-aarch64/ifunc-18a.d: Likewise.
+ * ld-aarch64/ifunc-18a.s: Likewise.
+ * ld-aarch64/ifunc-18b.d: Likewise.
+ * ld-aarch64/ifunc-18b.s: Likewise.
+ * ld-aarch64/ifunc-19a.d: Likewise.
+ * ld-aarch64/ifunc-19a.s: Likewise.
+ * ld-aarch64/ifunc-19b.d: Likewise.
+ * ld-aarch64/ifunc-19b.s: Likewise.
+ * ld-aarch64/ifunc-2-local.d: Likewise.
+ * ld-aarch64/ifunc-2-local.s: Likewise.
+ * ld-aarch64/ifunc-2.d: Likewise.
+ * ld-aarch64/ifunc-2.s: Likewise.
+ * ld-aarch64/ifunc-20.d: Likewise.
+ * ld-aarch64/ifunc-20.s: Likewise.
+ * ld-aarch64/ifunc-3.s: Likewise.
+ * ld-aarch64/ifunc-3a.d: Likewise.
+ * ld-aarch64/ifunc-3b.d: Likewise.
+ * ld-aarch64/ifunc-4.d: Likewise.
+ * ld-aarch64/ifunc-4.s: Likewise.
+ * ld-aarch64/ifunc-4a.d: Likewise.
+ * ld-aarch64/ifunc-5-local.s: Likewise.
+ * ld-aarch64/ifunc-5.s: Likewise.
+ * ld-aarch64/ifunc-5a-local.d: Likewise.
+ * ld-aarch64/ifunc-5a.d: Likewise.
+ * ld-aarch64/ifunc-5b-local.d: Likewise.
+ * ld-aarch64/ifunc-5b.d: Likewise.
+ * ld-aarch64/ifunc-5r-local.d: Likewise.
+ * ld-aarch64/ifunc-6.s: Likewise.
+ * ld-aarch64/ifunc-6a.d: Likewise.
+ * ld-aarch64/ifunc-6b.d: Likewise.
+ * ld-aarch64/ifunc-7.s: Likewise.
+ * ld-aarch64/ifunc-7a.d: Likewise.
+ * ld-aarch64/ifunc-7b.d: Likewise.
+ * ld-aarch64/ifunc-7c.d: Likewise.
+ * ld-aarch64/ifunc-8.d: Likewise.
+ * ld-aarch64/ifunc-8a.s: Likewise.
+ * ld-aarch64/ifunc-8b.s: Likewise.
+ * ld-aarch64/ifunc-9.d: Likewise.
+ * ld-aarch64/ifunc-9.s: Likewise.
+
2013-09-24 Gregory Fong <gregory.0xf0@gmail.com>
* ld-mips-elf/eh-frame5.d, ld-mips-elf/jalx-2.dd,
diff --git a/ld/testsuite/ld-aarch64/aarch64-elf.exp b/ld/testsuite/ld-aarch64/aarch64-elf.exp
index d687cc2..5c150dd 100644
--- a/ld/testsuite/ld-aarch64/aarch64-elf.exp
+++ b/ld/testsuite/ld-aarch64/aarch64-elf.exp
@@ -114,3 +114,44 @@ run_dump_test "gc-tls-relocs"
run_dump_test "gc-plt-relocs"
run_dump_test "gc-relocs-257-dyn"
run_dump_test "gc-relocs-257"
+
+# ifunc tests
+run_dump_test "ifunc-1"
+run_dump_test "ifunc-1-local"
+run_dump_test "ifunc-2"
+run_dump_test "ifunc-2-local"
+run_dump_test "ifunc-3a"
+run_dump_test "ifunc-3b"
+run_dump_test "ifunc-4"
+run_dump_test "ifunc-4a"
+run_dump_test "ifunc-5a"
+run_dump_test "ifunc-5b"
+run_dump_test "ifunc-5a-local"
+run_dump_test "ifunc-5b-local"
+run_dump_test "ifunc-5r-local"
+run_dump_test "ifunc-6a"
+run_dump_test "ifunc-6b"
+run_dump_test "ifunc-7a"
+run_dump_test "ifunc-7b"
+run_dump_test "ifunc-7c"
+run_dump_test "ifunc-8"
+run_dump_test "ifunc-9"
+run_dump_test "ifunc-10"
+run_dump_test "ifunc-11"
+run_dump_test "ifunc-12"
+run_dump_test "ifunc-13"
+run_dump_test "ifunc-14a"
+run_dump_test "ifunc-14b"
+run_dump_test "ifunc-14c"
+run_dump_test "ifunc-14d"
+run_dump_test "ifunc-14e"
+run_dump_test "ifunc-14f"
+run_dump_test "ifunc-15"
+run_dump_test "ifunc-16"
+run_dump_test "ifunc-17a"
+run_dump_test "ifunc-17b"
+run_dump_test "ifunc-18a"
+run_dump_test "ifunc-18b"
+run_dump_test "ifunc-19a"
+run_dump_test "ifunc-19b"
+run_dump_test "ifunc-20"
diff --git a/ld/testsuite/ld-aarch64/ifunc-1-local.d b/ld/testsuite/ld-aarch64/ifunc-1-local.d
new file mode 100644
index 0000000..0e307e0
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/ifunc-1-local.d
@@ -0,0 +1,7 @@
+#ld: -shared
+#objdump: -dw
+#target: aarch64*-*-*
+
+#...
+[ \t0-9a-f]+:[ \t0-9a-f]+bl[ \t0-9a-f]+<\*ABS\*\+(0x2a0|0x2f0)@plt>
+#pass
diff --git a/ld/testsuite/ld-aarch64/ifunc-1-local.s b/ld/testsuite/ld-aarch64/ifunc-1-local.s
new file mode 100644
index 0000000..7b9d117
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/ifunc-1-local.s
@@ -0,0 +1,13 @@
+ .type foo, %gnu_indirect_function
+ .set __GI_foo, foo
+ .text
+ .type foo, @function
+foo:
+ ret
+ .size foo, .-foo
+.globl bar
+ .type bar, @function
+bar:
+ bl __GI_foo
+ ret
+ .size bar, .-bar
diff --git a/ld/testsuite/ld-aarch64/ifunc-1.d b/ld/testsuite/ld-aarch64/ifunc-1.d
new file mode 100644
index 0000000..9e522c9
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/ifunc-1.d
@@ -0,0 +1,7 @@
+#ld: -shared
+#objdump: -dw
+#target: aarch64*-*-*
+
+#...
+[ \t0-9a-f]+:[ \t0-9a-f]+bl[ \t0-9a-f]+<\*ABS\*\+(0x2c0|0x308)@plt>
+#pass
diff --git a/ld/testsuite/ld-aarch64/ifunc-1.s b/ld/testsuite/ld-aarch64/ifunc-1.s
new file mode 100644
index 0000000..6f86c8a
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/ifunc-1.s
@@ -0,0 +1,16 @@
+ .type foo, %gnu_indirect_function
+ .global __GI_foo
+ .hidden __GI_foo
+ .set __GI_foo, foo
+ .text
+.globl foo
+ .type foo, @function
+foo:
+ ret
+ .size foo, .-foo
+.globl bar
+ .type bar, @function
+bar:
+ bl __GI_foo
+ ret
+ .size bar, .-bar
diff --git a/ld/testsuite/ld-aarch64/ifunc-10.d b/ld/testsuite/ld-aarch64/ifunc-10.d
new file mode 100644
index 0000000..782b078
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/ifunc-10.d
@@ -0,0 +1,5 @@
+#ld: -e bar --gc-sections
+#readelf: -r --wide
+#target: aarch64*-*-*
+
+There are no relocations in this file.
diff --git a/ld/testsuite/ld-aarch64/ifunc-10.s b/ld/testsuite/ld-aarch64/ifunc-10.s
new file mode 100644
index 0000000..10468c1
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/ifunc-10.s
@@ -0,0 +1,25 @@
+ .section .text.foo,"ax",@progbits
+ .type foo, @function
+foo:
+ .global foo
+ adrp x0, :got:ifunc
+ ldr x0, [x0, #:got_lo12:ifunc]
+ bl ifunc
+ adrp x0, xxx
+ add x0, x0, :lo12:xxx
+ ret
+
+ .section .text.bar,"ax",@progbits
+ .type bar, @function
+bar:
+ .global bar
+ ret
+
+ .section .text.ifunc,"ax",@progbits
+ .type ifunc, @gnu_indirect_function
+ifunc:
+ ret
+
+ .section .data.foo,"aw",@progbits
+xxx:
+ .quad ifunc
diff --git a/ld/testsuite/ld-aarch64/ifunc-11.d b/ld/testsuite/ld-aarch64/ifunc-11.d
new file mode 100644
index 0000000..782b078
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/ifunc-11.d
@@ -0,0 +1,5 @@
+#ld: -e bar --gc-sections
+#readelf: -r --wide
+#target: aarch64*-*-*
+
+There are no relocations in this file.
diff --git a/ld/testsuite/ld-aarch64/ifunc-11.s b/ld/testsuite/ld-aarch64/ifunc-11.s
new file mode 100644
index 0000000..e1820de
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/ifunc-11.s
@@ -0,0 +1,26 @@
+ .section .text.foo,"ax",@progbits
+ .type foo, @function
+foo:
+ .global foo
+ adrp x0, :got:ifunc
+ ldr x0, [x0, #:got_lo12:ifunc]
+ bl ifunc
+ adrp x0, xxx
+ add x0, x0, :lo12:xxx
+ ret
+
+ .section .text.bar,"ax",@progbits
+ .type bar, @function
+bar:
+ .global bar
+ ret
+
+ .section .text.ifunc,"ax",@progbits
+ .type ifunc, @gnu_indirect_function
+ .global ifunc
+ifunc:
+ ret
+
+ .section .data.foo,"aw",@progbits
+xxx:
+ .quad ifunc
diff --git a/ld/testsuite/ld-aarch64/ifunc-12.d b/ld/testsuite/ld-aarch64/ifunc-12.d
new file mode 100644
index 0000000..8fa8ce0
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/ifunc-12.d
@@ -0,0 +1,5 @@
+#ld: -shared -e bar --gc-sections
+#readelf: -r --wide
+#target: aarch64*-*-*
+
+There are no relocations in this file.
diff --git a/ld/testsuite/ld-aarch64/ifunc-12.s b/ld/testsuite/ld-aarch64/ifunc-12.s
new file mode 100644
index 0000000..aad30df
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/ifunc-12.s
@@ -0,0 +1,24 @@
+ .section .text.foo,"ax",@progbits
+ .type foo, @function
+foo:
+ adrp x0, :got:ifunc
+ ldr x0, [x0, #:got_lo12:ifunc]
+ bl ifunc
+ adrp x0, xxx
+ add x0, x0, :lo12:xxx
+ ret
+
+ .section .text.bar,"ax",@progbits
+ .type bar, @function
+bar:
+ .global bar
+ ret
+
+ .section .text.ifunc,"ax",@progbits
+ .type ifunc, @gnu_indirect_function
+ifunc:
+ ret
+
+ .section .data.foo,"aw",@progbits
+xxx:
+ .quad ifunc
diff --git a/ld/testsuite/ld-aarch64/ifunc-13.d b/ld/testsuite/ld-aarch64/ifunc-13.d
new file mode 100644
index 0000000..e1b5c10
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/ifunc-13.d
@@ -0,0 +1,13 @@
+#source: ifunc-13a.s
+#source: ifunc-13b.s
+#ld: -shared -z nocombreloc
+#readelf: -r --wide
+#target: aarch64*-*-*
+
+Relocation section '.rela.ifunc' at offset 0x[0-9a-f]+ contains 1 entries:
+[ ]+Offset[ ]+Info[ ]+Type[ ]+.*
+[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_AARCH64_ABS64[ ]+ifunc\(\)[ ]+ifunc \+ 0
+
+Relocation section '.rela.plt' at offset 0x[0-9a-f]+ contains 1 entries:
+[ ]+Offset[ ]+Info[ ]+Type[ ]+.*
+[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_AARCH64_JUMP_SLOT[ ]+ifunc\(\)[ ]+ifunc \+ 0
diff --git a/ld/testsuite/ld-aarch64/ifunc-13a.s b/ld/testsuite/ld-aarch64/ifunc-13a.s
new file mode 100644
index 0000000..873e06e
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/ifunc-13a.s
@@ -0,0 +1,11 @@
+ .text
+ .type foo, @function
+ .global foo
+foo:
+ adrp x0, xxx
+ add x0, x0, :lo12:xxx
+ ret
+
+ .data
+xxx:
+ .quad ifunc
diff --git a/ld/testsuite/ld-aarch64/ifunc-13b.s b/ld/testsuite/ld-aarch64/ifunc-13b.s
new file mode 100644
index 0000000..3560394
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/ifunc-13b.s
@@ -0,0 +1,5 @@
+ .text
+ .type ifunc, @gnu_indirect_function
+ .globl ifunc
+ifunc:
+ ret
diff --git a/ld/testsuite/ld-aarch64/ifunc-14a.d b/ld/testsuite/ld-aarch64/ifunc-14a.d
new file mode 100644
index 0000000..ff580d0
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/ifunc-14a.d
@@ -0,0 +1,10 @@
+#source: ifunc-14a.s
+#source: ifunc-14b.s
+#ld: -shared -z nocombreloc
+#readelf: -d
+#target: aarch64*-*-*
+
+#failif
+#...
+.*\(TEXTREL\).*
+#...
diff --git a/ld/testsuite/ld-aarch64/ifunc-14a.s b/ld/testsuite/ld-aarch64/ifunc-14a.s
new file mode 100644
index 0000000..7d6183c
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/ifunc-14a.s
@@ -0,0 +1,7 @@
+ .text
+ .globl bar
+ .type bar, @function
+bar:
+ bl foo
+ .size bar, .-bar
+ .hidden foo
diff --git a/ld/testsuite/ld-aarch64/ifunc-14b.d b/ld/testsuite/ld-aarch64/ifunc-14b.d
new file mode 100644
index 0000000..52ed2b4
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/ifunc-14b.d
@@ -0,0 +1,10 @@
+#source: ifunc-14b.s
+#source: ifunc-14a.s
+#ld: -shared -z nocombreloc
+#readelf: -d
+#target: aarch64*-*-*
+
+#failif
+#...
+.*\(TEXTREL\).*
+#...
diff --git a/ld/testsuite/ld-aarch64/ifunc-14b.s b/ld/testsuite/ld-aarch64/ifunc-14b.s
new file mode 100644
index 0000000..bac22eb
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/ifunc-14b.s
@@ -0,0 +1,5 @@
+ .type foo, %gnu_indirect_function
+ .globl foo
+foo:
+ ret
+ .size foo, .-foo
diff --git a/ld/testsuite/ld-aarch64/ifunc-14c.d b/ld/testsuite/ld-aarch64/ifunc-14c.d
new file mode 100644
index 0000000..a83126f
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/ifunc-14c.d
@@ -0,0 +1,10 @@
+#source: ifunc-14a.s
+#source: ifunc-14b.s
+#ld: -shared -z nocombreloc
+#readelf: -r --wide
+#target: aarch64*-*-*
+
+#failif
+#...
+.* +R_AARCH64_NONE +.*
+#...
diff --git a/ld/testsuite/ld-aarch64/ifunc-14c.s b/ld/testsuite/ld-aarch64/ifunc-14c.s
new file mode 100644
index 0000000..7853280
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/ifunc-14c.s
@@ -0,0 +1,7 @@
+ .text
+ .globl xxx
+ .type xxx, @function
+xxx:
+ bl foo
+ .size xxx, .-xxx
+ .hidden foo
diff --git a/ld/testsuite/ld-aarch64/ifunc-14d.d b/ld/testsuite/ld-aarch64/ifunc-14d.d
new file mode 100644
index 0000000..4ae88d2
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/ifunc-14d.d
@@ -0,0 +1,10 @@
+#source: ifunc-14b.s
+#source: ifunc-14a.s
+#ld: -shared -z nocombreloc
+#readelf: -r --wide
+#target: aarch64*-*-*
+
+#failif
+#...
+.* +R_AARCH64_NONE +.*
+#...
diff --git a/ld/testsuite/ld-aarch64/ifunc-14e.d b/ld/testsuite/ld-aarch64/ifunc-14e.d
new file mode 100644
index 0000000..62de35e
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/ifunc-14e.d
@@ -0,0 +1,11 @@
+#source: ifunc-14a.s
+#source: ifunc-14c.s
+#source: ifunc-14b.s
+#ld: -shared -z nocombreloc
+#readelf: -r --wide
+#target: aarch64*-*-*
+
+#failif
+#...
+.* +R_AARCH64_NONE +.*
+#...
diff --git a/ld/testsuite/ld-aarch64/ifunc-14f.d b/ld/testsuite/ld-aarch64/ifunc-14f.d
new file mode 100644
index 0000000..ab8bdbf
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/ifunc-14f.d
@@ -0,0 +1,11 @@
+#source: ifunc-14a.s
+#source: ifunc-14b.s
+#source: ifunc-14c.s
+#ld: -shared -z nocombreloc
+#readelf: -r --wide
+#target: aarch64*-*-*
+
+#failif
+#...
+.* +R_AARCH64_NONE +.*
+#...
diff --git a/ld/testsuite/ld-aarch64/ifunc-15.d b/ld/testsuite/ld-aarch64/ifunc-15.d
new file mode 100644
index 0000000..51d9242
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/ifunc-15.d
@@ -0,0 +1,12 @@
+#source: ifunc-15.s
+#ld: -shared -z nocombreloc
+#readelf: -r --wide
+#target: aarch64*-*-*
+
+Relocation section '.rela.got' at offset 0x[0-9a-f]+ contains 1 entries:
+[ ]+Offset[ ]+Info[ ]+Type[ ]+.*
+[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_AARCH64_GLOB_DAT[ ]+ifunc\(\)[ ]+ifunc \+ 0
+
+Relocation section '.rela.plt' at offset 0x[0-9a-f]+ contains 1 entries:
+[ ]+Offset[ ]+Info[ ]+Type[ ]+.*
+[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_AARCH64_JUMP_SLOT[ ]+ifunc\(\)[ ]+ifunc \+ 0
diff --git a/ld/testsuite/ld-aarch64/ifunc-15.s b/ld/testsuite/ld-aarch64/ifunc-15.s
new file mode 100644
index 0000000..f94b4a6
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/ifunc-15.s
@@ -0,0 +1,11 @@
+ .text
+ .type foo, @function
+ .global foo
+foo:
+ adrp x0, :got:ifunc
+ ldr x0, [x0, #:got_lo12:ifunc]
+ ret
+ .type ifunc, @gnu_indirect_function
+ .globl ifunc
+ifunc:
+ ret
diff --git a/ld/testsuite/ld-aarch64/ifunc-16.d b/ld/testsuite/ld-aarch64/ifunc-16.d
new file mode 100644
index 0000000..31ec162
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/ifunc-16.d
@@ -0,0 +1,9 @@
+#source: ifunc-16.s
+#ld: -shared
+#readelf: -r --wide
+#target: aarch64*-*-*
+
+Relocation section '.rela.plt' at .*
+[ ]+Offset[ ]+Info[ ]+Type[ ]+.*
+[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_AARCH64_JUMP_SLOT[ ]+0+[ ]+ifunc \+ 0
+[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_AARCH64_IRELATIVE[ ]+[0-9a-f]*
diff --git a/ld/testsuite/ld-aarch64/ifunc-16.s b/ld/testsuite/ld-aarch64/ifunc-16.s
new file mode 100644
index 0000000..ded401a
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/ifunc-16.s
@@ -0,0 +1,17 @@
+ .text
+ .globl fct
+ .type fct, @gnu_indirect_function
+ .set fct,resolve
+ .hidden int_fct
+ .globl int_fct
+ .set int_fct,fct
+ .p2align 4,,15
+ .type resolve, @function
+resolve:
+ bl ifunc
+ .size resolve, .-resolve
+ .globl g
+ .type g, @function
+g:
+ bl int_fct
+ .size g, .-g
diff --git a/ld/testsuite/ld-aarch64/ifunc-17a.d b/ld/testsuite/ld-aarch64/ifunc-17a.d
new file mode 100644
index 0000000..a87de7c
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/ifunc-17a.d
@@ -0,0 +1,9 @@
+#source: ifunc-17a.s
+#source: ifunc-17b.s
+#ld: -static
+#readelf: -s --wide
+#target: aarch64*-*-*
+
+#...
+ +[0-9]+: +[0-9a-f]+ +4 +OBJECT +GLOBAL +DEFAULT +[1-9] foo
+#pass
diff --git a/ld/testsuite/ld-aarch64/ifunc-17a.s b/ld/testsuite/ld-aarch64/ifunc-17a.s
new file mode 100644
index 0000000..e0bde49
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/ifunc-17a.s
@@ -0,0 +1,11 @@
+ .globl main
+ .globl start
+ .globl _start
+ .globl __start
+ .text
+main:
+start:
+_start:
+__start:
+ .byte 0
+ .common foo,4,4
diff --git a/ld/testsuite/ld-aarch64/ifunc-17b.d b/ld/testsuite/ld-aarch64/ifunc-17b.d
new file mode 100644
index 0000000..9286a9f
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/ifunc-17b.d
@@ -0,0 +1,9 @@
+#source: ifunc-17b.s
+#source: ifunc-17a.s
+#ld: -static
+#readelf: -s --wide
+#target: aarch64*-*-*
+
+#...
+ +[0-9]+: +[0-9a-f]+ +4 +OBJECT +GLOBAL +DEFAULT +[1-9] foo
+#pass
diff --git a/ld/testsuite/ld-aarch64/ifunc-17b.s b/ld/testsuite/ld-aarch64/ifunc-17b.s
new file mode 100644
index 0000000..66abe04
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/ifunc-17b.s
@@ -0,0 +1,6 @@
+ .weak foo
+ .type foo, %gnu_indirect_function
+ .size foo,1
+ .text
+foo:
+ .byte 1
diff --git a/ld/testsuite/ld-aarch64/ifunc-18a.d b/ld/testsuite/ld-aarch64/ifunc-18a.d
new file mode 100644
index 0000000..3db91d3
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/ifunc-18a.d
@@ -0,0 +1,14 @@
+#source: ifunc-18a.s
+#source: ifunc-18b.s
+#ld: -shared -z nocombreloc
+#readelf: -r --wide
+#target: aarch64*-*-*
+
+Relocation section '.rela.ifunc' at .*
+[ ]+Offset[ ]+Info[ ]+Type[ ]+.*
+[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_AARCH64_IRELATIVE[ ]+[0-9a-f]*
+
+Relocation section '.rela.plt' at .*
+[ ]+Offset[ ]+Info[ ]+Type[ ]+.*
+[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_AARCH64_IRELATIVE[ ]+[0-9a-f]*
+[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_AARCH64_IRELATIVE[ ]+[0-9a-f]*
diff --git a/ld/testsuite/ld-aarch64/ifunc-18a.s b/ld/testsuite/ld-aarch64/ifunc-18a.s
new file mode 100644
index 0000000..c29c121
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/ifunc-18a.s
@@ -0,0 +1,5 @@
+ .section .data.rel,"aw",@progbits
+ .globl foo_ptrt
+ .type foo_ptr, @object
+foo_ptr:
+ .dc.a foo
diff --git a/ld/testsuite/ld-aarch64/ifunc-18b.d b/ld/testsuite/ld-aarch64/ifunc-18b.d
new file mode 100644
index 0000000..b27f526
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/ifunc-18b.d
@@ -0,0 +1,14 @@
+#source: ifunc-18b.s
+#source: ifunc-18a.s
+#ld: -shared -z nocombreloc
+#readelf: -r --wide
+#target: aarch64*-*-*
+
+Relocation section '.rela.ifunc' at .*
+[ ]+Offset[ ]+Info[ ]+Type[ ]+.*
+[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_AARCH64_IRELATIVE[ ]+[0-9a-f]*
+
+Relocation section '.rela.plt' at .*
+[ ]+Offset[ ]+Info[ ]+Type[ ]+.*
+[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_AARCH64_IRELATIVE[ ]+[0-9a-f]*
+[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_AARCH64_IRELATIVE[ ]+[0-9a-f]*
diff --git a/ld/testsuite/ld-aarch64/ifunc-18b.s b/ld/testsuite/ld-aarch64/ifunc-18b.s
new file mode 100644
index 0000000..2e46c1e
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/ifunc-18b.s
@@ -0,0 +1,15 @@
+ .text
+ .type foo, %gnu_indirect_function
+ .hidden foo
+ .globl foo
+foo:
+ ret
+ .size foo, .-foo
+ .globl bar
+bar:
+ bl foo1
+ ret
+ .size bar, .-bar
+ .hidden foo1
+ .globl foo1
+ foo1 = foo
diff --git a/ld/testsuite/ld-aarch64/ifunc-19a.d b/ld/testsuite/ld-aarch64/ifunc-19a.d
new file mode 100644
index 0000000..dd82b24
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/ifunc-19a.d
@@ -0,0 +1,13 @@
+#source: ifunc-19a.s
+#source: ifunc-19b.s
+#ld: -shared -z nocombreloc
+#readelf: -r --wide
+#target: aarch64*-*-*
+
+Relocation section '.rela.ifunc' at .*
+[ ]+Offset[ ]+Info[ ]+Type[ ]+.*
+[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_AARCH64_IRELATIVE[ ]+[0-9a-f]*
+
+Relocation section '.rela.plt' at .*
+[ ]+Offset[ ]+Info[ ]+Type[ ]+.*
+[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_AARCH64_IRELATIVE[ ]+[0-9a-f]*
diff --git a/ld/testsuite/ld-aarch64/ifunc-19a.s b/ld/testsuite/ld-aarch64/ifunc-19a.s
new file mode 100644
index 0000000..3a3d0cd
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/ifunc-19a.s
@@ -0,0 +1,5 @@
+ .section .data.rel,"aw",@progbits
+ .globl foo_ptrt
+ .type foo_ptr, @object
+foo_ptr:
+ .dc.a foo1
diff --git a/ld/testsuite/ld-aarch64/ifunc-19b.d b/ld/testsuite/ld-aarch64/ifunc-19b.d
new file mode 100644
index 0000000..1e0819c
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/ifunc-19b.d
@@ -0,0 +1,13 @@
+#source: ifunc-19b.s
+#source: ifunc-19a.s
+#ld: -shared -z nocombreloc
+#readelf: -r --wide
+#target: aarch64*-*-*
+
+Relocation section '.rela.ifunc' at .*
+[ ]+Offset[ ]+Info[ ]+Type[ ]+.*
+[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_AARCH64_IRELATIVE[ ]+[0-9a-f]*
+
+Relocation section '.rela.plt' at .*
+[ ]+Offset[ ]+Info[ ]+Type[ ]+.*
+[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_AARCH64_IRELATIVE[ ]+[0-9a-f]*
diff --git a/ld/testsuite/ld-aarch64/ifunc-19b.s b/ld/testsuite/ld-aarch64/ifunc-19b.s
new file mode 100644
index 0000000..2e46c1e
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/ifunc-19b.s
@@ -0,0 +1,15 @@
+ .text
+ .type foo, %gnu_indirect_function
+ .hidden foo
+ .globl foo
+foo:
+ ret
+ .size foo, .-foo
+ .globl bar
+bar:
+ bl foo1
+ ret
+ .size bar, .-bar
+ .hidden foo1
+ .globl foo1
+ foo1 = foo
diff --git a/ld/testsuite/ld-aarch64/ifunc-2-local.d b/ld/testsuite/ld-aarch64/ifunc-2-local.d
new file mode 100644
index 0000000..103f3e4
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/ifunc-2-local.d
@@ -0,0 +1,9 @@
+#ld: -shared
+#objdump: -dw
+#target: aarch64*-*-*
+
+#...
+[ \t0-9a-f]+:[ \t0-9a-f]+bl[ \t0-9a-f]+<\*ABS\*\+(0x2a0|0x2f0)@plt>
+[ \t0-9a-f]+:[ \t0-9a-f]+adrp[ \t]+x0, 0 <.*>
+[ \t0-9a-f]+:[ \t0-9a-f]+add[ \t]+x0, x0, #(0x290|0x2e0)
+#pass
diff --git a/ld/testsuite/ld-aarch64/ifunc-2-local.s b/ld/testsuite/ld-aarch64/ifunc-2-local.s
new file mode 100644
index 0000000..632c31f
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/ifunc-2-local.s
@@ -0,0 +1,15 @@
+ .type foo, %gnu_indirect_function
+ .set __GI_foo, foo
+ .text
+ .type foo, @function
+foo:
+ ret
+ .size foo, .-foo
+.globl bar
+ .type bar, @function
+bar:
+ bl __GI_foo
+ adrp x0, __GI_foo
+ add x0, x0, :lo12:__GI_foo
+ ret
+ .size bar, .-bar
diff --git a/ld/testsuite/ld-aarch64/ifunc-2.d b/ld/testsuite/ld-aarch64/ifunc-2.d
new file mode 100644
index 0000000..70ce224
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/ifunc-2.d
@@ -0,0 +1,9 @@
+#ld: -shared
+#objdump: -dw
+#target: aarch64*-*-*
+
+#...
+[ \t0-9a-f]+:[ \t0-9a-f]+bl[ \t0-9a-f]+<\*ABS\*\+(0x2c0|0x308)@plt>
+[ \t0-9a-f]+:[ \t0-9a-f]+adrp[ \t]+x0, 0 <.*>
+[ \t0-9a-f]+:[ \t0-9a-f]+add[ \t]+x0, x0, #(0x2b0|0x2f8)
+#pass
diff --git a/ld/testsuite/ld-aarch64/ifunc-2.s b/ld/testsuite/ld-aarch64/ifunc-2.s
new file mode 100644
index 0000000..da350df
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/ifunc-2.s
@@ -0,0 +1,18 @@
+ .type foo, %gnu_indirect_function
+ .global __GI_foo
+ .hidden __GI_foo
+ .set __GI_foo, foo
+ .text
+.globl foo
+ .type foo, @function
+foo:
+ ret
+ .size foo, .-foo
+.globl bar
+ .type bar, @function
+bar:
+ bl __GI_foo
+ adrp x0, __GI_foo
+ add x0, x0, :lo12:__GI_foo
+ ret
+ .size bar, .-bar
diff --git a/ld/testsuite/ld-aarch64/ifunc-20.d b/ld/testsuite/ld-aarch64/ifunc-20.d
new file mode 100644
index 0000000..3380479
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/ifunc-20.d
@@ -0,0 +1,12 @@
+#source: ifunc-20.s
+#ld: -shared -z nocombreloc
+#readelf: -r --wide
+#target: aarch64*-*-*
+
+Relocation section '.rela.ifunc' at offset 0x[0-9a-f]+ contains 1 entries:
+[ ]+Offset[ ]+Info[ ]+Type[ ]+.*
+[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_AARCH64_ABS64[ ]+ifunc\(\)[ ]+ifunc \+ 0
+
+Relocation section '.rela.plt' at offset 0x[0-9a-f]+ contains 1 entries:
+[ ]+Offset[ ]+Info[ ]+Type[ ]+.*
+[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_AARCH64_JUMP_SLOT[ ]+ifunc\(\)[ ]+ifunc \+ 0
diff --git a/ld/testsuite/ld-aarch64/ifunc-20.s b/ld/testsuite/ld-aarch64/ifunc-20.s
new file mode 100644
index 0000000..17393cb
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/ifunc-20.s
@@ -0,0 +1,16 @@
+ .section .data.rel,"aw",@progbits
+ .globl ifunc_ptrt
+ .type ifunc_ptr, @object
+ifunc_ptr:
+ .dc.a ifunc
+ .text
+ .type ifunc, @gnu_indirect_function
+ .globl ifunc
+ifunc:
+ ret
+ .size ifunc, .-ifunc
+ .type bar, @function
+ .globl bar
+bar:
+ bl ifunc
+ .size bar, .-bar
diff --git a/ld/testsuite/ld-aarch64/ifunc-3.s b/ld/testsuite/ld-aarch64/ifunc-3.s
new file mode 100644
index 0000000..c68b1b7
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/ifunc-3.s
@@ -0,0 +1,16 @@
+ .type foo, %gnu_indirect_function
+ .global __GI_foo
+ .protected __GI_foo
+ .set __GI_foo, foo
+ .text
+.globl foo
+ .type foo, @function
+foo:
+ ret
+ .size foo, .-foo
+.globl bar
+ .type bar, @function
+bar:
+ bl __GI_foo
+ ret
+ .size bar, .-bar
diff --git a/ld/testsuite/ld-aarch64/ifunc-3a.d b/ld/testsuite/ld-aarch64/ifunc-3a.d
new file mode 100644
index 0000000..4f61a8b
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/ifunc-3a.d
@@ -0,0 +1,8 @@
+#source: ifunc-3.s
+#ld: -shared
+#objdump: -dw
+#target: aarch64*-*-*
+
+#...
+[ \t0-9a-f]+:[ \t0-9a-f]+bl[ \t0-9a-f]+<\*ABS\*\+(0x2e0|0x330)@plt>
+#pass
diff --git a/ld/testsuite/ld-aarch64/ifunc-3b.d b/ld/testsuite/ld-aarch64/ifunc-3b.d
new file mode 100644
index 0000000..7e177a6
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/ifunc-3b.d
@@ -0,0 +1,8 @@
+#source: ifunc-3.s
+#ld: -shared
+#readelf: -r --wide
+#target: aarch64*-*-*
+
+#...
+[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_[_0-9A-Z]+_IRELATIVE[ ]*[0-9a-f]*
+#pass
diff --git a/ld/testsuite/ld-aarch64/ifunc-4.d b/ld/testsuite/ld-aarch64/ifunc-4.d
new file mode 100644
index 0000000..5e69b05
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/ifunc-4.d
@@ -0,0 +1,7 @@
+#ld:
+#readelf: -r --wide
+#target: aarch64*-*-*
+
+#...
+[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_[_0-9A-Z]+_IRELATIVE[ ]*[0-9a-f]*
+#pass
diff --git a/ld/testsuite/ld-aarch64/ifunc-4.s b/ld/testsuite/ld-aarch64/ifunc-4.s
new file mode 100644
index 0000000..c2b66f5
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/ifunc-4.s
@@ -0,0 +1,18 @@
+ .text
+ .type foo, %gnu_indirect_function
+.globl foo
+ .type foo, @function
+foo:
+ ret
+ .size foo, .-foo
+ .type start,"function"
+ .global start
+start:
+ .type _start,"function"
+ .global _start
+_start:
+ .type __start,"function"
+ .global __start
+__start:
+ .type __start,"function"
+ bl foo
diff --git a/ld/testsuite/ld-aarch64/ifunc-4a.d b/ld/testsuite/ld-aarch64/ifunc-4a.d
new file mode 100644
index 0000000..801e6cd
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/ifunc-4a.d
@@ -0,0 +1,8 @@
+#ld: -s
+#readelf: -r --wide
+#target: aarch64*-*-*
+#source: ifunc-4.s
+
+#...
+[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_[_0-9A-Z]+_IRELATIVE[ ]*[0-9a-f]*
+#pass
diff --git a/ld/testsuite/ld-aarch64/ifunc-5-local.s b/ld/testsuite/ld-aarch64/ifunc-5-local.s
new file mode 100644
index 0000000..8d23bab
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/ifunc-5-local.s
@@ -0,0 +1,19 @@
+ .text
+ .type foo, %gnu_indirect_function
+ .type foo, @function
+foo:
+ ret
+ .size foo, .-foo
+ .type start,"function"
+ .global start
+start:
+ .type _start,"function"
+ .global _start
+_start:
+ .type __start,"function"
+ .global __start
+__start:
+ .type __start,"function"
+ bl foo
+ adrp x0, :got:foo
+ ldr x0, [x0, #:got_lo12:foo]
diff --git a/ld/testsuite/ld-aarch64/ifunc-5.s b/ld/testsuite/ld-aarch64/ifunc-5.s
new file mode 100644
index 0000000..b1bbf1a
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/ifunc-5.s
@@ -0,0 +1,20 @@
+ .text
+ .type foo, %gnu_indirect_function
+.globl foo
+ .type foo, @function
+foo:
+ ret
+ .size foo, .-foo
+ .type start,"function"
+ .global start
+start:
+ .type _start,"function"
+ .global _start
+_start:
+ .type __start,"function"
+ .global __start
+__start:
+ .type __start,"function"
+ bl foo
+ adrp x0, :got:foo
+ ldr x0, [x0, #:got_lo12:foo]
diff --git a/ld/testsuite/ld-aarch64/ifunc-5a-local.d b/ld/testsuite/ld-aarch64/ifunc-5a-local.d
new file mode 100644
index 0000000..9693585
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/ifunc-5a-local.d
@@ -0,0 +1,8 @@
+#source: ifunc-5-local.s
+#ld:
+#readelf: -r --wide
+#target: aarch64*-*-*
+
+Relocation section '.rela.plt' at .*
+[ ]+Offset[ ]+Info[ ]+Type[ ]+.*
+[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_AARCH64_IRELATIVE[ ]+[0-9a-f]*
diff --git a/ld/testsuite/ld-aarch64/ifunc-5a.d b/ld/testsuite/ld-aarch64/ifunc-5a.d
new file mode 100644
index 0000000..f0ee59f
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/ifunc-5a.d
@@ -0,0 +1,8 @@
+#source: ifunc-5.s
+#ld:
+#readelf: -r --wide
+#target: aarch64*-*-*
+
+Relocation section '.rela.plt' at .*
+[ ]+Offset[ ]+Info[ ]+Type[ ]+.*
+[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_AARCH64_IRELATIVE[ ]+[0-9a-f]*
diff --git a/ld/testsuite/ld-aarch64/ifunc-5b-local.d b/ld/testsuite/ld-aarch64/ifunc-5b-local.d
new file mode 100644
index 0000000..e8e620c
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/ifunc-5b-local.d
@@ -0,0 +1,8 @@
+#source: ifunc-5-local.s
+#ld: -shared -z nocombreloc
+#readelf: -r --wide
+#target: aarch64*-*-*
+
+Relocation section '.rela.plt' at .*
+[ ]+Offset[ ]+Info[ ]+Type[ ]+.*
+[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_AARCH64_IRELATIVE[ ]+[0-9a-f]*
diff --git a/ld/testsuite/ld-aarch64/ifunc-5b.d b/ld/testsuite/ld-aarch64/ifunc-5b.d
new file mode 100644
index 0000000..0175982
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/ifunc-5b.d
@@ -0,0 +1,12 @@
+#source: ifunc-5.s
+#ld: -shared -z nocombreloc
+#readelf: -r --wide
+#target: aarch64*-*-*
+
+Relocation section '.rela.got' at .*
+[ ]+Offset[ ]+Info[ ]+Type[ ]+.*
+[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_AARCH64_GLOB_DAT[ ]+foo\(\)[ ]+foo \+ 0
+#...
+Relocation section '.rela.plt' at .*
+[ ]+Offset[ ]+Info[ ]+Type[ ]+.*
+[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_AARCH64_JUMP_SLOT[ ]+foo\(\)[ ]+foo \+ 0
diff --git a/ld/testsuite/ld-aarch64/ifunc-5r-local.d b/ld/testsuite/ld-aarch64/ifunc-5r-local.d
new file mode 100644
index 0000000..463cd25
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/ifunc-5r-local.d
@@ -0,0 +1,10 @@
+#source: ifunc-5-local.s
+#ld: -r
+#readelf: -r --wide
+#target: aarch64*-*-*
+
+Relocation section '.rela.text' at .*
+[ ]+Offset[ ]+Info[ ]+Type[ ]+.*
+[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_AARCH64_CALL26[ ]+foo\(\)[ ]+foo \+ 0
+[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_AARCH64_ADR_GOT_PAGE[ ]+foo\(\)[ ]+foo \+ 0
+[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_AARCH64_LD64_GOT_LO1[ ]+foo\(\)[ ]+foo \+ 0
diff --git a/ld/testsuite/ld-aarch64/ifunc-6.s b/ld/testsuite/ld-aarch64/ifunc-6.s
new file mode 100644
index 0000000..56486d6d
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/ifunc-6.s
@@ -0,0 +1,21 @@
+ .text
+ .type foo, %gnu_indirect_function
+.globl foo
+ .type foo, @function
+foo:
+ ret
+ .size foo, .-foo
+ .protected foo
+ .type start,"function"
+ .global start
+start:
+ .type _start,"function"
+ .global _start
+_start:
+ .type __start,"function"
+ .global __start
+__start:
+ .type __start,"function"
+ bl foo
+ adrp x0, :got:foo
+ ldr x0, [x0, #:got_lo12:foo]
diff --git a/ld/testsuite/ld-aarch64/ifunc-6a.d b/ld/testsuite/ld-aarch64/ifunc-6a.d
new file mode 100644
index 0000000..a50ad3a
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/ifunc-6a.d
@@ -0,0 +1,8 @@
+#source: ifunc-6.s
+#ld:
+#readelf: -r --wide
+#target: aarch64*-*-*
+
+Relocation section '.rela.plt' at .*
+[ ]+Offset[ ]+Info[ ]+Type[ ]+.*
+[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_AARCH64_IRELATIVE[ ]+[0-9a-f]*
diff --git a/ld/testsuite/ld-aarch64/ifunc-6b.d b/ld/testsuite/ld-aarch64/ifunc-6b.d
new file mode 100644
index 0000000..c415bc3
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/ifunc-6b.d
@@ -0,0 +1,12 @@
+#source: ifunc-6.s
+#ld: -shared -z nocombreloc
+#readelf: -r --wide
+#target: aarch64*-*-*
+
+Relocation section '.rela.got' at .*
+[ ]+Offset[ ]+Info[ ]+Type[ ]+.*
+[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_AARCH64_GLOB_DAT[ ]+foo\(\)[ ]+foo \+ 0
+#...
+Relocation section '.rela.plt' at .*
+[ ]+Offset[ ]+Info[ ]+Type[ ]+.*
+[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_AARCH64_IRELATIVE[ ]+[0-9a-f]*
diff --git a/ld/testsuite/ld-aarch64/ifunc-7.s b/ld/testsuite/ld-aarch64/ifunc-7.s
new file mode 100644
index 0000000..51485af
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/ifunc-7.s
@@ -0,0 +1,21 @@
+ .text
+ .type foo, %gnu_indirect_function
+.globl foo
+ .type foo, @function
+foo:
+ ret
+ .size foo, .-foo
+ .hidden foo
+ .type start,"function"
+ .global start
+start:
+ .type _start,"function"
+ .global _start
+_start:
+ .type __start,"function"
+ .global __start
+__start:
+ .type __start,"function"
+ bl foo
+ adrp x0, :got:foo
+ ldr x0, [x0, #:got_lo12:foo]
diff --git a/ld/testsuite/ld-aarch64/ifunc-7a.d b/ld/testsuite/ld-aarch64/ifunc-7a.d
new file mode 100644
index 0000000..c246c99
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/ifunc-7a.d
@@ -0,0 +1,8 @@
+#source: ifunc-7.s
+#ld:
+#readelf: -r --wide
+#target: aarch64*-*-*
+
+Relocation section '.rela.plt' at .*
+[ ]+Offset[ ]+Info[ ]+Type[ ]+.*
+[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_AARCH64_IRELATIVE[ ]+[0-9a-f]*
diff --git a/ld/testsuite/ld-aarch64/ifunc-7b.d b/ld/testsuite/ld-aarch64/ifunc-7b.d
new file mode 100644
index 0000000..efdd379
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/ifunc-7b.d
@@ -0,0 +1,8 @@
+#source: ifunc-7.s
+#ld: -shared
+#readelf: -r --wide
+#target: aarch64*-*-*
+
+Relocation section '.rela.plt' at .*
+[ ]+Offset[ ]+Info[ ]+Type[ ]+.*
+[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_AARCH64_IRELATIVE[ ]+[0-9a-f]*
diff --git a/ld/testsuite/ld-aarch64/ifunc-7c.d b/ld/testsuite/ld-aarch64/ifunc-7c.d
new file mode 100644
index 0000000..1967742
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/ifunc-7c.d
@@ -0,0 +1,19 @@
+#source: ifunc-7.s
+#ld: -shared
+#objdump: -dr -j .text
+#target: aarch64*-*-*
+
+# Check if adrp and ldr have been relocated correctly.
+
+.*: file format elf.+aarch64.*
+
+
+Disassembly of section \.text:
+
+[0-9a-f]+ <foo>:
+ [0-9a-f]+: d65f03c0 ret
+
+[0-9a-f]+ <__start>:
+ [0-9a-f]+: [0-9a-f]+ bl [0-9a-f]+ <\*ABS\*\+0x[0-9a-f]+@plt>
+ [0-9a-f]+: [0-9a-f]+ adrp x0, [0-9]+ <__start\+0x[0-9a-f]+>
+ [0-9a-f]+: [0-9a-f]+ ldr x0, \[x0,.+\]
diff --git a/ld/testsuite/ld-aarch64/ifunc-8.d b/ld/testsuite/ld-aarch64/ifunc-8.d
new file mode 100644
index 0000000..8aadc51
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/ifunc-8.d
@@ -0,0 +1,9 @@
+#source: ifunc-8a.s
+#source: ifunc-8b.s
+#ld:
+#readelf: -r --wide
+#target: aarch64*-*-*
+
+Relocation section '.rela.plt' at .*
+[ ]+Offset[ ]+Info[ ]+Type[ ]+.*
+[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_AARCH64_IRELATIVE[ ]+[0-9a-f]*
diff --git a/ld/testsuite/ld-aarch64/ifunc-8a.s b/ld/testsuite/ld-aarch64/ifunc-8a.s
new file mode 100644
index 0000000..94c073a
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/ifunc-8a.s
@@ -0,0 +1,13 @@
+ .text
+ .type start,"function"
+ .global start
+start:
+ .type _start,"function"
+ .global _start
+_start:
+ .type __start,"function"
+ .global __start
+__start:
+ .type __start,"function"
+ adrp x0, :got:foo
+ ldr x0, [x0, #:got_lo12:foo]
diff --git a/ld/testsuite/ld-aarch64/ifunc-8b.s b/ld/testsuite/ld-aarch64/ifunc-8b.s
new file mode 100644
index 0000000..1f108f8
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/ifunc-8b.s
@@ -0,0 +1,7 @@
+ .text
+ .type foo, %gnu_indirect_function
+.globl foo
+ .type foo, @function
+foo:
+ ret
+ .size foo, .-foo
diff --git a/ld/testsuite/ld-aarch64/ifunc-9.d b/ld/testsuite/ld-aarch64/ifunc-9.d
new file mode 100644
index 0000000..3b4e995
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/ifunc-9.d
@@ -0,0 +1,3 @@
+#ld: --export-dynamic
+#error: .*dynamic STT_GNU_IFUNC symbol `foo' with pointer equality in `.*.o' can not be used when making an executable; recompile with -fPIE and relink with -pie
+#target: aarch64*-*-*
diff --git a/ld/testsuite/ld-aarch64/ifunc-9.s b/ld/testsuite/ld-aarch64/ifunc-9.s
new file mode 100644
index 0000000..2e2f577
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/ifunc-9.s
@@ -0,0 +1,23 @@
+ .text
+ .type foo, %gnu_indirect_function
+.globl foo
+ .type foo, @function
+foo:
+ ret
+ .size foo, .-foo
+ .type start,"function"
+ .global start
+start:
+ .type _start,"function"
+ .global _start
+_start:
+ .type __start,"function"
+ .global __start
+__start:
+ .type __start,"function"
+ adrp x0, .LANCHOR0
+ add x0, x0, :lo12:.LANCHOR0
+ .data
+ .align 3
+.LANCHOR0 = . + 0
+ .xword foo
diff --git a/ld/testsuite/ld-ifunc/ifunc.exp b/ld/testsuite/ld-ifunc/ifunc.exp
index df913d8..1d64efc 100644
--- a/ld/testsuite/ld-ifunc/ifunc.exp
+++ b/ld/testsuite/ld-ifunc/ifunc.exp
@@ -24,10 +24,11 @@
# IFUNC support has only been implemented for the ix86, x86_64, powerpc,
-# and sparc so far.
+# aarch64 and sparc so far.
if {!(([istarget "i?86-*-*"]
|| [istarget "x86_64-*-*"]
|| [istarget "powerpc*-*-*"]
+ || [istarget "aarch64*-*-*"]
|| [istarget "sparc*-*-*"])
&& ([istarget "*-*-elf*"]
|| [istarget "*-*-nacl*"]