This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH 2/2] [RFC] Add IFUNC support for MIPS (v4)


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]