This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[PATCH 2/2] [RFC] Add IFUNC support for MIPS (v4)
- From: Faraz Shahbazker <faraz dot shahbazker at imgtec dot com>
- To: "binutils at sourceware dot org" <binutils at sourceware dot org>, <rdsandiford at googlemail dot com>
- Cc: <macro at imgtec dot com>
- Date: Thu, 7 Jan 2016 16:10:50 -0800
- Subject: [PATCH 2/2] [RFC] Add IFUNC support for MIPS (v4)
- Authentication-results: sourceware.org; auth=none
- References: <5583540C dot 7070800 at imgtec dot com> <87381jtr31 dot fsf at googlemail dot com> <55899D52 dot 1050000 at imgtec dot com> <87vbeegucz dot fsf at googlemail dot com> <5589AFCD dot 10905 at imgtec dot com> <DCB1C42372B1674B8F912A294CCB775A71680718 at BADAG02 dot ba dot imgtec dot org> <87615awnv8 dot fsf at googlemail dot com> <5600517C dot 1030608 at imgtec dot com> <874mig14xs dot fsf at googlemail dot com> <561D2820 dot 10107 at imgtec dot com> <871tc0acam dot fsf at googlemail dot com> <5678829D dot 4080108 at imgtec dot com> <877fk6jewx dot fsf at googlemail dot com>
Test cases
ld/testsuite/ChangeLog:
* ld-ifunc/ifunc.exp: Enable IFUNC tests for MIPS targets
* ld-mips-elf/mips-ifunc.exp: IFUNC test script
* ifunc-3-n32.r, ifunc-3-n32.sym, ifunc-3-n32.t, ifunc-3-n64.r,
ifunc-3-n64.sym, ifunc-3-n64.t, ifunc-3-o32.r, ifunc-3-o32.sym,
ifunc-3-o32.t, ifunc-4-n32.r, ifunc-4-n32.sym, ifunc-4-n32.t,
ifunc-4-n64.r, ifunc-4-n64.sym, ifunc-4-n64.t, ifunc-4-o32.r,
ifunc-4-o32.sym, ifunc-4-o32.t, ifunc-5-n32.g, ifunc-5-n32.r,
ifunc-5-n32.sym, ifunc-5-n64.g, ifunc-5-n64.r, ifunc-5-n64.sym,
ifunc-5-o32.g, ifunc-5-o32.r, ifunc-5-o32.sym, ifunc-6-n32.r,
ifunc-6-n32.sym, ifunc-6-n64.r, ifunc-6-n64.sym, ifunc-6-o32.r,
ifunc-6-o32.sym, ifunc-7-o32.r, ifunc-7-o32.sec, ifunc-8-o32.g,
ifunc-8-o32.r, ifunc-8-o32.sec, ifunc-9-o32.g, ifunc-9-o32.r,
ifunc-9-o32.sec ifunc-9-o32.t, ifunc-10-o32.r, ifunc-10-o32.secm,
ifunc-11-o32.g, ifunc-11-o32.r, ifunc-11-o32.sec, ifunc-12-o32.g,
ifunc-12-o32.r, ifunc-12-o32.sec, ifunc-13-o32.r,
ifunc-13-o32.sec, ifunc-13-o32.t, ifunc-local-1.s,
ifunc-local-2.s, ifunc-local-3.s, ifunc-local-4.s,
ifunc-local-5.s, ifunc-local-6.s, ifunc-dyn-def.s, ifunc-dyn-main.s,
ifunc-dyn-ref.s, ifunc-dyn.ld, ifunc-iplt.ld,
ifunc-iplt-0x400000.t, ifunc-iplt-0x400000000.t,
ifunc-iplt-0x4000000000000.t, ifunc-iplt-micromips.t,
ifunc-iplt-micromips.igot, ifunc-iplt-mips16.t,
ifunc-iplt-mips16.igot, ifunc-iplt-mips32r6.t, ifunc-static-def.s,
ifunc-static-def-mips16.s, ifunc-static-main.s,
ifunc-static-main-mips16.s, ifunc-static-ref.s, ifunc-static.ld,
libifunc-1-n32.sym, libifunc-1-n64.sym, libifunc-1-o32.sym,
libifunc-2-n32.sym, libifunc-2-n64.sym, libifunc-2-o32.sym:
New tests.
---
ld/testsuite/ld-ifunc/ifunc.exp | 3 +-
ld/testsuite/ld-mips-elf/ifunc-10-o32.r | 3 +
ld/testsuite/ld-mips-elf/ifunc-10-o32.sec | 5 +
ld/testsuite/ld-mips-elf/ifunc-11-o32.g | 7 +
ld/testsuite/ld-mips-elf/ifunc-11-o32.r | 3 +
ld/testsuite/ld-mips-elf/ifunc-11-o32.sec | 5 +
ld/testsuite/ld-mips-elf/ifunc-12-o32.g | 7 +
ld/testsuite/ld-mips-elf/ifunc-12-o32.r | 3 +
ld/testsuite/ld-mips-elf/ifunc-12-o32.sec | 5 +
ld/testsuite/ld-mips-elf/ifunc-13-o32.r | 4 +
ld/testsuite/ld-mips-elf/ifunc-13-o32.sec | 3 +
ld/testsuite/ld-mips-elf/ifunc-13-o32.t | 5 +
ld/testsuite/ld-mips-elf/ifunc-3-n32.r | 4 +
ld/testsuite/ld-mips-elf/ifunc-3-n32.sym | 3 +
ld/testsuite/ld-mips-elf/ifunc-3-n32.t | 10 +
ld/testsuite/ld-mips-elf/ifunc-3-n64.r | 8 +
ld/testsuite/ld-mips-elf/ifunc-3-n64.sym | 3 +
ld/testsuite/ld-mips-elf/ifunc-3-n64.t | 11 +
ld/testsuite/ld-mips-elf/ifunc-3-o32.r | 4 +
ld/testsuite/ld-mips-elf/ifunc-3-o32.sym | 3 +
ld/testsuite/ld-mips-elf/ifunc-3-o32.t | 11 +
ld/testsuite/ld-mips-elf/ifunc-4-n32.r | 3 +
ld/testsuite/ld-mips-elf/ifunc-4-n32.sym | 4 +
ld/testsuite/ld-mips-elf/ifunc-4-n32.t | 10 +
ld/testsuite/ld-mips-elf/ifunc-4-n64.r | 5 +
ld/testsuite/ld-mips-elf/ifunc-4-n64.sym | 4 +
ld/testsuite/ld-mips-elf/ifunc-4-n64.t | 11 +
ld/testsuite/ld-mips-elf/ifunc-4-o32.r | 3 +
ld/testsuite/ld-mips-elf/ifunc-4-o32.sym | 4 +
ld/testsuite/ld-mips-elf/ifunc-4-o32.t | 11 +
ld/testsuite/ld-mips-elf/ifunc-5-n32.g | 11 +
ld/testsuite/ld-mips-elf/ifunc-5-n32.r | 4 +
ld/testsuite/ld-mips-elf/ifunc-5-n32.sym | 4 +
ld/testsuite/ld-mips-elf/ifunc-5-n64.g | 12 +
ld/testsuite/ld-mips-elf/ifunc-5-n64.r | 8 +
ld/testsuite/ld-mips-elf/ifunc-5-n64.sym | 4 +
ld/testsuite/ld-mips-elf/ifunc-5-o32.g | 11 +
ld/testsuite/ld-mips-elf/ifunc-5-o32.r | 4 +
ld/testsuite/ld-mips-elf/ifunc-5-o32.sym | 3 +
ld/testsuite/ld-mips-elf/ifunc-5.dyn | 3 +
ld/testsuite/ld-mips-elf/ifunc-6-n32.r | 4 +
ld/testsuite/ld-mips-elf/ifunc-6-n32.sym | 3 +
ld/testsuite/ld-mips-elf/ifunc-6-n64.r | 8 +
ld/testsuite/ld-mips-elf/ifunc-6-n64.sym | 3 +
ld/testsuite/ld-mips-elf/ifunc-6-o32.r | 4 +
ld/testsuite/ld-mips-elf/ifunc-6-o32.sym | 3 +
ld/testsuite/ld-mips-elf/ifunc-7-o32.r | 3 +
ld/testsuite/ld-mips-elf/ifunc-7-o32.sec | 4 +
ld/testsuite/ld-mips-elf/ifunc-8-o32.g | 6 +
ld/testsuite/ld-mips-elf/ifunc-8-o32.r | 3 +
ld/testsuite/ld-mips-elf/ifunc-8-o32.sec | 17 +
ld/testsuite/ld-mips-elf/ifunc-9-o32.g | 6 +
ld/testsuite/ld-mips-elf/ifunc-9-o32.r | 4 +
ld/testsuite/ld-mips-elf/ifunc-9-o32.sec | 17 +
ld/testsuite/ld-mips-elf/ifunc-9-o32.t | 8 +
ld/testsuite/ld-mips-elf/ifunc-dyn-def.s | 67 +++
ld/testsuite/ld-mips-elf/ifunc-dyn-main.s | 39 ++
ld/testsuite/ld-mips-elf/ifunc-dyn-ref.s | 43 ++
ld/testsuite/ld-mips-elf/ifunc-dyn.ld | 25 ++
ld/testsuite/ld-mips-elf/ifunc-iplt-0x400000.t | 11 +
ld/testsuite/ld-mips-elf/ifunc-iplt-0x400000000.t | 13 +
.../ld-mips-elf/ifunc-iplt-0x4000000000000.t | 14 +
ld/testsuite/ld-mips-elf/ifunc-iplt-micromips.igot | 7 +
ld/testsuite/ld-mips-elf/ifunc-iplt-micromips.t | 9 +
ld/testsuite/ld-mips-elf/ifunc-iplt-mips16.igot | 8 +
ld/testsuite/ld-mips-elf/ifunc-iplt-mips16.t | 12 +
ld/testsuite/ld-mips-elf/ifunc-iplt-mips32r6.t | 11 +
ld/testsuite/ld-mips-elf/ifunc-iplt.ld | 26 ++
ld/testsuite/ld-mips-elf/ifunc-local-1.s | 176 ++++++++
ld/testsuite/ld-mips-elf/ifunc-local-2.s | 99 +++++
ld/testsuite/ld-mips-elf/ifunc-local-3.s | 135 ++++++
ld/testsuite/ld-mips-elf/ifunc-local-4.s | 183 +++++++++
ld/testsuite/ld-mips-elf/ifunc-local-5.s | 106 +++++
ld/testsuite/ld-mips-elf/ifunc-local-6.s | 112 +++++
ld/testsuite/ld-mips-elf/ifunc-static-def-mips16.s | 434 ++++++++++++++++++++
ld/testsuite/ld-mips-elf/ifunc-static-def.s | 145 +++++++
.../ld-mips-elf/ifunc-static-main-mips16.s | 157 +++++++
ld/testsuite/ld-mips-elf/ifunc-static-main.s | 35 ++
ld/testsuite/ld-mips-elf/ifunc-static-ref.s | 36 ++
ld/testsuite/ld-mips-elf/ifunc-static.ld | 27 ++
ld/testsuite/ld-mips-elf/libifunc-1-n32.sym | 4 +
ld/testsuite/ld-mips-elf/libifunc-1-n64.sym | 4 +
ld/testsuite/ld-mips-elf/libifunc-1-o32.sym | 4 +
ld/testsuite/ld-mips-elf/libifunc-2-n32.sym | 4 +
ld/testsuite/ld-mips-elf/libifunc-2-n64.sym | 4 +
ld/testsuite/ld-mips-elf/libifunc-2-o32.sym | 5 +
ld/testsuite/ld-mips-elf/mips-ifunc.exp | 282 +++++++++++++
87 files changed, 2558 insertions(+), 1 deletion(-)
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-10-o32.r
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-10-o32.sec
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-11-o32.g
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-11-o32.r
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-11-o32.sec
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-12-o32.g
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-12-o32.r
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-12-o32.sec
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-13-o32.r
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-13-o32.sec
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-13-o32.t
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-3-n32.r
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-3-n32.sym
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-3-n32.t
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-3-n64.r
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-3-n64.sym
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-3-n64.t
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-3-o32.r
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-3-o32.sym
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-3-o32.t
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-4-n32.r
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-4-n32.sym
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-4-n32.t
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-4-n64.r
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-4-n64.sym
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-4-n64.t
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-4-o32.r
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-4-o32.sym
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-4-o32.t
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-5-n32.g
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-5-n32.r
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-5-n32.sym
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-5-n64.g
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-5-n64.r
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-5-n64.sym
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-5-o32.g
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-5-o32.r
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-5-o32.sym
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-5.dyn
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-6-n32.r
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-6-n32.sym
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-6-n64.r
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-6-n64.sym
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-6-o32.r
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-6-o32.sym
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-7-o32.r
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-7-o32.sec
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-8-o32.g
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-8-o32.r
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-8-o32.sec
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-9-o32.g
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-9-o32.r
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-9-o32.sec
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-9-o32.t
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-dyn-def.s
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-dyn-main.s
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-dyn-ref.s
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-dyn.ld
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-iplt-0x400000.t
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-iplt-0x400000000.t
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-iplt-0x4000000000000.t
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-iplt-micromips.igot
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-iplt-micromips.t
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-iplt-mips16.igot
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-iplt-mips16.t
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-iplt-mips32r6.t
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-iplt.ld
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-local-1.s
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-local-2.s
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-local-3.s
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-local-4.s
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-local-5.s
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-local-6.s
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-static-def-mips16.s
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-static-def.s
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-static-main-mips16.s
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-static-main.s
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-static-ref.s
create mode 100644 ld/testsuite/ld-mips-elf/ifunc-static.ld
create mode 100644 ld/testsuite/ld-mips-elf/libifunc-1-n32.sym
create mode 100644 ld/testsuite/ld-mips-elf/libifunc-1-n64.sym
create mode 100644 ld/testsuite/ld-mips-elf/libifunc-1-o32.sym
create mode 100644 ld/testsuite/ld-mips-elf/libifunc-2-n32.sym
create mode 100644 ld/testsuite/ld-mips-elf/libifunc-2-n64.sym
create mode 100644 ld/testsuite/ld-mips-elf/libifunc-2-o32.sym
create mode 100644 ld/testsuite/ld-mips-elf/mips-ifunc.exp
diff --git a/ld/testsuite/ld-ifunc/ifunc.exp b/ld/testsuite/ld-ifunc/ifunc.exp
index 5a5bf72..25b18b1 100644
--- a/ld/testsuite/ld-ifunc/ifunc.exp
+++ b/ld/testsuite/ld-ifunc/ifunc.exp
@@ -30,7 +30,8 @@ if {!(([istarget "i?86-*-*"]
|| [istarget "powerpc*-*-*"]
|| [istarget "aarch64*-*-*"]
|| [istarget "sparc*-*-*"]
- || [istarget "s390*-*-*"])
+ || [istarget "s390*-*-*"]
+ || [istarget "mips*-*-*"])
&& ([istarget "*-*-elf*"]
|| [istarget "*-*-nacl*"]
|| (([istarget "*-*-linux*"]
diff --git a/ld/testsuite/ld-mips-elf/ifunc-10-o32.r b/ld/testsuite/ld-mips-elf/ifunc-10-o32.r
new file mode 100644
index 0000000..789b7d8
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-10-o32.r
@@ -0,0 +1,3 @@
+Relocation section '.rel.dyn' at offset 0xe8 contains 1 entries:
+ Offset Info Type Sym.Value Sym. Name
+00410254 00000080 R_MIPS_IRELATIVE
diff --git a/ld/testsuite/ld-mips-elf/ifunc-10-o32.sec b/ld/testsuite/ld-mips-elf/ifunc-10-o32.sec
new file mode 100644
index 0000000..8f68890
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-10-o32.sec
@@ -0,0 +1,5 @@
+#...
+.* \.iplt .*
+.*
+.* \.igot .*
+#pass
\ No newline at end of file
diff --git a/ld/testsuite/ld-mips-elf/ifunc-11-o32.g b/ld/testsuite/ld-mips-elf/ifunc-11-o32.g
new file mode 100644
index 0000000..2d42af5
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-11-o32.g
@@ -0,0 +1,7 @@
+#...
+004101a0 <_GLOBAL_OFFSET_TABLE_>:
+ 4101a0: 00000000 nop
+ 4101a4: 80000000 lb zero,0\(zero\)
+ 4101a8: 00400000 0x400000
+ 4101ac: 00400170 0x400170
+#pass
diff --git a/ld/testsuite/ld-mips-elf/ifunc-11-o32.r b/ld/testsuite/ld-mips-elf/ifunc-11-o32.r
new file mode 100644
index 0000000..6803275
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-11-o32.r
@@ -0,0 +1,3 @@
+Relocation section '.rel.dyn' at offset 0xe8 contains 1 entries:
+ Offset Info Type Sym.Value Sym. Name
+00410194 00000080 R_MIPS_IRELATIVE
diff --git a/ld/testsuite/ld-mips-elf/ifunc-11-o32.sec b/ld/testsuite/ld-mips-elf/ifunc-11-o32.sec
new file mode 100644
index 0000000..8f68890
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-11-o32.sec
@@ -0,0 +1,5 @@
+#...
+.* \.iplt .*
+.*
+.* \.igot .*
+#pass
\ No newline at end of file
diff --git a/ld/testsuite/ld-mips-elf/ifunc-12-o32.g b/ld/testsuite/ld-mips-elf/ifunc-12-o32.g
new file mode 100644
index 0000000..1fe54c1
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-12-o32.g
@@ -0,0 +1,7 @@
+#...
+004101b0 <_GLOBAL_OFFSET_TABLE_>:
+ 4101b0: 00000000 nop
+ 4101b4: 80000000 lb zero,0\(zero\)
+ 4101b8: 00400000 0x400000
+ 4101bc: 00400180 0x400180
+#pass
diff --git a/ld/testsuite/ld-mips-elf/ifunc-12-o32.r b/ld/testsuite/ld-mips-elf/ifunc-12-o32.r
new file mode 100644
index 0000000..f4a3a8b
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-12-o32.r
@@ -0,0 +1,3 @@
+Relocation section '.rel.dyn' at offset 0xe8 contains 1 entries:
+ Offset Info Type Sym.Value Sym. Name
+004101a4 00000080 R_MIPS_IRELATIVE
diff --git a/ld/testsuite/ld-mips-elf/ifunc-12-o32.sec b/ld/testsuite/ld-mips-elf/ifunc-12-o32.sec
new file mode 100644
index 0000000..8f68890
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-12-o32.sec
@@ -0,0 +1,5 @@
+#...
+.* \.iplt .*
+.*
+.* \.igot .*
+#pass
\ No newline at end of file
diff --git a/ld/testsuite/ld-mips-elf/ifunc-13-o32.r b/ld/testsuite/ld-mips-elf/ifunc-13-o32.r
new file mode 100644
index 0000000..9101767
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-13-o32.r
@@ -0,0 +1,4 @@
+Relocation section '.rel.dyn' at offset 0xe8 contains 2 entries:
+ Offset Info Type Sym.Value Sym. Name
+004101e8 00000080 R_MIPS_IRELATIVE
+00000000 00000000 R_MIPS_NONE
diff --git a/ld/testsuite/ld-mips-elf/ifunc-13-o32.sec b/ld/testsuite/ld-mips-elf/ifunc-13-o32.sec
new file mode 100644
index 0000000..da8594e
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-13-o32.sec
@@ -0,0 +1,3 @@
+#...
+.* \.iplt .*
+#pass
\ No newline at end of file
diff --git a/ld/testsuite/ld-mips-elf/ifunc-13-o32.t b/ld/testsuite/ld-mips-elf/ifunc-13-o32.t
new file mode 100644
index 0000000..f13cfb4
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-13-o32.t
@@ -0,0 +1,5 @@
+#...
+00400190 <main>:
+#...
+ 4001a0: 0c100070 jal 4001c0 <.iplt.func1>
+#pass
\ No newline at end of file
diff --git a/ld/testsuite/ld-mips-elf/ifunc-3-n32.r b/ld/testsuite/ld-mips-elf/ifunc-3-n32.r
new file mode 100644
index 0000000..b14c140
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-3-n32.r
@@ -0,0 +1,4 @@
+Relocation section '.rel.dyn' at offset 0x12000 contains 2 entries:
+ Offset Info Type Sym.Value Sym. Name
+00000000 00000000 R_MIPS_NONE
+00000800 00000080 R_MIPS_IRELATIVE
diff --git a/ld/testsuite/ld-mips-elf/ifunc-3-n32.sym b/ld/testsuite/ld-mips-elf/ifunc-3-n32.sym
new file mode 100644
index 0000000..a0a1c12
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-3-n32.sym
@@ -0,0 +1,3 @@
+#...
+ 2 0: 00000400 28 FUNC GLOBAL DEFAULT 1 func1
+#pass
\ No newline at end of file
diff --git a/ld/testsuite/ld-mips-elf/ifunc-3-n32.t b/ld/testsuite/ld-mips-elf/ifunc-3-n32.t
new file mode 100644
index 0000000..edf2787
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-3-n32.t
@@ -0,0 +1,10 @@
+tmpdir/ifunc-3-n32: file format elf32-ntradbigmips
+
+
+Disassembly of section .iplt:
+
+00000400 <.iplt.func1>:
+ 400: 3c0f0000 lui t3,0x0
+ 404: 8df90800 lw t9,2048\(t3\)
+ 408: 03200008 jr t9
+ 40c: 00000000 nop
diff --git a/ld/testsuite/ld-mips-elf/ifunc-3-n64.r b/ld/testsuite/ld-mips-elf/ifunc-3-n64.r
new file mode 100644
index 0000000..53b6455
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-3-n64.r
@@ -0,0 +1,8 @@
+Relocation section '.rel.dyn' at offset 0x12000 contains 2 entries:
+ Offset Info Type Sym. Value Sym. Name
+000000000000 000000000000 R_MIPS_NONE
+ Type2: R_MIPS_NONE
+ Type3: R_MIPS_NONE
+000000000800 000000000080 R_MIPS_IRELATIVE
+ Type2: R_MIPS_NONE
+ Type3: R_MIPS_NONE
diff --git a/ld/testsuite/ld-mips-elf/ifunc-3-n64.sym b/ld/testsuite/ld-mips-elf/ifunc-3-n64.sym
new file mode 100644
index 0000000..ea4760a
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-3-n64.sym
@@ -0,0 +1,3 @@
+#...
+ 2 0: 0000000000000400 28 FUNC GLOBAL DEFAULT 1 func1
+#pass
\ No newline at end of file
diff --git a/ld/testsuite/ld-mips-elf/ifunc-3-n64.t b/ld/testsuite/ld-mips-elf/ifunc-3-n64.t
new file mode 100644
index 0000000..0df1db2
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-3-n64.t
@@ -0,0 +1,11 @@
+tmpdir/ifunc-3-n64: file format elf64-tradbigmips
+
+
+Disassembly of section .iplt:
+
+0000000000000400 <.iplt.func1>:
+ 400: 3c0f0000 lui t3,0x0
+ 404: ddf90800 ld t9,2048\(t3\)
+ 408: 03200008 jr t9
+ 40c: 00000000 nop
+ ...
diff --git a/ld/testsuite/ld-mips-elf/ifunc-3-o32.r b/ld/testsuite/ld-mips-elf/ifunc-3-o32.r
new file mode 100644
index 0000000..b14c140
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-3-o32.r
@@ -0,0 +1,4 @@
+Relocation section '.rel.dyn' at offset 0x12000 contains 2 entries:
+ Offset Info Type Sym.Value Sym. Name
+00000000 00000000 R_MIPS_NONE
+00000800 00000080 R_MIPS_IRELATIVE
diff --git a/ld/testsuite/ld-mips-elf/ifunc-3-o32.sym b/ld/testsuite/ld-mips-elf/ifunc-3-o32.sym
new file mode 100644
index 0000000..034b158
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-3-o32.sym
@@ -0,0 +1,3 @@
+#...
+ 2 0: 00000400 40 FUNC GLOBAL DEFAULT 1 func1
+#pass
\ No newline at end of file
diff --git a/ld/testsuite/ld-mips-elf/ifunc-3-o32.t b/ld/testsuite/ld-mips-elf/ifunc-3-o32.t
new file mode 100644
index 0000000..eba438f
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-3-o32.t
@@ -0,0 +1,11 @@
+tmpdir/ifunc-3-o32: file format elf32-tradbigmips
+
+
+Disassembly of section .iplt:
+
+00000400 <.iplt.func1>:
+ 400: 3c0f0000 lui t7,0x0
+ 404: 8df90800 lw t9,2048\(t7\)
+ 408: 00000000 nop
+ 40c: 03200008 jr t9
+ 410: 00000000 nop
diff --git a/ld/testsuite/ld-mips-elf/ifunc-4-n32.r b/ld/testsuite/ld-mips-elf/ifunc-4-n32.r
new file mode 100644
index 0000000..e899ffc
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-4-n32.r
@@ -0,0 +1,3 @@
+Relocation section '.rel.dyn' at offset 0x11000 contains 1 entries:
+ Offset Info Type Sym.Value Sym. Name
+00080800 00000080 R_MIPS_IRELATIVE
diff --git a/ld/testsuite/ld-mips-elf/ifunc-4-n32.sym b/ld/testsuite/ld-mips-elf/ifunc-4-n32.sym
new file mode 100644
index 0000000..1a8f307
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-4-n32.sym
@@ -0,0 +1,4 @@
+#...
+ 22: 00080000 16 FUNC LOCAL DEFAULT 1 .iplt.func1
+ 23: 0008049c 156 IFUNC GLOBAL DEFAULT 2 func1
+#pass
\ No newline at end of file
diff --git a/ld/testsuite/ld-mips-elf/ifunc-4-n32.t b/ld/testsuite/ld-mips-elf/ifunc-4-n32.t
new file mode 100644
index 0000000..a681706
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-4-n32.t
@@ -0,0 +1,10 @@
+tmpdir/ifunc-4-n32: file format elf32-ntradbigmips
+
+
+Disassembly of section .iplt:
+
+00080000 <.iplt.func1>:
+ 80000: 3c0f0008 lui t3,0x8
+ 80004: 8df90800 lw t9,2048\(t3\)
+ 80008: 03200008 jr t9
+ 8000c: 00000000 nop
diff --git a/ld/testsuite/ld-mips-elf/ifunc-4-n64.r b/ld/testsuite/ld-mips-elf/ifunc-4-n64.r
new file mode 100644
index 0000000..695742b
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-4-n64.r
@@ -0,0 +1,5 @@
+Relocation section '.rel.dyn' at offset 0x11000 contains 1 entries:
+ Offset Info Type Sym. Value Sym. Name
+000000080800 000000000080 R_MIPS_IRELATIVE
+ Type2: R_MIPS_NONE
+ Type3: R_MIPS_NONE
diff --git a/ld/testsuite/ld-mips-elf/ifunc-4-n64.sym b/ld/testsuite/ld-mips-elf/ifunc-4-n64.sym
new file mode 100644
index 0000000..ed469d8
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-4-n64.sym
@@ -0,0 +1,4 @@
+#...
+ 22: 0000000000080000 32 FUNC LOCAL DEFAULT 1 .iplt.func1
+ 23: 000000000008049c 156 IFUNC GLOBAL DEFAULT 2 func1
+#pass
\ No newline at end of file
diff --git a/ld/testsuite/ld-mips-elf/ifunc-4-n64.t b/ld/testsuite/ld-mips-elf/ifunc-4-n64.t
new file mode 100644
index 0000000..bf5a2d2
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-4-n64.t
@@ -0,0 +1,11 @@
+tmpdir/ifunc-4-n64: file format elf64-tradbigmips
+
+
+Disassembly of section .iplt:
+
+0000000000080000 <.iplt.func1>:
+ 80000: 3c0f0008 lui t3,0x8
+ 80004: ddf90800 ld t9,2048\(t3\)
+ 80008: 03200008 jr t9
+ 8000c: 00000000 nop
+ ...
diff --git a/ld/testsuite/ld-mips-elf/ifunc-4-o32.r b/ld/testsuite/ld-mips-elf/ifunc-4-o32.r
new file mode 100644
index 0000000..e899ffc
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-4-o32.r
@@ -0,0 +1,3 @@
+Relocation section '.rel.dyn' at offset 0x11000 contains 1 entries:
+ Offset Info Type Sym.Value Sym. Name
+00080800 00000080 R_MIPS_IRELATIVE
diff --git a/ld/testsuite/ld-mips-elf/ifunc-4-o32.sym b/ld/testsuite/ld-mips-elf/ifunc-4-o32.sym
new file mode 100644
index 0000000..4e3ed8c
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-4-o32.sym
@@ -0,0 +1,4 @@
+#...
+ 17: 00080000 20 FUNC LOCAL DEFAULT 1 .iplt.func1
+ 18: 0008049c 156 IFUNC GLOBAL DEFAULT 2 func1
+#pass
\ No newline at end of file
diff --git a/ld/testsuite/ld-mips-elf/ifunc-4-o32.t b/ld/testsuite/ld-mips-elf/ifunc-4-o32.t
new file mode 100644
index 0000000..bc71cb0
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-4-o32.t
@@ -0,0 +1,11 @@
+tmpdir/ifunc-4-o32: file format elf32-tradbigmips
+
+
+Disassembly of section .iplt:
+
+00080000 <.iplt.func1>:
+ 80000: 3c0f0008 lui t7,0x8
+ 80004: 8df90800 lw t9,2048\(t7\)
+ 80008: 00000000 nop
+ 8000c: 03200008 jr t9
+ 80010: 00000000 nop
diff --git a/ld/testsuite/ld-mips-elf/ifunc-5-n32.g b/ld/testsuite/ld-mips-elf/ifunc-5-n32.g
new file mode 100644
index 0000000..884ca55
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-5-n32.g
@@ -0,0 +1,11 @@
+
+tmpdir/ifunc-5-n32: file format elf32-ntradbigmips
+
+
+Disassembly of section .got:
+
+00000400 <.got>:
+ 400: 00000000 nop
+ 404: 80000000 lb zero,0\(zero\)
+ 408: 0000000c syscall
+ ...
diff --git a/ld/testsuite/ld-mips-elf/ifunc-5-n32.r b/ld/testsuite/ld-mips-elf/ifunc-5-n32.r
new file mode 100644
index 0000000..aba5cb2
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-5-n32.r
@@ -0,0 +1,4 @@
+Relocation section '.rel.dyn' at offset 0x11000 contains 2 entries:
+ Offset Info Type Sym.Value Sym. Name
+00000000 00000000 R_MIPS_NONE
+00000408 00000203 R_MIPS_REL32 func1\(\) func1
diff --git a/ld/testsuite/ld-mips-elf/ifunc-5-n32.sym b/ld/testsuite/ld-mips-elf/ifunc-5-n32.sym
new file mode 100644
index 0000000..3dc0342
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-5-n32.sym
@@ -0,0 +1,4 @@
+#...
+ 2 0: 0000000c 28 IFUNC GLOBAL DEFAULT 1 func1
+ 4 1: 0000000c 28 FUNC GLOBAL DEFAULT 1 func1_ifunc
+#pass
\ No newline at end of file
diff --git a/ld/testsuite/ld-mips-elf/ifunc-5-n64.g b/ld/testsuite/ld-mips-elf/ifunc-5-n64.g
new file mode 100644
index 0000000..70911f2
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-5-n64.g
@@ -0,0 +1,12 @@
+
+tmpdir/ifunc-5-n64: file format elf64-tradbigmips
+
+
+Disassembly of section .got:
+
+0000000000000400 <.got>:
+ ...
+ 408: 80000000 lb zero,0\(zero\)
+ ...
+ 414: 0000000c syscall
+ ...
diff --git a/ld/testsuite/ld-mips-elf/ifunc-5-n64.r b/ld/testsuite/ld-mips-elf/ifunc-5-n64.r
new file mode 100644
index 0000000..49db321
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-5-n64.r
@@ -0,0 +1,8 @@
+Relocation section '.rel.dyn' at offset 0x11000 contains 2 entries:
+ Offset Info Type Sym. Value Sym. Name
+000000000000 000000000000 R_MIPS_NONE
+ Type2: R_MIPS_NONE
+ Type3: R_MIPS_NONE
+000000000410 000200001203 R_MIPS_REL32 func1\(\) func1
+ Type2: R_MIPS_64
+ Type3: R_MIPS_NONE
diff --git a/ld/testsuite/ld-mips-elf/ifunc-5-n64.sym b/ld/testsuite/ld-mips-elf/ifunc-5-n64.sym
new file mode 100644
index 0000000..483b13d
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-5-n64.sym
@@ -0,0 +1,4 @@
+#...
+ 2 0: 000000000000000c 28 IFUNC GLOBAL DEFAULT 1 func1
+ 4 1: 000000000000000c 28 FUNC GLOBAL DEFAULT 1 func1_ifunc
+#pass
\ No newline at end of file
diff --git a/ld/testsuite/ld-mips-elf/ifunc-5-o32.g b/ld/testsuite/ld-mips-elf/ifunc-5-o32.g
new file mode 100644
index 0000000..cf80f02
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-5-o32.g
@@ -0,0 +1,11 @@
+
+tmpdir/ifunc-5-o32: file format elf32-tradbigmips
+
+
+Disassembly of section .got:
+
+00000400 <.got>:
+ 400: 00000000 nop
+ 404: 80000000 lb zero,0\(zero\)
+ 408: 0000000c syscall
+ ...
diff --git a/ld/testsuite/ld-mips-elf/ifunc-5-o32.r b/ld/testsuite/ld-mips-elf/ifunc-5-o32.r
new file mode 100644
index 0000000..18bdec1
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-5-o32.r
@@ -0,0 +1,4 @@
+Relocation section '.rel.dyn' at offset 0x11000 contains 2 entries:
+ Offset Info Type Sym.Value Sym. Name
+00000000 00000000 R_MIPS_NONE
+00000408 00000303 R_MIPS_REL32 func1\(\) func1
diff --git a/ld/testsuite/ld-mips-elf/ifunc-5-o32.sym b/ld/testsuite/ld-mips-elf/ifunc-5-o32.sym
new file mode 100644
index 0000000..dd5ada4
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-5-o32.sym
@@ -0,0 +1,3 @@
+#...
+ 3 0: 0000000c 40 IFUNC GLOBAL DEFAULT 1 func1
+#pass
\ No newline at end of file
diff --git a/ld/testsuite/ld-mips-elf/ifunc-5.dyn b/ld/testsuite/ld-mips-elf/ifunc-5.dyn
new file mode 100644
index 0000000..4730fb9
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-5.dyn
@@ -0,0 +1,3 @@
+#...
+ 0x0*70000036 \(MIPS_GENERAL_GOTNO\).* 3
+#pass
\ No newline at end of file
diff --git a/ld/testsuite/ld-mips-elf/ifunc-6-n32.r b/ld/testsuite/ld-mips-elf/ifunc-6-n32.r
new file mode 100644
index 0000000..ad53c7e
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-6-n32.r
@@ -0,0 +1,4 @@
+Relocation section '.rel.dyn' at offset 0x11000 contains 2 entries:
+ Offset Info Type Sym.Value Sym. Name
+00000000 00000000 R_MIPS_NONE
+00000808 00000080 R_MIPS_IRELATIVE
diff --git a/ld/testsuite/ld-mips-elf/ifunc-6-n32.sym b/ld/testsuite/ld-mips-elf/ifunc-6-n32.sym
new file mode 100644
index 0000000..a0a1c12
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-6-n32.sym
@@ -0,0 +1,3 @@
+#...
+ 2 0: 00000400 28 FUNC GLOBAL DEFAULT 1 func1
+#pass
\ No newline at end of file
diff --git a/ld/testsuite/ld-mips-elf/ifunc-6-n64.r b/ld/testsuite/ld-mips-elf/ifunc-6-n64.r
new file mode 100644
index 0000000..7321380
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-6-n64.r
@@ -0,0 +1,8 @@
+Relocation section '.rel.dyn' at offset 0x11000 contains 2 entries:
+ Offset Info Type Sym. Value Sym. Name
+000000000000 000000000000 R_MIPS_NONE
+ Type2: R_MIPS_NONE
+ Type3: R_MIPS_NONE
+000000000810 000000000080 R_MIPS_IRELATIVE
+ Type2: R_MIPS_NONE
+ Type3: R_MIPS_NONE
diff --git a/ld/testsuite/ld-mips-elf/ifunc-6-n64.sym b/ld/testsuite/ld-mips-elf/ifunc-6-n64.sym
new file mode 100644
index 0000000..ea4760a
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-6-n64.sym
@@ -0,0 +1,3 @@
+#...
+ 2 0: 0000000000000400 28 FUNC GLOBAL DEFAULT 1 func1
+#pass
\ No newline at end of file
diff --git a/ld/testsuite/ld-mips-elf/ifunc-6-o32.r b/ld/testsuite/ld-mips-elf/ifunc-6-o32.r
new file mode 100644
index 0000000..ad53c7e
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-6-o32.r
@@ -0,0 +1,4 @@
+Relocation section '.rel.dyn' at offset 0x11000 contains 2 entries:
+ Offset Info Type Sym.Value Sym. Name
+00000000 00000000 R_MIPS_NONE
+00000808 00000080 R_MIPS_IRELATIVE
diff --git a/ld/testsuite/ld-mips-elf/ifunc-6-o32.sym b/ld/testsuite/ld-mips-elf/ifunc-6-o32.sym
new file mode 100644
index 0000000..034b158
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-6-o32.sym
@@ -0,0 +1,3 @@
+#...
+ 2 0: 00000400 40 FUNC GLOBAL DEFAULT 1 func1
+#pass
\ No newline at end of file
diff --git a/ld/testsuite/ld-mips-elf/ifunc-7-o32.r b/ld/testsuite/ld-mips-elf/ifunc-7-o32.r
new file mode 100644
index 0000000..761c7ee
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-7-o32.r
@@ -0,0 +1,3 @@
+Relocation section '.rel.dyn' at offset 0xe8 contains 1 entries:
+ Offset Info Type Sym.Value Sym. Name
+00410250 00000080 R_MIPS_IRELATIVE
diff --git a/ld/testsuite/ld-mips-elf/ifunc-7-o32.sec b/ld/testsuite/ld-mips-elf/ifunc-7-o32.sec
new file mode 100644
index 0000000..c904010
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-7-o32.sec
@@ -0,0 +1,4 @@
+#...
+.* \.iplt .*
+.* \.igot .*
+#pass
diff --git a/ld/testsuite/ld-mips-elf/ifunc-8-o32.g b/ld/testsuite/ld-mips-elf/ifunc-8-o32.g
new file mode 100644
index 0000000..6961a7f
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-8-o32.g
@@ -0,0 +1,6 @@
+#...
+00410170 <_GLOBAL_OFFSET_TABLE_>:
+ 410170: 00000000 nop
+ 410174: 80000000 lb zero,0\(zero\)
+ 410178: 004000fc 0x4000fc
+#pass
diff --git a/ld/testsuite/ld-mips-elf/ifunc-8-o32.r b/ld/testsuite/ld-mips-elf/ifunc-8-o32.r
new file mode 100644
index 0000000..ba4c7d6
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-8-o32.r
@@ -0,0 +1,3 @@
+Relocation section '.rel.dyn' at offset 0xe8 contains 1 entries:
+ Offset Info Type Sym.Value Sym. Name
+00410178 00000080 R_MIPS_IRELATIVE
diff --git a/ld/testsuite/ld-mips-elf/ifunc-8-o32.sec b/ld/testsuite/ld-mips-elf/ifunc-8-o32.sec
new file mode 100644
index 0000000..a0dfae2
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-8-o32.sec
@@ -0,0 +1,17 @@
+#...
+Section Headers:
+!.* \.iplt .*
+!.* \.iplt .*
+!.* \.iplt .*
+!.* \.iplt .*
+!.* \.iplt .*
+!.* \.iplt .*
+.* \.got .*
+!.* \.iplt .*
+!.* \.iplt .*
+!.* \.iplt .*
+!.* \.iplt .*
+!.* \.iplt .*
+!.* \.iplt .*
+!.* \.iplt .*
+#pass
\ No newline at end of file
diff --git a/ld/testsuite/ld-mips-elf/ifunc-9-o32.g b/ld/testsuite/ld-mips-elf/ifunc-9-o32.g
new file mode 100644
index 0000000..c470055
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-9-o32.g
@@ -0,0 +1,6 @@
+#...
+004101b0 <_GLOBAL_OFFSET_TABLE_>:
+ 4101b0: 00000000 nop
+ 4101b4: 80000000 lb zero,0\(zero\)
+ 4101b8: 0040010c syscall 0x10004
+#pass
diff --git a/ld/testsuite/ld-mips-elf/ifunc-9-o32.r b/ld/testsuite/ld-mips-elf/ifunc-9-o32.r
new file mode 100644
index 0000000..a2cedc8
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-9-o32.r
@@ -0,0 +1,4 @@
+Relocation section '.rel.dyn' at offset 0xe8 contains 2 entries:
+ Offset Info Type Sym.Value Sym. Name
+004101d8 00000080 R_MIPS_IRELATIVE
+00000000 00000000 R_MIPS_NONE
diff --git a/ld/testsuite/ld-mips-elf/ifunc-9-o32.sec b/ld/testsuite/ld-mips-elf/ifunc-9-o32.sec
new file mode 100644
index 0000000..39c7712
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-9-o32.sec
@@ -0,0 +1,17 @@
+#...
+Section Headers:
+!.* \.igot .*
+!.* \.igot .*
+!.* \.igot .*
+!.* \.igot .*
+!.* \.igot .*
+!.* \.igot .*
+.* \.iplt .*
+.* \.got .*
+!.* \.igot .*
+!.* \.igot .*
+!.* \.igot .*
+!.* \.igot .*
+!.* \.igot .*
+!.* \.igot .*
+#pass
\ No newline at end of file
diff --git a/ld/testsuite/ld-mips-elf/ifunc-9-o32.t b/ld/testsuite/ld-mips-elf/ifunc-9-o32.t
new file mode 100644
index 0000000..ca3f48b
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-9-o32.t
@@ -0,0 +1,8 @@
+#...
+00400190 <.iplt.func1>:
+ 400190: 3c0f0041 lui t7,0x41
+ 400194: 8df901b8 lw t9,440\(t7\)
+ 400198: 00000000 nop
+ 40019c: 03200008 jr t9
+ 4001a0: 00000000 nop
+#pass
\ No newline at end of file
diff --git a/ld/testsuite/ld-mips-elf/ifunc-dyn-def.s b/ld/testsuite/ld-mips-elf/ifunc-dyn-def.s
new file mode 100644
index 0000000..9b5d2a8
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-dyn-def.s
@@ -0,0 +1,67 @@
+ .file 1 "ifunc.c"
+ .section .mdebug.abi32
+ .previous
+ .nan legacy
+ .gnu_attribute 4, 1
+ .abicalls
+ .text
+ .align 2
+ .set nomips16
+ .set nomicromips
+ .ent f1_a
+ .type f1_a, @function
+f1_a:
+ nop
+
+ .set macro
+ .set reorder
+ .end f1_a
+ .size f1_a, .-f1_a
+ .align 2
+ .set nomips16
+ .set nomicromips
+ .ent f1_b
+ .type f1_b, @function
+f1_b:
+ nop
+
+ .set macro
+ .set reorder
+ .end f1_b
+ .size f1_b, .-f1_b
+ .align 2
+ .set nomips16
+ .set nomicromips
+ .ent f1_c
+ .type f1_c, @function
+f1_c:
+ .frame $fp,8,$31 # vars= 0, regs= 1/0, args= 0, gp= 0
+ nop
+
+ .set macro
+ .set reorder
+ .end f1_c
+ .size f1_c, .-f1_c
+ .align 2
+ .globl func1_ifunc
+ .set nomips16
+ .set nomicromips
+ .ent func1_ifunc
+ .type func1_ifunc, @function
+func1_ifunc:
+ lw $2,%got(f1_a)($28)
+ addiu $2,$2,%lo(f1_a)
+ lw $2,%got(f1_b)($28)
+ addiu $2,$2,%lo(f1_b)
+ lw $2,%got(f1_c)($28)
+ addiu $2,$2,%lo(f1_c)
+ nop
+
+ .set macro
+ .set reorder
+ .end func1_ifunc
+ .size func1_ifunc, .-func1_ifunc
+ .globl func1
+ .type func1, @gnu_indirect_function
+ func1 = func1_ifunc
+ .ident "GCC: (GNU) 4.9.0 20130917 (experimental)"
diff --git a/ld/testsuite/ld-mips-elf/ifunc-dyn-main.s b/ld/testsuite/ld-mips-elf/ifunc-dyn-main.s
new file mode 100644
index 0000000..8c12176
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-dyn-main.s
@@ -0,0 +1,39 @@
+ .file 1 "ifunc_ref_main_2.c"
+ .section .mdebug.abi32
+ .previous
+ .nan legacy
+ .gnu_attribute 4, 1
+ .abicalls
+ .option pic0
+ .text
+ .align 2
+ .globl main
+ .set nomips16
+ .set nomicromips
+ .ent main
+ .type main, @function
+main:
+ .frame $fp,32,$31 # vars= 0, regs= 2/0, args= 16, gp= 8
+ .mask 0xc0000000,-4
+ .fmask 0x00000000,0
+ .set noreorder
+ .set nomacro
+ addiu $sp,$sp,-32
+ sw $31,28($sp)
+ sw $fp,24($sp)
+ move $fp,$sp
+ jal ref1
+ nop
+
+ move $sp,$fp
+ lw $31,28($sp)
+ lw $fp,24($sp)
+ addiu $sp,$sp,32
+ j $31
+ nop
+
+ .set macro
+ .set reorder
+ .end main
+ .size main, .-main
+ .ident "GCC: (GNU) 4.9.0 20130930 (experimental)"
diff --git a/ld/testsuite/ld-mips-elf/ifunc-dyn-ref.s b/ld/testsuite/ld-mips-elf/ifunc-dyn-ref.s
new file mode 100644
index 0000000..d562096
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-dyn-ref.s
@@ -0,0 +1,43 @@
+ .file 1 "ifunc_ref.c"
+ .section .mdebug.abi32
+ .previous
+ .nan legacy
+ .gnu_attribute 4, 1
+ .abicalls
+ .text
+ .align 2
+ .globl ref1
+ .set nomips16
+ .set nomicromips
+ .ent ref1
+ .type ref1, @function
+ref1:
+ .frame $fp,32,$31 # vars= 0, regs= 2/0, args= 16, gp= 8
+ .mask 0xc0000000,-4
+ .fmask 0x00000000,0
+ .set noreorder
+ .cpload $25
+ .set nomacro
+ addiu $sp,$sp,-32
+ sw $31,28($sp)
+ sw $fp,24($sp)
+ move $fp,$sp
+ .cprestore 16
+ lw $2,%call16(func1)($28)
+ move $25,$2
+ jalr $25
+ nop
+
+ lw $28,16($fp)
+ move $sp,$fp
+ lw $31,28($sp)
+ lw $fp,24($sp)
+ addiu $sp,$sp,32
+ j $31
+ nop
+
+ .set macro
+ .set reorder
+ .end ref1
+ .size ref1, .-ref1
+ .ident "GCC: (GNU) 4.9.0 20130930 (experimental)"
diff --git a/ld/testsuite/ld-mips-elf/ifunc-dyn.ld b/ld/testsuite/ld-mips-elf/ifunc-dyn.ld
new file mode 100644
index 0000000..c82c8ce
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-dyn.ld
@@ -0,0 +1,25 @@
+ENTRY(_start)
+SECTIONS
+{
+ . = ALIGN (0x400);
+ .text : { *(.text) }
+
+ . = ALIGN (0x400);
+ .iplt : { *(.iplt) }
+
+ . = ALIGN (0x400);
+ .igot : { *(.igot) }
+
+ . = ALIGN (0x400);
+ .got : { *(.got) }
+
+ . = ALIGN (0x400);
+ .data : { *(.data) }
+
+ . = ALIGN (0x1000);
+ .rel.dyn :
+ {
+ *(.rel.*)
+ }
+
+}
diff --git a/ld/testsuite/ld-mips-elf/ifunc-iplt-0x400000.t b/ld/testsuite/ld-mips-elf/ifunc-iplt-0x400000.t
new file mode 100644
index 0000000..c46a85d
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-iplt-0x400000.t
@@ -0,0 +1,11 @@
+tmpdir/ifunc-iplt-0x400000: file format elf64-tradbigmips
+
+
+Disassembly of section .iplt:
+
+0000000000400188 <.iplt.func1>:
+ 400188: 3c0f0041 lui t3,0x41
+ 40018c: ddf90320 ld t9,800\(t3\)
+ 400190: 03200008 jr t9
+ 400194: 00000000 nop
+ ...
diff --git a/ld/testsuite/ld-mips-elf/ifunc-iplt-0x400000000.t b/ld/testsuite/ld-mips-elf/ifunc-iplt-0x400000000.t
new file mode 100644
index 0000000..3562b23
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-iplt-0x400000000.t
@@ -0,0 +1,13 @@
+tmpdir/ifunc-iplt-0x400000000: file format elf64-tradbigmips
+
+
+Disassembly of section .iplt:
+
+0000000400000188 <.iplt.func1>:
+ 400000188: 3c0f0004 lui t3,0x4
+ 40000018c: 25ef0001 addiu t3,t3,1
+ 400000190: 000f7c38 dsll t3,t3,0x10
+ 400000194: ddf90320 ld t9,800\(t3\)
+ 400000198: 03200008 jr t9
+ 40000019c: 00000000 nop
+ ...
diff --git a/ld/testsuite/ld-mips-elf/ifunc-iplt-0x4000000000000.t b/ld/testsuite/ld-mips-elf/ifunc-iplt-0x4000000000000.t
new file mode 100644
index 0000000..90e8306
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-iplt-0x4000000000000.t
@@ -0,0 +1,14 @@
+tmpdir/ifunc-iplt-0x4000000000000: file format elf64-tradbigmips
+
+
+Disassembly of section .iplt:
+
+0004000000000188 <.iplt.func1>:
+ 4000000000188: 3c0f0004 lui t3,0x4
+ 400000000018c: 3c0e0001 lui t2,0x1
+ 4000000000190: 25ef0000 addiu t3,t3,0
+ 4000000000194: 000f783c dsll32 t3,t3,0x0
+ 4000000000198: 01ee782d daddu t3,t3,t2
+ 400000000019c: ddf90320 ld t9,800\(t3\)
+ 40000000001a0: 03200008 jr t9
+ 40000000001a4: 00000000 nop
diff --git a/ld/testsuite/ld-mips-elf/ifunc-iplt-micromips.igot b/ld/testsuite/ld-mips-elf/ifunc-iplt-micromips.igot
new file mode 100644
index 0000000..b9844dc
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-iplt-micromips.igot
@@ -0,0 +1,7 @@
+tmpdir/ifunc-iplt-micromips: file format elf32-tradbigmips
+
+
+Disassembly of section .igot:
+
+004101d0 <_fdata>:
+ 4101d0: 0040014d break 0x40,0x5
diff --git a/ld/testsuite/ld-mips-elf/ifunc-iplt-micromips.t b/ld/testsuite/ld-mips-elf/ifunc-iplt-micromips.t
new file mode 100644
index 0000000..bc2f2a9
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-iplt-micromips.t
@@ -0,0 +1,9 @@
+tmpdir/ifunc-iplt-micromips: file format elf32-tradbigmips
+
+
+Disassembly of section .iplt:
+
+004001c0 <.iplt.func1>:
+ 4001c0: 41a3 0041 lui v1,0x41
+ 4001c4: ff23 01d0 lw t9,464\(v1\)
+ 4001c8: 45b9 jrc t9
diff --git a/ld/testsuite/ld-mips-elf/ifunc-iplt-mips16.igot b/ld/testsuite/ld-mips-elf/ifunc-iplt-mips16.igot
new file mode 100644
index 0000000..78f2988
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-iplt-mips16.igot
@@ -0,0 +1,8 @@
+
+tmpdir/ifunc-iplt-mips16: file format elf32-tradbigmips
+
+
+Disassembly of section .igot:
+
+00410190 <.igot>:
+ 410190: 00400125 0x400125
diff --git a/ld/testsuite/ld-mips-elf/ifunc-iplt-mips16.t b/ld/testsuite/ld-mips-elf/ifunc-iplt-mips16.t
new file mode 100644
index 0000000..564083d
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-iplt-mips16.t
@@ -0,0 +1,12 @@
+tmpdir/ifunc-iplt-mips16: file format elf32-tradbigmips
+
+
+Disassembly of section .iplt:
+
+00400170 <.iplt.func1>:
+ 400170: b202 lw v0,400178 <.iplt.func1\+0x8>
+ 400172: 9a60 lw v1,0\(v0\)
+ 400174: eb00 jr v1
+ 400176: 653b move t9,v1
+ 400178: 0041 addiu s0,sp,260
+ 40017a: 0190 addiu s1,sp,576
diff --git a/ld/testsuite/ld-mips-elf/ifunc-iplt-mips32r6.t b/ld/testsuite/ld-mips-elf/ifunc-iplt-mips32r6.t
new file mode 100644
index 0000000..5250ffe
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-iplt-mips32r6.t
@@ -0,0 +1,11 @@
+
+tmpdir/ifunc-iplt-mips32r6: file format elf32-tradbigmips
+
+
+Disassembly of section .iplt:
+
+00400230 <.iplt.func1>:
+ 400230: 3c0f0041 lui t7,0x41
+ 400234: 8df90240 lw t9,576\(t7\)
+ 400238: 03200009 jr t9
+ 40023c: 00000000 nop
diff --git a/ld/testsuite/ld-mips-elf/ifunc-iplt.ld b/ld/testsuite/ld-mips-elf/ifunc-iplt.ld
new file mode 100644
index 0000000..a26b803
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-iplt.ld
@@ -0,0 +1,26 @@
+ENTRY(_start)
+SECTIONS
+{
+ . = ALIGN (0x400);
+ .iplt : { *(.iplt) }
+
+ . = ALIGN (0x400);
+ .text : { *(.text) }
+
+ . = ALIGN (0x400);
+ .igot : { *(.igot) }
+
+ . = ALIGN (0x400);
+ .got : { *(.got) }
+
+ . = ALIGN (0x400);
+ .data : { *(.data) }
+
+ . = ALIGN (0x1000);
+ .rel.dyn :
+ {
+ *(.rel.*)
+ }
+/* /DISCARD/ : { *(*) } */
+
+}
diff --git a/ld/testsuite/ld-mips-elf/ifunc-local-1.s b/ld/testsuite/ld-mips-elf/ifunc-local-1.s
new file mode 100644
index 0000000..3b839d1
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-local-1.s
@@ -0,0 +1,176 @@
+ .section .mdebug.abi32
+ .previous
+ .abicalls
+ .option pic0
+ .text
+ .align 2
+ .ent f1_a
+ .type f1_a, @function
+f1_a:
+ .frame $fp,8,$31 # vars= 0, regs= 1/0, args= 0, gp= 0
+ .mask 0x40000000,-4
+ .fmask 0x00000000,0
+ .set noreorder
+ .set nomacro
+ addiu $sp,$sp,-8
+ sw $fp,4($sp)
+ move $fp,$sp
+ li $2,1 # 0x1
+ move $sp,$fp
+ lw $fp,4($sp)
+ addiu $sp,$sp,8
+ j $31
+ nop
+
+ .set macro
+ .set reorder
+ .end f1_a
+ .size f1_a, .-f1_a
+ .align 2
+ .ent f1_b
+ .type f1_b, @function
+f1_b:
+ .frame $fp,8,$31 # vars= 0, regs= 1/0, args= 0, gp= 0
+ .mask 0x40000000,-4
+ .fmask 0x00000000,0
+ .set noreorder
+ .set nomacro
+ addiu $sp,$sp,-8
+ sw $fp,4($sp)
+ move $fp,$sp
+ li $2,2 # 0x2
+ move $sp,$fp
+ lw $fp,4($sp)
+ addiu $sp,$sp,8
+ j $31
+ nop
+
+ .set macro
+ .set reorder
+ .end f1_b
+ .size f1_b, .-f1_b
+ .align 2
+ .ent f1_c
+ .type f1_c, @function
+f1_c:
+ .frame $fp,8,$31 # vars= 0, regs= 1/0, args= 0, gp= 0
+ .mask 0x40000000,-4
+ .fmask 0x00000000,0
+ .set noreorder
+ .set nomacro
+ addiu $sp,$sp,-8
+ sw $fp,4($sp)
+ move $fp,$sp
+ li $2,3 # 0x3
+ move $sp,$fp
+ lw $fp,4($sp)
+ addiu $sp,$sp,8
+ j $31
+ nop
+
+ .set macro
+ .set reorder
+ .end f1_c
+ .size f1_c, .-f1_c
+ .align 2
+ .globl func1_ifunc
+ .ent func1_ifunc
+ .type func1_ifunc, @function
+func1_ifunc:
+ .frame $fp,432,$31 # vars= 400, regs= 2/0, args= 16, gp= 8
+ .mask 0xc0000000,-4
+ .fmask 0x00000000,0
+ .set noreorder
+ .set nomacro
+ addiu $sp,$sp,-432
+ sw $31,428($sp)
+ sw $fp,424($sp)
+ move $fp,$sp
+ addiu $2,$fp,28
+ move $4,$2
+ nop
+
+ beq $2,$0,$L8
+ nop
+
+ li $2,48 # 0x30
+ sw $2,24($fp)
+ j $L9
+ nop
+
+$L8:
+ li $2,3 # 0x3
+ sw $2,24($fp)
+$L9:
+ lw $2,24($fp)
+ andi $2,$2,0xf0
+ beq $2,$0,$L10
+ nop
+
+ lui $2,%hi(f1_a)
+ addiu $2,$2,%lo(f1_a)
+ j $L13
+ nop
+
+$L10:
+ lw $2,24($fp)
+ andi $2,$2,0xf
+ beq $2,$0,$L12
+ nop
+
+ lui $2,%hi(f1_b)
+ addiu $2,$2,%lo(f1_b)
+ j $L13
+ nop
+
+$L12:
+ lui $2,%hi(f1_c)
+ addiu $2,$2,%lo(f1_c)
+$L13:
+ move $sp,$fp
+ lw $31,428($sp)
+ lw $fp,424($sp)
+ addiu $sp,$sp,432
+ j $31
+ nop
+
+ .set macro
+ .set reorder
+ .end func1_ifunc
+ .size func1_ifunc, .-func1_ifunc
+ .type func1, @gnu_indirect_function
+ func1 = func1_ifunc
+
+
+ .align 2
+ .globl main
+ .set nomips16
+ .set nomicromips
+ .ent main
+ .option pic0
+ .type main, @function
+main:
+ .frame $fp,32,$31 # vars= 0, regs= 2/0, args= 16, gp= 8
+ .mask 0xc0000000,-4
+ .fmask 0x00000000,0
+ .set noreorder
+ .set nomacro
+ addiu $sp,$sp,-32
+ sw $31,28($sp)
+ sw $fp,24($sp)
+ move $fp,$sp
+ jal func1
+ nop
+
+ move $sp,$fp
+ lw $31,28($sp)
+ lw $fp,24($sp)
+ addiu $sp,$sp,32
+ j $31
+ nop
+
+ .set macro
+ .set reorder
+ .end main
+ .size main, .-main
+ .ident "GCC: (GNU) 4.9.0 20130930 (experimental)"
diff --git a/ld/testsuite/ld-mips-elf/ifunc-local-2.s b/ld/testsuite/ld-mips-elf/ifunc-local-2.s
new file mode 100644
index 0000000..5872e3b
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-local-2.s
@@ -0,0 +1,99 @@
+ .section .mdebug.abi32
+ .previous
+ .nan legacy
+ .gnu_attribute 4, 1
+ .abicalls
+ .text
+ .align 2
+ .set nomips16
+ .set nomicromips
+ .ent f1_a
+ .type f1_a, @function
+f1_a:
+ nop
+
+ .set macro
+ .set reorder
+ .end f1_a
+ .size f1_a, .-f1_a
+ .align 2
+ .set nomips16
+ .set nomicromips
+ .ent f1_b
+ .type f1_b, @function
+f1_b:
+ nop
+
+ .set macro
+ .set reorder
+ .end f1_b
+ .size f1_b, .-f1_b
+ .align 2
+ .set nomips16
+ .set nomicromips
+ .ent f1_c
+ .type f1_c, @function
+f1_c:
+ .frame $fp,8,$31 # vars= 0, regs= 1/0, args= 0, gp= 0
+ nop
+
+ .set macro
+ .set reorder
+ .end f1_c
+ .size f1_c, .-f1_c
+ .align 2
+ .globl func1_ifunc
+ .set nomips16
+ .set nomicromips
+ .ent func1_ifunc
+ .type func1_ifunc, @function
+func1_ifunc:
+ lw $2,%got(f1_a)($28)
+ addiu $2,$2,%lo(f1_a)
+ lw $2,%got(f1_b)($28)
+ addiu $2,$2,%lo(f1_b)
+ lw $2,%got(f1_c)($28)
+ addiu $2,$2,%lo(f1_c)
+ nop
+
+ .set macro
+ .set reorder
+ .end func1_ifunc
+ .size func1_ifunc, .-func1_ifunc
+ .type func1, @gnu_indirect_function
+ func1 = func1_ifunc
+
+ .align 2
+ .globl main
+ .set nomips16
+ .set nomicromips
+ .ent main
+ .type main, @function
+main:
+ .frame $fp,32,$31 # vars= 0, regs= 2/0, args= 16, gp= 8
+ .mask 0xc0000000,-4
+ .fmask 0x00000000,0
+ .set noreorder
+ .cpload $25
+ .set nomacro
+ addiu $sp,$sp,-32
+ sw $31,28($sp)
+ sw $fp,24($sp)
+ move $fp,$sp
+ .cprestore 16
+ lw $2,%call16(func1)($28)
+ move $25,$2
+1: jalr $25
+ nop
+ move $sp,$fp
+ lw $31,28($sp)
+ lw $fp,24($sp)
+ addiu $sp,$sp,32
+ j $31
+ nop
+
+ .set macro
+ .set reorder
+ .end main
+ .size main, .-main
+ .ident "GCC: (GNU) 4.9.0 20130930 (experimental)"
diff --git a/ld/testsuite/ld-mips-elf/ifunc-local-3.s b/ld/testsuite/ld-mips-elf/ifunc-local-3.s
new file mode 100644
index 0000000..779c3ce
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-local-3.s
@@ -0,0 +1,135 @@
+ .section .mdebug.abi32
+ .previous
+ .nan legacy
+ .gnu_attribute 4, 1
+ .abicalls
+ .text
+ .align 2
+ .set nomips16
+ .set nomicromips
+ .ent f1_a
+ .type f1_a, @function
+f1_a:
+ nop
+
+ .set macro
+ .set reorder
+ .end f1_a
+ .size f1_a, .-f1_a
+ .align 2
+ .set nomips16
+ .set nomicromips
+ .ent f1_b
+ .type f1_b, @function
+f1_b:
+ nop
+
+ .set macro
+ .set reorder
+ .end f1_b
+ .size f1_b, .-f1_b
+ .align 2
+ .set nomips16
+ .set nomicromips
+ .ent f1_c
+ .type f1_c, @function
+f1_c:
+ .frame $fp,8,$31 # vars= 0, regs= 1/0, args= 0, gp= 0
+ nop
+
+ .set macro
+ .set reorder
+ .end f1_c
+ .size f1_c, .-f1_c
+ .align 2
+ .globl func1_ifunc
+ .set nomips16
+ .set nomicromips
+ .ent func1_ifunc
+ .type func1_ifunc, @function
+func1_ifunc:
+ lw $2,%got(f1_a)($28)
+ addiu $2,$2,%lo(f1_a)
+ lw $2,%got(f1_b)($28)
+ addiu $2,$2,%lo(f1_b)
+ lw $2,%got(f1_c)($28)
+ addiu $2,$2,%lo(f1_c)
+ nop
+
+ .set macro
+ .set reorder
+ .end func1_ifunc
+ .size func1_ifunc, .-func1_ifunc
+ .type func1, @gnu_indirect_function
+ func1 = func1_ifunc
+
+ .option pic0
+ .text
+ .align 2
+ .globl ref1
+ .ent ref1
+ .type ref1, @function
+ref1:
+ .frame $fp,32,$31 # vars= 0, regs= 2/0, args= 16, gp= 8
+ .mask 0xc0000000,-4
+ .fmask 0x00000000,0
+ .set noreorder
+ .set nomacro
+ addiu $sp,$sp,-32
+ sw $31,28($sp)
+ sw $fp,24($sp)
+ move $fp,$sp
+ jal func1
+ nop
+
+ move $sp,$fp
+ lw $31,28($sp)
+ lw $fp,24($sp)
+ addiu $sp,$sp,32
+ j $31
+ nop
+
+ .set macro
+ .set reorder
+ .end ref1
+ .size ref1, .-ref1
+
+ .align 2
+ .globl main
+ .set nomips16
+ .set nomicromips
+ .globl main
+ .ent main
+ .type main, @function
+main:
+ .frame $fp,32,$31 # vars= 0, regs= 2/0, args= 16, gp= 8
+ .mask 0xc0000000,-4
+ .fmask 0x00000000,0
+ .set noreorder
+ .cpload $25
+ .set nomacro
+ addiu $sp,$sp,-32
+ sw $31,28($sp)
+ sw $fp,24($sp)
+ move $fp,$sp
+ .cprestore 16
+ lw $2,%call16(func1)($28)
+ move $25,$2
+ jalr $25
+ nop
+
+ jal ref1
+ nop
+
+ lw $28,16($fp)
+ move $sp,$fp
+ lw $31,28($sp)
+ lw $fp,24($sp)
+ addiu $sp,$sp,32
+ j $31
+ nop
+
+ .set macro
+ .set reorder
+ .end main
+ .size main, .-main
diff --git a/ld/testsuite/ld-mips-elf/ifunc-local-4.s b/ld/testsuite/ld-mips-elf/ifunc-local-4.s
new file mode 100644
index 0000000..c57a32f
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-local-4.s
@@ -0,0 +1,183 @@
+ .section .mdebug.abi32
+ .previous
+ .abicalls
+ .option pic0
+ .text
+ .align 2
+ .ent f1_a
+ .type f1_a, @function
+f1_a:
+ .frame $fp,8,$31 # vars= 0, regs= 1/0, args= 0, gp= 0
+ .mask 0x40000000,-4
+ .fmask 0x00000000,0
+ .set noreorder
+ .set nomacro
+ addiu $sp,$sp,-8
+ sw $fp,4($sp)
+ move $fp,$sp
+ li $2,1 # 0x1
+ move $sp,$fp
+ lw $fp,4($sp)
+ addiu $sp,$sp,8
+ j $31
+ nop
+
+ .set macro
+ .set reorder
+ .end f1_a
+ .size f1_a, .-f1_a
+ .align 2
+ .ent f1_b
+ .type f1_b, @function
+f1_b:
+ .frame $fp,8,$31 # vars= 0, regs= 1/0, args= 0, gp= 0
+ .mask 0x40000000,-4
+ .fmask 0x00000000,0
+ .set noreorder
+ .set nomacro
+ addiu $sp,$sp,-8
+ sw $fp,4($sp)
+ move $fp,$sp
+ li $2,2 # 0x2
+ move $sp,$fp
+ lw $fp,4($sp)
+ addiu $sp,$sp,8
+ j $31
+ nop
+
+ .set macro
+ .set reorder
+ .end f1_b
+ .size f1_b, .-f1_b
+ .align 2
+ .ent f1_c
+ .type f1_c, @function
+f1_c:
+ .frame $fp,8,$31 # vars= 0, regs= 1/0, args= 0, gp= 0
+ .mask 0x40000000,-4
+ .fmask 0x00000000,0
+ .set noreorder
+ .set nomacro
+ addiu $sp,$sp,-8
+ sw $fp,4($sp)
+ move $fp,$sp
+ li $2,3 # 0x3
+ move $sp,$fp
+ lw $fp,4($sp)
+ addiu $sp,$sp,8
+ j $31
+ nop
+
+ .set macro
+ .set reorder
+ .end f1_c
+ .size f1_c, .-f1_c
+ .align 2
+ .globl func1_ifunc
+ .ent func1_ifunc
+ .type func1_ifunc, @function
+func1_ifunc:
+ .frame $fp,432,$31 # vars= 400, regs= 2/0, args= 16, gp= 8
+ .mask 0xc0000000,-4
+ .fmask 0x00000000,0
+ .set noreorder
+ .set nomacro
+ addiu $sp,$sp,-432
+ sw $31,428($sp)
+ sw $fp,424($sp)
+ move $fp,$sp
+ addiu $2,$fp,28
+ move $4,$2
+ nop
+
+ beq $2,$0,$L8
+ nop
+
+ li $2,48 # 0x30
+ sw $2,24($fp)
+ j $L9
+ nop
+
+$L8:
+ li $2,3 # 0x3
+ sw $2,24($fp)
+$L9:
+ lw $2,24($fp)
+ andi $2,$2,0xf0
+ beq $2,$0,$L10
+ nop
+
+ lui $2,%hi(f1_a)
+ addiu $2,$2,%lo(f1_a)
+ j $L13
+ nop
+
+$L10:
+ lw $2,24($fp)
+ andi $2,$2,0xf
+ beq $2,$0,$L12
+ nop
+
+ lui $2,%hi(f1_b)
+ addiu $2,$2,%lo(f1_b)
+ j $L13
+ nop
+
+$L12:
+ lui $2,%hi(f1_c)
+ addiu $2,$2,%lo(f1_c)
+$L13:
+ move $sp,$fp
+ lw $31,428($sp)
+ lw $fp,424($sp)
+ addiu $sp,$sp,432
+ j $31
+ nop
+
+ .set macro
+ .set reorder
+ .end func1_ifunc
+ .size func1_ifunc, .-func1_ifunc
+ .type func1, @gnu_indirect_function
+ func1 = func1_ifunc
+
+
+ .align 2
+ .globl main
+ .set nomips16
+ .set nomicromips
+ .ent main
+ .option pic0
+ .type main, @function
+main:
+ .frame $fp,32,$31 # vars= 0, regs= 2/0, args= 16, gp= 8
+ .mask 0xc0000000,-4
+ .fmask 0x00000000,0
+ .set noreorder
+ .set nomacro
+ addiu $sp,$sp,-32
+ sw $31,28($sp)
+ sw $fp,24($sp)
+ move $fp,$sp
+ jal func1
+ nop
+
+ move $sp,$fp
+ lw $31,28($sp)
+ lw $fp,24($sp)
+ addiu $sp,$sp,32
+ j $31
+ nop
+
+ .set macro
+ .set reorder
+ .end main
+ .size main, .-main
+
+ .section .data.rel,"aw",@progbits
+ .align 2
+ .type fptr, @object
+ .size fptr, 4
+fptr:
+ .word func1
+ .ident "GCC: (GNU) 4.9.0 20130930 (experimental)"
diff --git a/ld/testsuite/ld-mips-elf/ifunc-local-5.s b/ld/testsuite/ld-mips-elf/ifunc-local-5.s
new file mode 100644
index 0000000..684303f
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-local-5.s
@@ -0,0 +1,106 @@
+ .section .mdebug.abi32
+ .previous
+ .nan legacy
+ .gnu_attribute 4, 1
+ .abicalls
+ .text
+ .align 2
+ .set nomips16
+ .set nomicromips
+ .ent f1_a
+ .type f1_a, @function
+f1_a:
+ nop
+
+ .set macro
+ .set reorder
+ .end f1_a
+ .size f1_a, .-f1_a
+ .align 2
+ .set nomips16
+ .set nomicromips
+ .ent f1_b
+ .type f1_b, @function
+f1_b:
+ nop
+
+ .set macro
+ .set reorder
+ .end f1_b
+ .size f1_b, .-f1_b
+ .align 2
+ .set nomips16
+ .set nomicromips
+ .ent f1_c
+ .type f1_c, @function
+f1_c:
+ .frame $fp,8,$31 # vars= 0, regs= 1/0, args= 0, gp= 0
+ nop
+
+ .set macro
+ .set reorder
+ .end f1_c
+ .size f1_c, .-f1_c
+ .align 2
+ .globl func1_ifunc
+ .set nomips16
+ .set nomicromips
+ .ent func1_ifunc
+ .type func1_ifunc, @function
+func1_ifunc:
+ lw $2,%got(f1_a)($28)
+ addiu $2,$2,%lo(f1_a)
+ lw $2,%got(f1_b)($28)
+ addiu $2,$2,%lo(f1_b)
+ lw $2,%got(f1_c)($28)
+ addiu $2,$2,%lo(f1_c)
+ nop
+
+ .set macro
+ .set reorder
+ .end func1_ifunc
+ .size func1_ifunc, .-func1_ifunc
+ .type func1, @gnu_indirect_function
+ func1 = func1_ifunc
+
+ .align 2
+ .globl main
+ .set nomips16
+ .set nomicromips
+ .ent main
+ .type main, @function
+main:
+ .frame $fp,32,$31 # vars= 0, regs= 2/0, args= 16, gp= 8
+ .mask 0xc0000000,-4
+ .fmask 0x00000000,0
+ .set noreorder
+ .cpload $25
+ .set nomacro
+ addiu $sp,$sp,-32
+ sw $31,28($sp)
+ sw $fp,24($sp)
+ move $fp,$sp
+ .cprestore 16
+ lw $2,%call16(func1)($28)
+ move $25,$2
+ .reloc 1f,R_MIPS_JALR,func1
+1: jalr $25
+ nop
+ move $sp,$fp
+ lw $31,28($sp)
+ lw $fp,24($sp)
+ addiu $sp,$sp,32
+ j $31
+ nop
+
+ .set macro
+ .set reorder
+ .end main
+ .size main, .-main
+ .section .data.rel,"aw",@progbits
+ .align 2
+ .type fptr, @object
+ .size fptr, 4
+fptr:
+ .word func1
+ .ident "GCC: (GNU) 4.9.0 20130930 (experimental)"
diff --git a/ld/testsuite/ld-mips-elf/ifunc-local-6.s b/ld/testsuite/ld-mips-elf/ifunc-local-6.s
new file mode 100644
index 0000000..6cf12c3
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-local-6.s
@@ -0,0 +1,112 @@
+ .section .mdebug.abi32
+ .previous
+ .nan legacy
+ .gnu_attribute 4, 1
+ .abicalls
+ .text
+ .align 2
+ .set nomips16
+ .set nomicromips
+ .ent f1_a
+ .type f1_a, @function
+f1_a:
+ nop
+
+ .set macro
+ .set reorder
+ .end f1_a
+ .size f1_a, .-f1_a
+ .align 2
+ .set nomips16
+ .set nomicromips
+ .ent f1_b
+ .type f1_b, @function
+f1_b:
+ nop
+
+ .set macro
+ .set reorder
+ .end f1_b
+ .size f1_b, .-f1_b
+ .align 2
+ .set nomips16
+ .set nomicromips
+ .ent f1_c
+ .type f1_c, @function
+f1_c:
+ .frame $fp,8,$31 # vars= 0, regs= 1/0, args= 0, gp= 0
+ nop
+
+ .set macro
+ .set reorder
+ .end f1_c
+ .size f1_c, .-f1_c
+ .align 2
+ .globl func1_ifunc
+ .set nomips16
+ .set nomicromips
+ .ent func1_ifunc
+ .type func1_ifunc, @function
+func1_ifunc:
+ lw $2,%got(f1_a)($28)
+ addiu $2,$2,%lo(f1_a)
+ lw $2,%got(f1_b)($28)
+ addiu $2,$2,%lo(f1_b)
+ lw $2,%got(f1_c)($28)
+ addiu $2,$2,%lo(f1_c)
+ nop
+
+ .set macro
+ .set reorder
+ .end func1_ifunc
+ .size func1_ifunc, .-func1_ifunc
+ .type func1, @gnu_indirect_function
+ func1 = func1_ifunc
+
+ .align 2
+ .globl main
+ .set nomips16
+ .set nomicromips
+ .globl main
+ .ent main
+ .type main, @function
+main:
+ .frame $fp,32,$31 # vars= 0, regs= 2/0, args= 16, gp= 8
+ .mask 0xc0000000,-4
+ .fmask 0x00000000,0
+ .set noreorder
+ .cpload $25
+ .set nomacro
+ addiu $sp,$sp,-32
+ sw $31,28($sp)
+ sw $fp,24($sp)
+ move $fp,$sp
+ .cprestore 16
+ lw $2,%call16(func1)($28)
+ move $25,$2
+ jalr $25
+ nop
+
+ lui $2,%hi(func1)
+ addiu $2, $2, %lo(func1)
+ nop
+
+ lw $28,16($fp)
+ move $sp,$fp
+ lw $31,28($sp)
+ lw $fp,24($sp)
+ addiu $sp,$sp,32
+ j $31
+ nop
+
+ .set macro
+ .set reorder
+ .end main
+ .size main, .-main
+ .section .data.rel,"aw",@progbits
+ .align 2
+ .type fptr, @object
+ .size fptr, 4
+fptr:
+ .word func1
+ .ident "GCC: (GNU) 4.9.0 20130930 (experimental)"
diff --git a/ld/testsuite/ld-mips-elf/ifunc-static-def-mips16.s b/ld/testsuite/ld-mips-elf/ifunc-static-def-mips16.s
new file mode 100644
index 0000000..31c8c7c
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-static-def-mips16.s
@@ -0,0 +1,434 @@
+ .section .mdebug.abi32
+ .previous
+ .nan legacy
+ .module fp=xx
+ .module nooddspreg
+ .abicalls
+ .option pic0
+ .text
+$Ltext0:
+ .cfi_sections .debug_frame
+ .align 2
+$LFB0 = .
+ .file 1 "ifunc-static-def.c"
+ .loc 1 3 0
+ .cfi_startproc
+ .set mips16
+ .set nomicromips
+ .ent f1_a
+ .type f1_a, @function
+f1_a:
+ .frame $17,8,$31 # vars= 0, regs= 1/0, args= 0, gp= 0
+ .mask 0x00020000,-4
+ .fmask 0x00000000,0
+ save 8,$17
+ .cfi_def_cfa_offset 8
+ .cfi_offset 17, -4
+ move $17,$sp
+ .cfi_def_cfa_register 17
+ .loc 1 3 0
+ li $2,1
+ move $sp,$17
+ .cfi_def_cfa_register 29
+ restore 8,$17
+ .cfi_restore 17
+ .cfi_def_cfa_offset 0
+ j $31
+ .end f1_a
+ .cfi_endproc
+$LFE0:
+ .size f1_a, .-f1_a
+ .align 2
+$LFB1 = .
+ .loc 1 4 0
+ .cfi_startproc
+ .set mips16
+ .set nomicromips
+ .ent f1_b
+ .type f1_b, @function
+f1_b:
+ .frame $17,8,$31 # vars= 0, regs= 1/0, args= 0, gp= 0
+ .mask 0x00020000,-4
+ .fmask 0x00000000,0
+ save 8,$17
+ .cfi_def_cfa_offset 8
+ .cfi_offset 17, -4
+ move $17,$sp
+ .cfi_def_cfa_register 17
+ .loc 1 4 0
+ li $2,2
+ move $sp,$17
+ .cfi_def_cfa_register 29
+ restore 8,$17
+ .cfi_restore 17
+ .cfi_def_cfa_offset 0
+ j $31
+ .end f1_b
+ .cfi_endproc
+$LFE1:
+ .size f1_b, .-f1_b
+ .align 2
+$LFB2 = .
+ .loc 1 5 0
+ .cfi_startproc
+ .set mips16
+ .set nomicromips
+ .ent f1_c
+ .type f1_c, @function
+f1_c:
+ .frame $17,8,$31 # vars= 0, regs= 1/0, args= 0, gp= 0
+ .mask 0x00020000,-4
+ .fmask 0x00000000,0
+ save 8,$17
+ .cfi_def_cfa_offset 8
+ .cfi_offset 17, -4
+ move $17,$sp
+ .cfi_def_cfa_register 17
+ .loc 1 5 0
+ li $2,3
+ move $sp,$17
+ .cfi_def_cfa_register 29
+ restore 8,$17
+ .cfi_restore 17
+ .cfi_def_cfa_offset 0
+ j $31
+ .end f1_c
+ .cfi_endproc
+$LFE2:
+ .size f1_c, .-f1_c
+
+ .comm global,4,4
+ .globl result
+ .data
+ .align 2
+ .type result, @object
+ .size result, 4
+result:
+ .word 6
+ .text
+ .align 2
+ .globl func1_ifunc
+$LFB3 = .
+ .loc 1 12 0
+ .cfi_startproc
+ .set mips16
+ .set nomicromips
+ .ent func1_ifunc
+ .type func1_ifunc, @function
+func1_ifunc:
+ .frame $17,24,$31 # vars= 8, regs= 1/0, args= 0, gp= 8
+ .mask 0x00020000,-4
+ .fmask 0x00000000,0
+ save 24,$17
+ .cfi_def_cfa_offset 24
+ .cfi_offset 17, -4
+ move $17,$sp
+ .cfi_def_cfa_register 17
+ .loc 1 15 0
+ lw $2,$L13
+ lw $2,0($2)
+ beqz $2,$L8
+ .loc 1 16 0
+ li $2,48
+ sw $2,8($17)
+ b $L9
+$L8:
+ .loc 1 18 0
+ li $2,3
+ sw $2,8($17)
+$L9:
+ .loc 1 20 0
+ lw $3,8($17)
+ li $2,240
+ and $2,$3
+ beqz $2,$L10
+ .loc 1 21 0
+ lw $2,$L14
+ b $L11
+$L10:
+ .loc 1 22 0
+ lw $3,8($17)
+ li $2,15
+ and $2,$3
+ beqz $2,$L12
+ .loc 1 23 0
+ lw $2,$L15
+ b $L11
+$L12:
+ .loc 1 25 0
+ lw $2,$L16
+$L11:
+ .loc 1 26 0
+ move $sp,$17
+ .cfi_def_cfa_register 29
+ restore 24,$17
+ .cfi_restore 17
+ .cfi_def_cfa_offset 0
+ j $31
+ .align 2
+$L13:
+ .word global
+$L14:
+ .word f1_a
+$L15:
+ .word f1_b
+$L16:
+ .word f1_c
+ .end func1_ifunc
+ .cfi_endproc
+$LFE3:
+ .size func1_ifunc, .-func1_ifunc
+ .globl func1
+ .type func1, @gnu_indirect_function
+ func1 = func1_ifunc
+$Letext0:
+ .section .debug_info,"",@progbits
+$Ldebug_info0:
+ .4byte 0xb9
+ .2byte 0x4
+ .4byte $Ldebug_abbrev0
+ .byte 0x4
+ .uleb128 0x1
+ .4byte $LASF5
+ .byte 0xc
+ .4byte $LASF6
+ .4byte $LASF7
+ .4byte $Ltext0
+ .4byte $Letext0-$Ltext0
+ .4byte $Ldebug_line0
+ .uleb128 0x2
+ .4byte $LASF0
+ .byte 0x1
+ .byte 0x3
+ .4byte 0x3a
+ .4byte $LFB0
+ .4byte $LFE0-$LFB0
+ .uleb128 0x1
+ .byte 0x9c
+ .uleb128 0x3
+ .byte 0x4
+ .byte 0x5
+ .ascii "int\000"
+ .uleb128 0x2
+ .4byte $LASF1
+ .byte 0x1
+ .byte 0x4
+ .4byte 0x3a
+ .4byte $LFB1
+ .4byte $LFE1-$LFB1
+ .uleb128 0x1
+ .byte 0x9c
+ .uleb128 0x2
+ .4byte $LASF2
+ .byte 0x1
+ .byte 0x5
+ .4byte 0x3a
+ .4byte $LFB2
+ .4byte $LFE2-$LFB2
+ .uleb128 0x1
+ .byte 0x9c
+ .uleb128 0x4
+ .4byte $LASF8
+ .byte 0x1
+ .byte 0xb
+ .4byte 0x93
+ .4byte $LFB3
+ .4byte $LFE3-$LFB3
+ .uleb128 0x1
+ .byte 0x9c
+ .4byte 0x93
+ .uleb128 0x5
+ .4byte $LASF4
+ .byte 0x1
+ .byte 0xd
+ .4byte 0x95
+ .uleb128 0x2
+ .byte 0x91
+ .sleb128 -16
+ .byte 0
+ .uleb128 0x6
+ .byte 0x4
+ .uleb128 0x7
+ .4byte 0x3a
+ .uleb128 0x8
+ .4byte $LASF3
+ .byte 0x1
+ .byte 0x7
+ .4byte 0x3a
+ .uleb128 0x5
+ .byte 0x3
+ .4byte global
+ .uleb128 0x8
+ .4byte $LASF4
+ .byte 0x1
+ .byte 0x8
+ .4byte 0x95
+ .uleb128 0x5
+ .byte 0x3
+ .4byte result
+ .byte 0
+ .section .debug_abbrev,"",@progbits
+$Ldebug_abbrev0:
+ .uleb128 0x1
+ .uleb128 0x11
+ .byte 0x1
+ .uleb128 0x25
+ .uleb128 0xe
+ .uleb128 0x13
+ .uleb128 0xb
+ .uleb128 0x3
+ .uleb128 0xe
+ .uleb128 0x1b
+ .uleb128 0xe
+ .uleb128 0x11
+ .uleb128 0x1
+ .uleb128 0x12
+ .uleb128 0x6
+ .uleb128 0x10
+ .uleb128 0x17
+ .byte 0
+ .byte 0
+ .uleb128 0x2
+ .uleb128 0x2e
+ .byte 0
+ .uleb128 0x3
+ .uleb128 0xe
+ .uleb128 0x3a
+ .uleb128 0xb
+ .uleb128 0x3b
+ .uleb128 0xb
+ .uleb128 0x27
+ .uleb128 0x19
+ .uleb128 0x49
+ .uleb128 0x13
+ .uleb128 0x11
+ .uleb128 0x1
+ .uleb128 0x12
+ .uleb128 0x6
+ .uleb128 0x40
+ .uleb128 0x18
+ .uleb128 0x2117
+ .uleb128 0x19
+ .byte 0
+ .byte 0
+ .uleb128 0x3
+ .uleb128 0x24
+ .byte 0
+ .uleb128 0xb
+ .uleb128 0xb
+ .uleb128 0x3e
+ .uleb128 0xb
+ .uleb128 0x3
+ .uleb128 0x8
+ .byte 0
+ .byte 0
+ .uleb128 0x4
+ .uleb128 0x2e
+ .byte 0x1
+ .uleb128 0x3f
+ .uleb128 0x19
+ .uleb128 0x3
+ .uleb128 0xe
+ .uleb128 0x3a
+ .uleb128 0xb
+ .uleb128 0x3b
+ .uleb128 0xb
+ .uleb128 0x27
+ .uleb128 0x19
+ .uleb128 0x49
+ .uleb128 0x13
+ .uleb128 0x11
+ .uleb128 0x1
+ .uleb128 0x12
+ .uleb128 0x6
+ .uleb128 0x40
+ .uleb128 0x18
+ .uleb128 0x2117
+ .uleb128 0x19
+ .uleb128 0x1
+ .uleb128 0x13
+ .byte 0
+ .byte 0
+ .uleb128 0x5
+ .uleb128 0x34
+ .byte 0
+ .uleb128 0x3
+ .uleb128 0xe
+ .uleb128 0x3a
+ .uleb128 0xb
+ .uleb128 0x3b
+ .uleb128 0xb
+ .uleb128 0x49
+ .uleb128 0x13
+ .uleb128 0x2
+ .uleb128 0x18
+ .byte 0
+ .byte 0
+ .uleb128 0x6
+ .uleb128 0xf
+ .byte 0
+ .uleb128 0xb
+ .uleb128 0xb
+ .byte 0
+ .byte 0
+ .uleb128 0x7
+ .uleb128 0x35
+ .byte 0
+ .uleb128 0x49
+ .uleb128 0x13
+ .byte 0
+ .byte 0
+ .uleb128 0x8
+ .uleb128 0x34
+ .byte 0
+ .uleb128 0x3
+ .uleb128 0xe
+ .uleb128 0x3a
+ .uleb128 0xb
+ .uleb128 0x3b
+ .uleb128 0xb
+ .uleb128 0x49
+ .uleb128 0x13
+ .uleb128 0x3f
+ .uleb128 0x19
+ .uleb128 0x2
+ .uleb128 0x18
+ .byte 0
+ .byte 0
+ .byte 0
+ .section .debug_aranges,"",@progbits
+ .4byte 0x1c
+ .2byte 0x2
+ .4byte $Ldebug_info0
+ .byte 0x4
+ .byte 0
+ .2byte 0
+ .2byte 0
+ .4byte $Ltext0
+ .4byte $Letext0-$Ltext0
+ .4byte 0
+ .4byte 0
+ .section .debug_line,"",@progbits
+$Ldebug_line0:
+ .section .debug_str,"MS",@progbits,1
+$LASF8:
+ .ascii "func1_ifunc\000"
+$LASF5:
+ .ascii "GNU C11 5.0.0 20150302 (experimental) -mel -mno-shared -"
+ .ascii "mips16 -mel -mno-relax-pic-calls -mllsc -mplt -mips32r2 "
+ .ascii "-msynci -mabi=32 -mfpxx -g\000"
+$LASF4:
+ .ascii "result\000"
+$LASF6:
+ .ascii "ifunc-static-def.c\000"
+$LASF7:
+ .ascii "/home/frs/tmp/ifunc/test\000"
+$LASF3:
+ .ascii "global\000"
+$LASF0:
+ .ascii "f1_a\000"
+$LASF1:
+ .ascii "f1_b\000"
+$LASF2:
+ .ascii "f1_c\000"
+ .ident "GCC: (GNU) 5.0.0 20150302 (experimental)"
diff --git a/ld/testsuite/ld-mips-elf/ifunc-static-def.s b/ld/testsuite/ld-mips-elf/ifunc-static-def.s
new file mode 100644
index 0000000..55f36b7
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-static-def.s
@@ -0,0 +1,145 @@
+ .file 1 "ifunc.c"
+ .section .mdebug.abi32
+ .previous
+ .abicalls
+ .option pic0
+ .text
+ .align 2
+ .ent f1_a
+ .type f1_a, @function
+f1_a:
+ .frame $fp,8,$31 # vars= 0, regs= 1/0, args= 0, gp= 0
+ .mask 0x40000000,-4
+ .fmask 0x00000000,0
+ .set noreorder
+ .set nomacro
+ addiu $sp,$sp,-8
+ sw $fp,4($sp)
+ move $fp,$sp
+ li $2,1 # 0x1
+ move $sp,$fp
+ lw $fp,4($sp)
+ addiu $sp,$sp,8
+ j $31
+ nop
+
+ .set macro
+ .set reorder
+ .end f1_a
+ .size f1_a, .-f1_a
+ .align 2
+ .ent f1_b
+ .type f1_b, @function
+f1_b:
+ .frame $fp,8,$31 # vars= 0, regs= 1/0, args= 0, gp= 0
+ .mask 0x40000000,-4
+ .fmask 0x00000000,0
+ .set noreorder
+ .set nomacro
+ addiu $sp,$sp,-8
+ sw $fp,4($sp)
+ move $fp,$sp
+ li $2,2 # 0x2
+ move $sp,$fp
+ lw $fp,4($sp)
+ addiu $sp,$sp,8
+ j $31
+ nop
+
+ .set macro
+ .set reorder
+ .end f1_b
+ .size f1_b, .-f1_b
+ .align 2
+ .ent f1_c
+ .type f1_c, @function
+f1_c:
+ .frame $fp,8,$31 # vars= 0, regs= 1/0, args= 0, gp= 0
+ .mask 0x40000000,-4
+ .fmask 0x00000000,0
+ .set noreorder
+ .set nomacro
+ addiu $sp,$sp,-8
+ sw $fp,4($sp)
+ move $fp,$sp
+ li $2,3 # 0x3
+ move $sp,$fp
+ lw $fp,4($sp)
+ addiu $sp,$sp,8
+ j $31
+ nop
+
+ .set macro
+ .set reorder
+ .end f1_c
+ .size f1_c, .-f1_c
+ .align 2
+ .globl func1_ifunc
+ .ent func1_ifunc
+ .type func1_ifunc, @function
+func1_ifunc:
+ .frame $fp,432,$31 # vars= 400, regs= 2/0, args= 16, gp= 8
+ .mask 0xc0000000,-4
+ .fmask 0x00000000,0
+ .set noreorder
+ .set nomacro
+ addiu $sp,$sp,-432
+ sw $31,428($sp)
+ sw $fp,424($sp)
+ move $fp,$sp
+ addiu $2,$fp,28
+ move $4,$2
+ nop
+
+ beq $2,$0,$L8
+ nop
+
+ li $2,48 # 0x30
+ sw $2,24($fp)
+ j $L9
+ nop
+
+$L8:
+ li $2,3 # 0x3
+ sw $2,24($fp)
+$L9:
+ lw $2,24($fp)
+ andi $2,$2,0xf0
+ beq $2,$0,$L10
+ nop
+
+ lui $2,%hi(f1_a)
+ addiu $2,$2,%lo(f1_a)
+ j $L13
+ nop
+
+$L10:
+ lw $2,24($fp)
+ andi $2,$2,0xf
+ beq $2,$0,$L12
+ nop
+
+ lui $2,%hi(f1_b)
+ addiu $2,$2,%lo(f1_b)
+ j $L13
+ nop
+
+$L12:
+ lui $2,%hi(f1_c)
+ addiu $2,$2,%lo(f1_c)
+$L13:
+ move $sp,$fp
+ lw $31,428($sp)
+ lw $fp,424($sp)
+ addiu $sp,$sp,432
+ j $31
+ nop
+
+ .set macro
+ .set reorder
+ .end func1_ifunc
+ .size func1_ifunc, .-func1_ifunc
+ .globl func1
+ .type func1, @gnu_indirect_function
+ func1 = func1_ifunc
+ .ident "GCC: (GNU) 4.9.0 20130930 (experimental)"
diff --git a/ld/testsuite/ld-mips-elf/ifunc-static-main-mips16.s b/ld/testsuite/ld-mips-elf/ifunc-static-main-mips16.s
new file mode 100644
index 0000000..43f4abe
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-static-main-mips16.s
@@ -0,0 +1,157 @@
+ .section .mdebug.abi32
+ .previous
+ .nan legacy
+ .module fp=xx
+ .module nooddspreg
+ .abicalls
+ .option pic0
+ .text
+$Ltext0:
+ .cfi_sections .debug_frame
+ .align 2
+ .globl main
+$LFB0 = .
+ .file 1 "ifunc-static-main.c"
+ .loc 1 4 0
+ .cfi_startproc
+ .set mips16
+ .set nomicromips
+ .ent main
+ .type main, @function
+main:
+ .frame $17,16,$31 # vars= 0, regs= 2/0, args= 16, gp= 8
+ .mask 0x80020000,-4
+ .fmask 0x00000000,0
+ save 32,$17,$31
+ .cfi_def_cfa_offset 32
+ .cfi_offset 31, -4
+ .cfi_offset 17, -8
+ addiu $17,$sp,16
+ .cfi_def_cfa 17, 16
+ .loc 1 5 0
+ jal func1
+ .loc 1 6 0
+ move $sp,$17
+ .cfi_def_cfa_register 29
+ restore 16,$17,$31
+ .cfi_restore 17
+ .cfi_restore 31
+ .cfi_def_cfa_offset 0
+ j $31
+ .end main
+ .cfi_endproc
+$LFE0:
+ .size main, .-main
+$Letext0:
+ .section .debug_info,"",@progbits
+$Ldebug_info0:
+ .4byte 0x3e
+ .2byte 0x4
+ .4byte $Ldebug_abbrev0
+ .byte 0x4
+ .uleb128 0x1
+ .4byte $LASF0
+ .byte 0xc
+ .4byte $LASF1
+ .4byte $LASF2
+ .4byte $Ltext0
+ .4byte $Letext0-$Ltext0
+ .4byte $Ldebug_line0
+ .uleb128 0x2
+ .4byte $LASF3
+ .byte 0x1
+ .byte 0x3
+ .4byte 0x3a
+ .4byte $LFB0
+ .4byte $LFE0-$LFB0
+ .uleb128 0x1
+ .byte 0x9c
+ .uleb128 0x3
+ .byte 0x4
+ .byte 0x5
+ .ascii "int\000"
+ .byte 0
+ .section .debug_abbrev,"",@progbits
+$Ldebug_abbrev0:
+ .uleb128 0x1
+ .uleb128 0x11
+ .byte 0x1
+ .uleb128 0x25
+ .uleb128 0xe
+ .uleb128 0x13
+ .uleb128 0xb
+ .uleb128 0x3
+ .uleb128 0xe
+ .uleb128 0x1b
+ .uleb128 0xe
+ .uleb128 0x11
+ .uleb128 0x1
+ .uleb128 0x12
+ .uleb128 0x6
+ .uleb128 0x10
+ .uleb128 0x17
+ .byte 0
+ .byte 0
+ .uleb128 0x2
+ .uleb128 0x2e
+ .byte 0
+ .uleb128 0x3f
+ .uleb128 0x19
+ .uleb128 0x3
+ .uleb128 0xe
+ .uleb128 0x3a
+ .uleb128 0xb
+ .uleb128 0x3b
+ .uleb128 0xb
+ .uleb128 0x27
+ .uleb128 0x19
+ .uleb128 0x49
+ .uleb128 0x13
+ .uleb128 0x11
+ .uleb128 0x1
+ .uleb128 0x12
+ .uleb128 0x6
+ .uleb128 0x40
+ .uleb128 0x18
+ .uleb128 0x2116
+ .uleb128 0x19
+ .byte 0
+ .byte 0
+ .uleb128 0x3
+ .uleb128 0x24
+ .byte 0
+ .uleb128 0xb
+ .uleb128 0xb
+ .uleb128 0x3e
+ .uleb128 0xb
+ .uleb128 0x3
+ .uleb128 0x8
+ .byte 0
+ .byte 0
+ .byte 0
+ .section .debug_aranges,"",@progbits
+ .4byte 0x1c
+ .2byte 0x2
+ .4byte $Ldebug_info0
+ .byte 0x4
+ .byte 0
+ .2byte 0
+ .2byte 0
+ .4byte $Ltext0
+ .4byte $Letext0-$Ltext0
+ .4byte 0
+ .4byte 0
+ .section .debug_line,"",@progbits
+$Ldebug_line0:
+ .section .debug_str,"MS",@progbits,1
+$LASF1:
+ .ascii "ifunc-static-main.c\000"
+$LASF0:
+ .ascii "GNU C11 5.0.0 20150302 (experimental) -mel -mno-shared -"
+ .ascii "mips16 -mel -mllsc -mplt -mips32r2 "
+ .ascii "-msynci -mabi=32 -mfpxx -g\000"
+$LASF2:
+ .ascii "/home/frs/tmp/ifunc/test\000"
+$LASF3:
+ .ascii "main\000"
+ .ident "GCC: (GNU) 5.0.0 20150302 (experimental)"
diff --git a/ld/testsuite/ld-mips-elf/ifunc-static-main.s b/ld/testsuite/ld-mips-elf/ifunc-static-main.s
new file mode 100644
index 0000000..4a6349e
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-static-main.s
@@ -0,0 +1,35 @@
+ .file 1 "ifunc_ref_main_1.c"
+ .section .mdebug.abi32
+ .previous
+ .abicalls
+ .option pic0
+ .text
+ .align 2
+ .globl main
+ .ent main
+ .type main, @function
+main:
+ .frame $fp,32,$31 # vars= 0, regs= 2/0, args= 16, gp= 8
+ .mask 0xc0000000,-4
+ .fmask 0x00000000,0
+ .set noreorder
+ .set nomacro
+ addiu $sp,$sp,-32
+ sw $31,28($sp)
+ sw $fp,24($sp)
+ move $fp,$sp
+ jal func1
+ nop
+
+ move $sp,$fp
+ lw $31,28($sp)
+ lw $fp,24($sp)
+ addiu $sp,$sp,32
+ j $31
+ nop
+
+ .set macro
+ .set reorder
+ .end main
+ .size main, .-main
+ .ident "GCC: (GNU) 4.9.0 20130930 (experimental)"
diff --git a/ld/testsuite/ld-mips-elf/ifunc-static-ref.s b/ld/testsuite/ld-mips-elf/ifunc-static-ref.s
new file mode 100644
index 0000000..76de6cd
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-static-ref.s
@@ -0,0 +1,36 @@
+ .file 1 "ifunc_ref.c"
+ .section .mdebug.abi32
+ .previous
+ .abicalls
+ .option pic0
+ .text
+ .align 2
+ .globl ref1
+ .set mips32r2
+ .ent ref1
+ .type ref1, @function
+ref1:
+ .frame $fp,32,$31 # vars= 0, regs= 2/0, args= 16, gp= 8
+ .mask 0xc0000000,-4
+ .fmask 0x00000000,0
+ .set noreorder
+ .set nomacro
+ addiu $sp,$sp,-32
+ sw $31,28($sp)
+ sw $fp,24($sp)
+ move $fp,$sp
+ jal func1
+ nop
+
+ move $sp,$fp
+ lw $31,28($sp)
+ lw $fp,24($sp)
+ addiu $sp,$sp,32
+ j $31
+ nop
+
+ .set macro
+ .set reorder
+ .end ref1
+ .size ref1, .-ref1
+ .ident "GCC: (GNU) 4.9.0 20130930 (experimental)"
diff --git a/ld/testsuite/ld-mips-elf/ifunc-static.ld b/ld/testsuite/ld-mips-elf/ifunc-static.ld
new file mode 100644
index 0000000..ef07ec6
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-static.ld
@@ -0,0 +1,27 @@
+ENTRY(_start)
+SECTIONS
+{
+ . = 0x80000;
+ . = ALIGN (0x400);
+ .iplt : { *(.iplt) }
+
+ . = ALIGN (0x400);
+ .text : { *(.text) }
+
+ . = ALIGN (0x400);
+ .igot : { *(.igot) }
+
+ . = ALIGN (0x400);
+ .got : { *(.got) }
+
+ . = ALIGN (0x400);
+ .data : { *(.data) }
+
+ . = ALIGN (0x1000);
+ .rel.dyn :
+ {
+ *(.rel.*)
+ }
+/* /DISCARD/ : { *(*) } */
+
+}
diff --git a/ld/testsuite/ld-mips-elf/libifunc-1-n32.sym b/ld/testsuite/ld-mips-elf/libifunc-1-n32.sym
new file mode 100644
index 0000000..88d7e5d
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/libifunc-1-n32.sym
@@ -0,0 +1,4 @@
+Symbol table for image:
+ Num Buc: Value Size Type Bind Vis Ndx Name
+ 3 0: 0000000c 28 FUNC GLOBAL DEFAULT 1 func1_ifunc
+ 2 0: 0000000c 28 IFUNC GLOBAL DEFAULT 1 func1
diff --git a/ld/testsuite/ld-mips-elf/libifunc-1-n64.sym b/ld/testsuite/ld-mips-elf/libifunc-1-n64.sym
new file mode 100644
index 0000000..7236950
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/libifunc-1-n64.sym
@@ -0,0 +1,4 @@
+Symbol table for image:
+ Num Buc: Value Size Type Bind Vis Ndx Name
+ 3 0: 000000000000000c 28 FUNC GLOBAL DEFAULT 1 func1_ifunc
+ 2 0: 000000000000000c 28 IFUNC GLOBAL DEFAULT 1 func1
diff --git a/ld/testsuite/ld-mips-elf/libifunc-1-o32.sym b/ld/testsuite/ld-mips-elf/libifunc-1-o32.sym
new file mode 100644
index 0000000..b5fff26
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/libifunc-1-o32.sym
@@ -0,0 +1,4 @@
+Symbol table for image:
+ Num Buc: Value Size Type Bind Vis Ndx Name
+ 3 0: 0000000c 40 FUNC GLOBAL DEFAULT 1 func1_ifunc
+ 2 0: 0000000c 40 IFUNC GLOBAL DEFAULT 1 func1
diff --git a/ld/testsuite/ld-mips-elf/libifunc-2-n32.sym b/ld/testsuite/ld-mips-elf/libifunc-2-n32.sym
new file mode 100644
index 0000000..2c1e84e
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/libifunc-2-n32.sym
@@ -0,0 +1,4 @@
+Symbol table for image:
+ Num Buc: Value Size Type Bind Vis Ndx Name
+ 2 0: 00000000 60 FUNC GLOBAL DEFAULT 1 ref1
+ 3 0: 00000040 0 FUNC GLOBAL DEFAULT UND func1
diff --git a/ld/testsuite/ld-mips-elf/libifunc-2-n64.sym b/ld/testsuite/ld-mips-elf/libifunc-2-n64.sym
new file mode 100644
index 0000000..3bd53fd
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/libifunc-2-n64.sym
@@ -0,0 +1,4 @@
+Symbol table for image:
+ Num Buc: Value Size Type Bind Vis Ndx Name
+ 2 0: 0000000000000000 60 FUNC GLOBAL DEFAULT 1 ref1
+ 3 0: 0000000000000040 0 FUNC GLOBAL DEFAULT UND func1
diff --git a/ld/testsuite/ld-mips-elf/libifunc-2-o32.sym b/ld/testsuite/ld-mips-elf/libifunc-2-o32.sym
new file mode 100644
index 0000000..b831edd
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/libifunc-2-o32.sym
@@ -0,0 +1,5 @@
+Symbol table for image:
+ Num Buc: Value Size Type Bind Vis Ndx Name
+ 3 0: 00000000 76 FUNC GLOBAL DEFAULT 1 ref1
+ 4 0: 00000050 0 FUNC GLOBAL DEFAULT UND func1
+ 2 0: 00000000 0 SECTION GLOBAL DEFAULT ABS _gp_disp
diff --git a/ld/testsuite/ld-mips-elf/mips-ifunc.exp b/ld/testsuite/ld-mips-elf/mips-ifunc.exp
new file mode 100644
index 0000000..320fbc9
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/mips-ifunc.exp
@@ -0,0 +1,282 @@
+# Expect script for MIPS IFUNC linker tests
+# Copyright 2013
+# Free Software Foundation, Inc.
+#
+# This file is part of the GNU Binutils.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+# MA 02110-1301, USA.
+#
+
+if {![istarget mips*-*-*] || ![is_elf_format]} {
+ return
+}
+
+# General setup
+#############################################
+set has_newabi [expr [istarget *-*-irix6*] \
+ || [istarget mips*-*-linux*] \
+ || [istarget mips*-sde-elf*]]
+set linux_gnu [expr [istarget mips*-*-linux*]]
+set embedded_elf [expr [istarget mips*-*-elf]]
+
+# Set defaults.
+set abi_asflags(o32) ""
+set abi_asflags(n32) "-march=from-abi -n32 -EB"
+set abi_asflags(n64) "-march=from-abi -64 -EB"
+set abi_ldflags(o32) ""
+set abi_ldflags(n32) -melf32bmipn32
+set abi_ldflags(n64) -melf64bmip
+
+# Override as needed.
+if { [istarget *-*-irix6*] } {
+ set abi_asflags(o32) "-32 -EB"
+ set abi_ldflags(o32) -melf32bsmip
+} elseif { [istarget mips64*-linux*] } {
+ set abi_asflags(o32) "-32 -EB"
+ set abi_ldflags(o32) -melf32btsmip
+} elseif { [istarget mips64*-*freebsd*] } {
+ set abi_asflags(o32) "-32 -EB"
+ set abi_ldflags(o32) -melf32btsmip_fbsd
+}
+if { [istarget mips*-*-linux*] || [istarget mips*-sde-elf*] } {
+ set abi_ldflags(n32) -melf32btsmipn32
+ set abi_ldflags(n64) -melf64btsmip
+} elseif { [istarget mips64*-*freebsd*] } {
+ set abi_ldflags(n32) -melf32btsmipn32_fbsd
+ set abi_ldflags(n64) -melf64btsmip_fbsd
+}
+#############################################
+
+
+# STT_GNU_IFUNC testing:
+#
+# 1. Dso with ifunc defined code
+# 2. Dso that references external ifunc'ed routines
+# 3. Dynamic executable with ifunc defined code
+# 4. Static executable with ifunc defined and referenced code
+# 5. Dso with with ifunc defined and referenced code
+# 6. Dynamic executable with ifunc defined and referenced code
+# STT_GNU_IFUNC tests.
+set abis [concat o32 [expr {$has_newabi ? "n32 n64" : ""}]]
+foreach { abi } $abis {
+ run_ld_link_tests [list \
+ [list \
+ "IFUNC 1 (Simple dso with def) ${abi}" \
+ "$abi_ldflags($abi) -shared -T ifunc-dyn.ld" "" \
+ "$abi_asflags($abi)" \
+ [list ifunc-dyn-def.s] \
+ [list "readelf -Ds libifunc-1-${abi}.sym"] \
+ "libifunc-1-${abi}.so" \
+ ] \
+ [list \
+ "IFUNC 2 (Simple dso with ref) ${abi}" \
+ "$abi_ldflags($abi) -shared -T ifunc-dyn.ld" "" \
+ "$abi_asflags($abi)" \
+ [list ifunc-dyn-ref.s] \
+ [list "readelf -Ds libifunc-2-${abi}.sym"] \
+ "libifunc-2-${abi}.so" \
+ ] \
+ [list \
+ "IFUNC 3 (Simple dynamic executable with def) ${abi}" \
+ "$abi_ldflags($abi) -Bdynamic -L./tmpdir -lifunc-2-${abi} -T ifunc-dyn.ld" "" \
+ "$abi_asflags($abi)" \
+ [list ifunc-dyn-main.s ifunc-dyn-def.s] \
+ [list "readelf -Ds ifunc-3-${abi}.sym" \
+ "readelf -r ifunc-3-${abi}.r" \
+ "objdump -dj.iplt ifunc-3-${abi}.t"] \
+ "ifunc-3-${abi}" \
+ ] \
+ [list \
+ "IFUNC 4 (Simple static executable with def and ref) ${abi}" \
+ "$abi_ldflags($abi) -Bstatic -T ifunc-static.ld" "" \
+ "$abi_asflags($abi) -non_shared" \
+ [list ifunc-static-main.s ifunc-static-def.s ifunc-static-ref.s] \
+ [list "readelf -s ifunc-4-${abi}.sym" \
+ "readelf -r ifunc-4-${abi}.r" \
+ "objdump -dj.iplt ifunc-4-${abi}.t"] \
+ "ifunc-4-${abi}" \
+ ] \
+ [list \
+ "IFUNC 5 (Dynamic shared object with def and ref) ${abi}" \
+ "$abi_ldflags($abi) -shared -T ifunc-dyn.ld" "" \
+ "$abi_asflags($abi) -KPIC" \
+ [list ifunc-dyn-def.s ifunc-dyn-ref.s] \
+ [list "readelf -Ds ifunc-5-${abi}.sym" \
+ "readelf -r ifunc-5-${abi}.r" \
+ "readelf -d ifunc-5.dyn" \
+ "objdump -dj.got ifunc-5-${abi}.g"] \
+ "ifunc-5-${abi}" \
+ ] \
+ [list \
+ "IFUNC 6 (Dynamic executable with def and ref) ${abi}" \
+ "$abi_ldflags($abi) -Bdynamic -L./tmpdir -lifunc-2-${abi} -T ifunc-dyn.ld" "" \
+ "$abi_asflags($abi)" \
+ [list ifunc-dyn-main.s ifunc-dyn-def.s ifunc-dyn-ref.s] \
+ [list "readelf -Ds ifunc-6-${abi}.sym" \
+ "readelf -d ifunc-6.dyn" \
+ "readelf -r ifunc-6-${abi}.r"] \
+ "ifunc-6-${abi}" \
+ ] \
+ ]
+}
+
+# IPLT sequences change based on how big the address of the
+# .igot.plt section is based on Mips loading immediate values.
+#
+set addrs { "0x400000" "0x400000000" "0x4000000000000" }
+foreach { addr } $addrs {
+ run_ld_link_tests [list \
+ [list \
+ "IFUNC IPLT (Simple static executable with def and ref) ${addr}" \
+ "$abi_ldflags(n64) -Bstatic -Ttext-segment ${addr}" "" \
+ "$abi_asflags(n64) -non_shared" \
+ [list ifunc-static-main.s ifunc-static-def.s ifunc-static-ref.s] \
+ [list "objdump -dj.iplt ifunc-iplt-${addr}.t"] \
+ "ifunc-iplt-${addr}" \
+ ] \
+ ]
+}
+
+# Check creation of IPLT/IGOT entries for locally bound IFUNC symbols.
+# When an IFUNC symbol binds locally there are 6 cases:
+# PIC relocs? non-PIC relocs? all call-only? variant test
+# n y y (1) IFUNC 7
+# y n y (2) IFUNC 8
+# y y y (3) IFUNC 9
+# n y n (4) IFUNC 10
+# y n n (5) IFUNC 11
+# y y n (5) IFUNC 12
+# (1) Need .iplt and .igot.
+# (2) No .iplt; .got entry with an IRELATIVE relocation.
+# (3) Need .iplt but no .igot; IRELATIVE entry should in .got
+# (4) Same as (1)
+# (5) Need .iplt and .igot; Separate regular .got entry to satisfy the PIC
+# references
+set abi o32
+run_ld_link_tests [list \
+ [list \
+ "IFUNC 7 (Simple static executable with def) ${abi}" \
+ "$abi_ldflags($abi) -static -Bstatic" "" \
+ "$abi_asflags($abi)" \
+ [list ifunc-local-1.s] \
+ [list "readelf -r ifunc-7-${abi}.r" \
+ "readelf -S ifunc-7-${abi}.sec"] \
+ "ifunc-7-${abi}" \
+ ] \
+ [list \
+ "IFUNC 8 (Simple dynamic executable with def) ${abi}" \
+ "$abi_ldflags($abi) -static" "" \
+ "$abi_asflags($abi)" \
+ [list ifunc-local-2.s] \
+ [list "readelf -r ifunc-8-${abi}.r" \
+ "readelf -S ifunc-8-${abi}.sec" \
+ "objdump -Dj.got ifunc-8-${abi}.g"] \
+ "ifunc-8-${abi}" \
+ ] \
+ [list \
+ "IFUNC 9 (Simple dynamic executable with def & PIC/non-PIC refs) ${abi}" \
+ "$abi_ldflags($abi) -static -Bstatic" "" \
+ "$abi_asflags($abi) -non_shared" \
+ [list ifunc-local-3.s] \
+ [list "readelf -r ifunc-9-${abi}.r" \
+ "readelf -S ifunc-9-${abi}.sec" \
+ "readelf -S ifunc-9-${abi}-x.sec" \
+ "objdump -Dj.got ifunc-9-${abi}.g" \
+ "objdump -dj.iplt ifunc-9-${abi}.t"] \
+ "ifunc-9-${abi}" \
+ ] \
+ [list \
+ "IFUNC 10 (Simple static executable with def & non-call ref) ${abi}" \
+ "$abi_ldflags($abi) -static -Bstatic" "" \
+ "$abi_asflags($abi) -non_shared" \
+ [list ifunc-local-4.s] \
+ [list "readelf -r ifunc-10-${abi}.r" \
+ "readelf -S ifunc-10-${abi}.sec"] \
+ "ifunc-10-${abi}" \
+ ] \
+ [list \
+ "IFUNC 11 (Simple dynamic executable with def & non-call ref) ${abi}" \
+ "$abi_ldflags($abi) -static" "" \
+ "$abi_asflags($abi)" \
+ [list ifunc-local-5.s] \
+ [list "readelf -r ifunc-11-${abi}.r" \
+ "readelf -S ifunc-11-${abi}.sec" \
+ "objdump -Dj.got ifunc-11-${abi}.g"] \
+ "ifunc-11-${abi}" \
+ ] \
+ [list \
+ "IFUNC 12 (Simple static executable with def, PIC/non-PIC, call/non-call refs) ${abi}" \
+ "$abi_ldflags($abi) -static -Bstatic" "" \
+ "$abi_asflags($abi) -non_shared" \
+ [list ifunc-local-6.s] \
+ [list "readelf -r ifunc-12-${abi}.r" \
+ "readelf -S ifunc-12-${abi}.sec" \
+ "objdump -Dj.got ifunc-12-${abi}.g"] \
+ "ifunc-12-${abi}" \
+ ] \
+]
+
+# Check that no PIC stub is used when IPLT stub is present.
+run_ld_link_tests [list \
+ [list \
+ "IFUNC 13 non-PIC calls to PIC IFUNC ${abi}" \
+ "$abi_ldflags($abi) -static -Bstatic" "" \
+ "$abi_asflags($abi) -non_shared" \
+ [list ifunc-dyn-def.s ifunc-dyn-ref.s ifunc-static-main.s] \
+ [list "readelf -r ifunc-13-${abi}.r" \
+ "readelf -S ifunc-13-${abi}.sec" \
+ "objdump -Dj.text ifunc-13-${abi}.t"] \
+ "ifunc-13-${abi}" \
+ ] \
+]
+
+# Check generation of mips32r6 stubs
+run_ld_link_tests [list \
+ [list \
+ "IFUNC IPLT (Simple static executable with def and ref) mips32r6" \
+ "" "" \
+ "$abi_asflags(o32) -mips32r6" \
+ [list ifunc-static-main.s ifunc-static-def.s] \
+ [list "objdump -dj.iplt ifunc-iplt-mips32r6.t"] \
+ "ifunc-iplt-mips32r6" \
+ ] \
+]
+
+# Check generation of micromips stubs
+run_ld_link_tests [list \
+ [list \
+ "IFUNC IPLT (Simple static executable with def and ref) micromips" \
+ "" "" \
+ "$abi_asflags(o32) -mmicromips" \
+ [list ifunc-static-main.s ifunc-static-def.s] \
+ [list "objdump -dj.iplt ifunc-iplt-micromips.t" \
+ "objdump -dj.igot ifunc-iplt-micromips.igot"] \
+ "ifunc-iplt-micromips" \
+ ] \
+]
+
+# Check generation of mips16 stubs
+run_ld_link_tests [list \
+ [list \
+ "IFUNC IPLT (Simple static executable with def and ref) mips16" \
+ "" "" \
+ "$abi_asflags(o32) -mips32r2 -mips16" \
+ [list ifunc-static-main-mips16.s ifunc-static-def-mips16.s] \
+ [list "objdump -dj.iplt ifunc-iplt-mips16.t" \
+ "objdump -dj.igot ifunc-iplt-mips16.igot"] \
+ "ifunc-iplt-mips16" \
+ ] \
+]
--
1.7.9.5