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 (v5)


Test-cases.

ld/testsuite/ChangeLog:

	* ld-ifunc/ifunc.exp: Enable IFUNC tests for MIPS targets.
	* ld-mips-elf/mips-ifunc.exp: New IFUNC test script.
	* ld-mips-elf/ifunc-dyn.ld: New.
	* ld-mips-elf/ifunc-iplt.ld: New.
	* ld-mips-elf/ifunc-static.ld: New.
	* ld-mips-elf/ifunc-dyn-def.s: New.
	* ld-mips-elf/ifunc-dyn-main.s: New.
	* ld-mips-elf/ifunc-dyn-ref.s: New.
	* ld-mips-elf/ifunc-local-1.s: New.
	* ld-mips-elf/ifunc-local-2.s: New.
	* ld-mips-elf/ifunc-local-3.s: New.
	* ld-mips-elf/ifunc-local-4.s: New.
	* ld-mips-elf/ifunc-local-5.s: New.
	* ld-mips-elf/ifunc-local-6.s: New.
	* ld-mips-elf/ifunc-mix-1.s: New.
	* ld-mips-elf/ifunc-mix-2.s: New.
	* ld-mips-elf/ifunc-static-def-mips16.s: New.
	* ld-mips-elf/ifunc-static-def.s: New.
	* ld-mips-elf/ifunc-static-main-mips16.s: New.
	* ld-mips-elf/ifunc-static-main.s: New.
	* ld-mips-elf/ifunc-static-ref.s: New.
	* ld-mips-elf/ifunc-10-o32.r: New.
	* ld-mips-elf/ifunc-11-o32.r: New.
	* ld-mips-elf/ifunc-12-o32.r: New.
	* ld-mips-elf/ifunc-13-o32.r: New.
	* ld-mips-elf/ifunc-3-n32.r: New.
	* ld-mips-elf/ifunc-3-n64.r: New.
	* ld-mips-elf/ifunc-3-o32.r: New.
	* ld-mips-elf/ifunc-4-n32.r: New.
	* ld-mips-elf/ifunc-4-n64.r: New.
	* ld-mips-elf/ifunc-4-o32.r: New.
	* ld-mips-elf/ifunc-5-n32.r: New.
	* ld-mips-elf/ifunc-5-n64.r: New.
	* ld-mips-elf/ifunc-5-o32.r: New.
	* ld-mips-elf/ifunc-6-n32.r: New.
	* ld-mips-elf/ifunc-6-n64.r: New.
	* ld-mips-elf/ifunc-6-o32.r: New.
	* ld-mips-elf/ifunc-7-o32.r: New.
	* ld-mips-elf/ifunc-8-o32.r: New.
	* ld-mips-elf/ifunc-9-o32.r: New.
	* ld-mips-elf/ifunc-mix-1.sym: New.
	* ld-mips-elf/ifunc-mix-2.sym: New.
	* ld-mips-elf/ifunc-3-n32.sym: New.
	* ld-mips-elf/ifunc-3-n64.sym: New.
	* ld-mips-elf/ifunc-3-o32.sym: New.
	* ld-mips-elf/ifunc-4-n32.sym: New.
	* ld-mips-elf/ifunc-4-n64.sym: New.
	* ld-mips-elf/ifunc-4-o32.sym: New.
	* ld-mips-elf/ifunc-5-n32.sym: New.
	* ld-mips-elf/ifunc-5-n64.sym: New.
	* ld-mips-elf/ifunc-5-o32.sym: New.
	* ld-mips-elf/ifunc-6-n32.sym: New.
	* ld-mips-elf/ifunc-6-n64.sym: New.
	* ld-mips-elf/ifunc-6-o32.sym: New.
	* ld-mips-elf/libifunc-1-n32.sym: New.
	* ld-mips-elf/libifunc-1-n64.sym: New.
	* ld-mips-elf/libifunc-1-o32.sym: New.
	* ld-mips-elf/libifunc-2-n32.sym: New.
	* ld-mips-elf/libifunc-2-n64.sym: New.
	* ld-mips-elf/libifunc-2-o32.sym: New.
	* ld-mips-elf/ifunc-mix-1.t: New.
	* ld-mips-elf/ifunc-mix-2.t: New.
	* ld-mips-elf/ifunc-13-o32.t: New.
	* ld-mips-elf/ifunc-3-n32.t: New.
	* ld-mips-elf/ifunc-3-n64.t: New.
	* ld-mips-elf/ifunc-3-o32.t: New.
	* ld-mips-elf/ifunc-4-n32.t: New.
	* ld-mips-elf/ifunc-4-n64.t: New.
	* ld-mips-elf/ifunc-4-o32.t: New.
	* ld-mips-elf/ifunc-9-o32.t: New.
	* ld-mips-elf/ifunc-iplt-0x4000000000000.t: New.
	* ld-mips-elf/ifunc-iplt-0x400000000.t: New.
	* ld-mips-elf/ifunc-iplt-0x400000.t: New.
	* ld-mips-elf/ifunc-iplt-micromips.t: New.
	* ld-mips-elf/ifunc-iplt-mips16.t: New.
	* ld-mips-elf/ifunc-iplt-mips32r6.t: New.
	* ld-mips-elf/ifunc-iplt-mix-1.t: New.
	* ld-mips-elf/ifunc-iplt-mix-2.t: New.
	* ld-mips-elf/ifunc-5-n32.g: New.
	* ld-mips-elf/ifunc-5-n64.g: New.
	* ld-mips-elf/ifunc-5-o32.g: New.
	* ld-mips-elf/ifunc-iplt-micromips.igot: New.
	* ld-mips-elf/ifunc-iplt-mips16.igot: New.
	* ld-mips-elf/ifunc-mix-1.igot: New.
	* ld-mips-elf/ifunc-mix-2.igot: New.
---
 ld/testsuite/ld-ifunc/ifunc.exp                    |    5 +-
 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-10.s                |  130 ++++++++++
 ld/testsuite/ld-mips-elf/ifunc-11-o32.got          |    4 +
 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-11.s                |   69 +++++
 ld/testsuite/ld-mips-elf/ifunc-12-o32.got          |    4 +
 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-12.s                |   74 ++++++
 ld/testsuite/ld-mips-elf/ifunc-13-o32.r            |    3 +
 ld/testsuite/ld-mips-elf/ifunc-13-o32.sec          |    3 +
 ld/testsuite/ld-mips-elf/ifunc-13-o32.t            |    7 +
 ld/testsuite/ld-mips-elf/ifunc-3-n32.r             |    3 +
 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             |    5 +
 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             |    3 +
 ld/testsuite/ld-mips-elf/ifunc-3-o32.sym           |    3 +
 ld/testsuite/ld-mips-elf/ifunc-3-o32.t             |   10 +
 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             |   10 +
 ld/testsuite/ld-mips-elf/ifunc-5-n32.got           |    5 +
 ld/testsuite/ld-mips-elf/ifunc-5-n32.r             |    3 +
 ld/testsuite/ld-mips-elf/ifunc-5-n32.sym           |    3 +
 ld/testsuite/ld-mips-elf/ifunc-5-n64.got           |    5 +
 ld/testsuite/ld-mips-elf/ifunc-5-n64.r             |    5 +
 ld/testsuite/ld-mips-elf/ifunc-5-n64.sym           |    3 +
 ld/testsuite/ld-mips-elf/ifunc-5-o32.got           |    5 +
 ld/testsuite/ld-mips-elf/ifunc-5-o32.r             |    3 +
 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             |    3 +
 ld/testsuite/ld-mips-elf/ifunc-6-n32.sym           |    3 +
 ld/testsuite/ld-mips-elf/ifunc-6-n64.r             |    5 +
 ld/testsuite/ld-mips-elf/ifunc-6-n64.sym           |    3 +
 ld/testsuite/ld-mips-elf/ifunc-6-o32.r             |    3 +
 ld/testsuite/ld-mips-elf/ifunc-6-o32.sym           |    3 +
 ld/testsuite/ld-mips-elf/ifunc-6.dyn               |    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-7.s                 |  115 +++++++++
 ld/testsuite/ld-mips-elf/ifunc-8-o32.got           |    4 +
 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-8.s                 |   64 +++++
 ld/testsuite/ld-mips-elf/ifunc-9-o32.got           |    4 +
 ld/testsuite/ld-mips-elf/ifunc-9-o32.r             |    3 +
 ld/testsuite/ld-mips-elf/ifunc-9-o32.sec           |   17 ++
 ld/testsuite/ld-mips-elf/ifunc-9-o32.t             |    7 +
 ld/testsuite/ld-mips-elf/ifunc-9.s                 |   94 +++++++
 ld/testsuite/ld-mips-elf/ifunc-dyn-def.s           |   40 +++
 ld/testsuite/ld-mips-elf/ifunc-dyn-main.s          |   21 ++
 ld/testsuite/ld-mips-elf/ifunc-dyn-ref.s           |   24 ++
 ld/testsuite/ld-mips-elf/ifunc-dyn.ld              |   27 ++
 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 |    4 +
 ld/testsuite/ld-mips-elf/ifunc-iplt-micromips.t    |   10 +
 ld/testsuite/ld-mips-elf/ifunc-iplt-mips16.igot    |    4 +
 ld/testsuite/ld-mips-elf/ifunc-iplt-mips16.t       |   10 +
 ld/testsuite/ld-mips-elf/ifunc-iplt-mips32r6.t     |   10 +
 ld/testsuite/ld-mips-elf/ifunc-iplt-mix-1.t        |   29 +++
 ld/testsuite/ld-mips-elf/ifunc-iplt-mix-2.t        |   27 ++
 ld/testsuite/ld-mips-elf/ifunc-iplt.ld             |   27 ++
 ld/testsuite/ld-mips-elf/ifunc-mix-1.igot          |    3 +
 ld/testsuite/ld-mips-elf/ifunc-mix-1.s             |   53 ++++
 ld/testsuite/ld-mips-elf/ifunc-mix-1.sym           |   15 ++
 ld/testsuite/ld-mips-elf/ifunc-mix-1.t             |   18 ++
 ld/testsuite/ld-mips-elf/ifunc-mix-2.igot          |    3 +
 ld/testsuite/ld-mips-elf/ifunc-mix-2.s             |   55 ++++
 ld/testsuite/ld-mips-elf/ifunc-mix-2.sym           |   15 ++
 ld/testsuite/ld-mips-elf/ifunc-mix-2.t             |   19 ++
 ld/testsuite/ld-mips-elf/ifunc-static-def-mips16.s |  124 +++++++++
 ld/testsuite/ld-mips-elf/ifunc-static-def.s        |   98 +++++++
 .../ld-mips-elf/ifunc-static-main-mips16.s         |   18 ++
 ld/testsuite/ld-mips-elf/ifunc-static-main.s       |   21 ++
 ld/testsuite/ld-mips-elf/ifunc-static-ref.s        |   12 +
 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        |    4 +
 ld/testsuite/ld-mips-elf/mips-ifunc.exp            |  273
++++++++++++++++++++
 98 files changed, 1871 insertions(+), 2 deletions(-)
 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-10.s
 create mode 100644 ld/testsuite/ld-mips-elf/ifunc-11-o32.got
 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-11.s
 create mode 100644 ld/testsuite/ld-mips-elf/ifunc-12-o32.got
 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-12.s
 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.got
 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.got
 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.got
 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-6.dyn
 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-7.s
 create mode 100644 ld/testsuite/ld-mips-elf/ifunc-8-o32.got
 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-8.s
 create mode 100644 ld/testsuite/ld-mips-elf/ifunc-9-o32.got
 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-9.s
 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-mix-1.t
 create mode 100644 ld/testsuite/ld-mips-elf/ifunc-iplt-mix-2.t
 create mode 100644 ld/testsuite/ld-mips-elf/ifunc-iplt.ld
 create mode 100644 ld/testsuite/ld-mips-elf/ifunc-mix-1.igot
 create mode 100644 ld/testsuite/ld-mips-elf/ifunc-mix-1.s
 create mode 100644 ld/testsuite/ld-mips-elf/ifunc-mix-1.sym
 create mode 100644 ld/testsuite/ld-mips-elf/ifunc-mix-1.t
 create mode 100644 ld/testsuite/ld-mips-elf/ifunc-mix-2.igot
 create mode 100644 ld/testsuite/ld-mips-elf/ifunc-mix-2.s
 create mode 100644 ld/testsuite/ld-mips-elf/ifunc-mix-2.sym
 create mode 100644 ld/testsuite/ld-mips-elf/ifunc-mix-2.t
 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 ffff2f1..86baa93 100644
--- a/ld/testsuite/ld-ifunc/ifunc.exp
+++ b/ld/testsuite/ld-ifunc/ifunc.exp
@@ -24,13 +24,14 @@


 # IFUNC support has only been implemented for the ix86, x86_64, powerpc,
-# aarch64, sparc, and S/390 so far.
+# aarch64, sparc, S/390 and mips so far.
 if {!(([istarget "i?86-*-*"]
        || [istarget "x86_64-*-*"]
        || [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..97e99c4
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-10-o32.r
@@ -0,0 +1,3 @@
+#...
+00410214  00000080 R_MIPS_IRELATIVE *
+#pass
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..1c06e46
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-10-o32.sec
@@ -0,0 +1,5 @@
+#...
+.* \.iplt .*
+.*
+.* \.igot .*
+#pass
diff --git a/ld/testsuite/ld-mips-elf/ifunc-10.s
b/ld/testsuite/ld-mips-elf/ifunc-10.s
new file mode 100644
index 0000000..f3d58ce
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-10.s
@@ -0,0 +1,130 @@
+	.abicalls
+	.option	pic0
+	.text
+	.align	2
+	.ent	f1_a
+	.type	f1_a, @function
+f1_a:
+	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
+
+	.end	f1_a
+	.size	f1_a, .-f1_a
+	.align	2
+	.ent	f1_b
+	.type	f1_b, @function
+f1_b:
+	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
+
+	.end	f1_b
+	.size	f1_b, .-f1_b
+	.align	2
+	.ent	f1_c
+	.type	f1_c, @function
+f1_c:
+	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
+
+	.end	f1_c
+	.size	f1_c, .-f1_c
+	.align	2
+	.globl	func1_ifunc
+	.ent	func1_ifunc
+	.type	func1_ifunc, @function
+func1_ifunc:
+	addiu	$sp,$sp,-432
+	sw	$31,428($sp)
+	sw	$fp,424($sp)
+	move	$fp,$sp
+	addiu	$2,$fp,28
+	move	$4,$2
+	beq	$2,$0,$L8
+
+	li	$2,48			# 0x30
+	sw	$2,24($fp)
+	j	$L9
+
+$L8:
+	li	$2,3			# 0x3
+	sw	$2,24($fp)
+$L9:
+	lw	$2,24($fp)
+	andi	$2,$2,0xf0
+	beq	$2,$0,$L10
+
+	lui	$2,%hi(f1_a)
+	addiu	$2,$2,%lo(f1_a)
+	j	$L13
+
+$L10:
+	lw	$2,24($fp)
+	andi	$2,$2,0xf
+	beq	$2,$0,$L12
+
+	lui	$2,%hi(f1_b)
+	addiu	$2,$2,%lo(f1_b)
+	j	$L13
+
+$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
+
+	.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:
+	addiu	$sp,$sp,-32
+	sw	$31,28($sp)
+	sw	$fp,24($sp)
+	move	$fp,$sp
+	jal	func1
+
+	move	$sp,$fp
+	lw	$31,28($sp)
+	lw	$fp,24($sp)
+	addiu	$sp,$sp,32
+	j	$31
+
+	.end	main
+	.size	main, .-main
+
+	.section        .data.rel,"aw",@progbits
+	.align  2
+	.type   fptr, @object
+	.size   fptr, 4
+fptr:
+	.word   func1
diff --git a/ld/testsuite/ld-mips-elf/ifunc-11-o32.got
b/ld/testsuite/ld-mips-elf/ifunc-11-o32.got
new file mode 100644
index 0000000..c307e1f
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-11-o32.got
@@ -0,0 +1,4 @@
+#...
+Contents of section \.got:
+ 410180 00000000 80000000 00400000 00400160 .*
+#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..deeb023
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-11-o32.r
@@ -0,0 +1,3 @@
+#...
+00410174  00000080 R_MIPS_IRELATIVE *
+#pass
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..1c06e46
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-11-o32.sec
@@ -0,0 +1,5 @@
+#...
+.* \.iplt .*
+.*
+.* \.igot .*
+#pass
diff --git a/ld/testsuite/ld-mips-elf/ifunc-11.s
b/ld/testsuite/ld-mips-elf/ifunc-11.s
new file mode 100644
index 0000000..609837f
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-11.s
@@ -0,0 +1,69 @@
+	.gnu_attribute 4, 1
+	.abicalls
+	.text
+	.ent	f1_a
+	.type	f1_a, @function
+f1_a:
+	nop
+
+	.end	f1_a
+	.size	f1_a, .-f1_a
+	.ent	f1_b
+	.type	f1_b, @function
+f1_b:
+	nop
+
+	.end	f1_b
+	.size	f1_b, .-f1_b
+	.ent	f1_c
+	.type	f1_c, @function
+f1_c:
+	.frame	$fp,8,$31		# vars= 0, regs= 1/0, args= 0, gp= 0
+	nop
+
+	.end	f1_c
+	.size	f1_c, .-f1_c
+	.globl	func1_ifunc
+	.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)
+
+	.end	func1_ifunc
+	.size	func1_ifunc, .-func1_ifunc
+	.type	func1, @gnu_indirect_function
+	func1 = func1_ifunc
+
+	.globl	main
+	.ent	main
+	.type	main, @function
+main:
+	.cpload	$25
+	addiu	$sp,$sp,-32
+	sw	$31,28($sp)
+	sw	$fp,24($sp)
+	move	$fp,$sp
+	.cprestore	16
+	lw	$2,%got(func1)($28)
+	move	$25,$2
+	.reloc	1f,R_MIPS_JALR,func1
+1:	jalr	$25
+	move	$sp,$fp
+	lw	$31,28($sp)
+	lw	$fp,24($sp)
+	addiu	$sp,$sp,32
+	j	$31
+
+	.end	main
+	.size	main, .-main
+	.section	.data.rel,"aw",@progbits
+	.align	2
+	.type	fptr, @object
+	.size	fptr, 4
+fptr:
+	.word	func1
diff --git a/ld/testsuite/ld-mips-elf/ifunc-12-o32.got
b/ld/testsuite/ld-mips-elf/ifunc-12-o32.got
new file mode 100644
index 0000000..797f5ed
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-12-o32.got
@@ -0,0 +1,4 @@
+#...
+Contents of section \.got:
+ 410190 00000000 80000000 00400000 00400170  .*
+#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..9d52278
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-12-o32.r
@@ -0,0 +1,3 @@
+#...
+00410184  00000080 R_MIPS_IRELATIVE *
+#pass
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..1c06e46
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-12-o32.sec
@@ -0,0 +1,5 @@
+#...
+.* \.iplt .*
+.*
+.* \.igot .*
+#pass
diff --git a/ld/testsuite/ld-mips-elf/ifunc-12.s
b/ld/testsuite/ld-mips-elf/ifunc-12.s
new file mode 100644
index 0000000..779e8b2
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-12.s
@@ -0,0 +1,74 @@
+	.gnu_attribute 4, 1
+	.abicalls
+	.text
+	.ent	f1_a
+	.type	f1_a, @function
+f1_a:
+	nop
+	.end	f1_a
+	.size	f1_a, .-f1_a
+
+	.ent	f1_b
+	.type	f1_b, @function
+f1_b:
+	nop
+	.end	f1_b
+	.size	f1_b, .-f1_b
+
+	.ent	f1_c
+	.type	f1_c, @function
+f1_c:
+	.frame	$fp,8,$31		# vars= 0, regs= 1/0, args= 0, gp= 0
+	nop
+	.end	f1_c
+	.size	f1_c, .-f1_c
+
+	.globl	func1_ifunc
+	.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)
+	.end	func1_ifunc
+	.size	func1_ifunc, .-func1_ifunc
+
+	.type	func1, @gnu_indirect_function
+	func1 = func1_ifunc
+
+	.globl	main
+	.ent	main
+	.type	main, @function
+main:
+	.cpload	$25
+	addiu	$sp,$sp,-32
+	sw	$31,28($sp)
+	sw	$fp,24($sp)
+	move	$fp,$sp
+	.cprestore	16
+	lw	$2,%got(func1)($28)
+	move	$25,$2
+	jalr	$25
+
+	lui	$2,%hi(func1)
+	addiu	$2, $2, %lo(func1)
+
+	lw	$28,16($fp)
+	move	$sp,$fp
+	lw	$31,28($sp)
+	lw	$fp,24($sp)
+	addiu	$sp,$sp,32
+	j	$31
+
+	.end	main
+	.size	main, .-main
+
+	.section	.data.rel,"aw",@progbits
+	.align	2
+	.type	fptr, @object
+	.size	fptr, 4
+fptr:
+	.word	func1
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..9f31964
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-13-o32.r
@@ -0,0 +1,3 @@
+#...
+004101a8  00000080 R_MIPS_IRELATIVE *
+#pass
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..77fa4da
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-13-o32.sec
@@ -0,0 +1,3 @@
+#...
+.* \.iplt .*
+#pass
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..5e7e527
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-13-o32.t
@@ -0,0 +1,7 @@
+#...
+00400160 <main>:
+.*
+.*
+.*
+  40016c:	0c100064 	jal	400190 <\.iplt\.func1>
+#pass
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..c0c5188
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-3-n32.r
@@ -0,0 +1,3 @@
+#...
+00000c00  00000080 R_MIPS_IRELATIVE *
+#pass
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..ef58b9f
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-3-n32.sym
@@ -0,0 +1,3 @@
+#...
+    2   0: 00000800    24 FUNC    GLOBAL DEFAULT   1 func1
+#pass
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..96cd6d6
--- /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:
+
+00000800 <.iplt.func1>:
+ 800:	3c0f0000 	lui	t3,0x0
+ 804:	8df90c00 	lw	t9,3072\(t3\)
+ 808:	03200008 	jr	t9
+ 80c:	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..531a6a1
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-3-n64.r
@@ -0,0 +1,5 @@
+#...
+000000000c00  000000001280 R_MIPS_IRELATIVE *
+                    Type2: R_MIPS_64 *
+                    Type3: R_MIPS_NONE *
+#pass
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..64a1bc7
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-3-n64.sym
@@ -0,0 +1,3 @@
+#...
+    2   0: 0000000000000800    24 FUNC    GLOBAL DEFAULT   1 func1
+#pass
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..8bdab3b
--- /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:
+
+0000000000000800 <.iplt.func1>:
+ 800:	3c0f0000 	lui	t3,0x0
+ 804:	ddf90c00 	ld	t9,3072\(t3\)
+ 808:	03200008 	jr	t9
+ 80c:	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..c0c5188
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-3-o32.r
@@ -0,0 +1,3 @@
+#...
+00000c00  00000080 R_MIPS_IRELATIVE *
+#pass
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..ef58b9f
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-3-o32.sym
@@ -0,0 +1,3 @@
+#...
+    2   0: 00000800    24 FUNC    GLOBAL DEFAULT   1 func1
+#pass
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..f2e9ec3
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-3-o32.t
@@ -0,0 +1,10 @@
+tmpdir/ifunc-3-o32:     file format elf32-tradbigmips
+
+
+Disassembly of section .iplt:
+
+00000800 <.iplt.func1>:
+ 800:	3c0f0000 	lui	t7,0x0
+ 804:	8df90c00 	lw	t9,3072\(t7\)
+ 808:	03200008 	jr	t9
+ 80c:	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..b3cfa8a
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-4-n32.r
@@ -0,0 +1,3 @@
+#...
+00080800  00000080 R_MIPS_IRELATIVE *
+#pass
\ No newline at end of file
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..8803279
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-4-n32.sym
@@ -0,0 +1,4 @@
+#...
+    19: 00080000    16 FUNC    LOCAL  DEFAULT    1 .iplt.func1
+    20: 00080490   132 IFUNC   GLOBAL DEFAULT    2 func1
+#pass
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..da8be1d
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-4-n64.r
@@ -0,0 +1,5 @@
+#...
+000000080800  000000001280 R_MIPS_IRELATIVE *
+                    Type2: R_MIPS_64 *
+                    Type3: R_MIPS_NONE *
+#pass
\ No newline at end of file
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..8061f9a
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-4-n64.sym
@@ -0,0 +1,4 @@
+#...
+    19: 0000000000080000    32 FUNC    LOCAL  DEFAULT    1 .iplt.func1
+    20: 0000000000080490   132 IFUNC   GLOBAL DEFAULT    2 func1
+#pass
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..81eb2e4
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-4-o32.r
@@ -0,0 +1,3 @@
+#...
+00080800  00000080 R_MIPS_IRELATIVE *
+#pass
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..9bdc7d6
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-4-o32.sym
@@ -0,0 +1,4 @@
+#...
+    14: 00080000    16 FUNC    LOCAL  DEFAULT    1 .iplt.func1
+    15: 00080490   132 IFUNC   GLOBAL DEFAULT    2 func1
+#pass
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..1ae0031
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-4-o32.t
@@ -0,0 +1,10 @@
+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:	03200008 	jr	t9
+   8000c:	00000000 	nop
diff --git a/ld/testsuite/ld-mips-elf/ifunc-5-n32.got
b/ld/testsuite/ld-mips-elf/ifunc-5-n32.got
new file mode 100644
index 0000000..cc20d56
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-5-n32.got
@@ -0,0 +1,5 @@
+#...
+ General entries:
+   Address     Access  Initial
+  00000808 -32744\(gp\) 0000040c
+#pass
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..72a1f0c
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-5-n32.r
@@ -0,0 +1,3 @@
+#...
+00000808  00000203 R_MIPS_REL32      func1\(\)    func1
+#pass
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..33f34cc
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-5-n32.sym
@@ -0,0 +1,3 @@
+#...
+    2   0: 0000040c    24 IFUNC   GLOBAL DEFAULT   1 func1
+#pass
diff --git a/ld/testsuite/ld-mips-elf/ifunc-5-n64.got
b/ld/testsuite/ld-mips-elf/ifunc-5-n64.got
new file mode 100644
index 0000000..63fe9d5
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-5-n64.got
@@ -0,0 +1,5 @@
+#...
+ General entries:
+           Address     Access          Initial
+  0000000000000810 -32736\(gp\) 000000000000040c
+#pass
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..54dd021
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-5-n64.r
@@ -0,0 +1,5 @@
+#...
+000000000810  000200001203 R_MIPS_REL32      func1\(\)          func1
+                    Type2: R_MIPS_64 *
+                    Type3: R_MIPS_NONE *
+#pass
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..61b491e
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-5-n64.sym
@@ -0,0 +1,3 @@
+#...
+    2   0: 000000000000040c    24 IFUNC   GLOBAL DEFAULT   1 func1
+#pass
diff --git a/ld/testsuite/ld-mips-elf/ifunc-5-o32.got
b/ld/testsuite/ld-mips-elf/ifunc-5-o32.got
new file mode 100644
index 0000000..cc20d56
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-5-o32.got
@@ -0,0 +1,5 @@
+#...
+ General entries:
+   Address     Access  Initial
+  00000808 -32744\(gp\) 0000040c
+#pass
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..72a1f0c
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-5-o32.r
@@ -0,0 +1,3 @@
+#...
+00000808  00000203 R_MIPS_REL32      func1\(\)    func1
+#pass
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..33f34cc
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-5-o32.sym
@@ -0,0 +1,3 @@
+#...
+    2   0: 0000040c    24 IFUNC   GLOBAL DEFAULT   1 func1
+#pass
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..582a8d4
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-5.dyn
@@ -0,0 +1,3 @@
+#...
+ 0x0*70000036 \(MIPS_GENERAL_GOTNO\).* 3
+#pass
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..ea30a44
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-6-n32.r
@@ -0,0 +1,3 @@
+#...
+00000c08  00000080 R_MIPS_IRELATIVE *
+#pass
\ No newline at end of file
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..ef58b9f
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-6-n32.sym
@@ -0,0 +1,3 @@
+#...
+    2   0: 00000800    24 FUNC    GLOBAL DEFAULT   1 func1
+#pass
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..6155b9b
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-6-n64.r
@@ -0,0 +1,5 @@
+#...
+000000000c10  000000001280 R_MIPS_IRELATIVE *
+                    Type2: R_MIPS_64 *
+                    Type3: R_MIPS_NONE *
+#pass
\ No newline at end of file
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..64a1bc7
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-6-n64.sym
@@ -0,0 +1,3 @@
+#...
+    2   0: 0000000000000800    24 FUNC    GLOBAL DEFAULT   1 func1
+#pass
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..ea30a44
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-6-o32.r
@@ -0,0 +1,3 @@
+#...
+00000c08  00000080 R_MIPS_IRELATIVE *
+#pass
\ No newline at end of file
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..ef58b9f
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-6-o32.sym
@@ -0,0 +1,3 @@
+#...
+    2   0: 00000800    24 FUNC    GLOBAL DEFAULT   1 func1
+#pass
diff --git a/ld/testsuite/ld-mips-elf/ifunc-6.dyn
b/ld/testsuite/ld-mips-elf/ifunc-6.dyn
new file mode 100644
index 0000000..582a8d4
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-6.dyn
@@ -0,0 +1,3 @@
+#...
+ 0x0*70000036 \(MIPS_GENERAL_GOTNO\).* 3
+#pass
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..1b3e164
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-7-o32.r
@@ -0,0 +1,3 @@
+#...
+00410210  00000080 R_MIPS_IRELATIVE *
+#pass
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-7.s
b/ld/testsuite/ld-mips-elf/ifunc-7.s
new file mode 100644
index 0000000..993bf08
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-7.s
@@ -0,0 +1,115 @@
+	.abicalls
+	.option	pic0
+	.text
+	.ent	f1_a
+	.type	f1_a, @function
+f1_a:
+	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
+	.end	f1_a
+	.size	f1_a, .-f1_a
+
+	.ent	f1_b
+	.type	f1_b, @function
+f1_b:
+	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
+	.end	f1_b
+	.size	f1_b, .-f1_b
+
+	.ent	f1_c
+	.type	f1_c, @function
+f1_c:
+	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
+	.end	f1_c
+	.size	f1_c, .-f1_c
+
+	.globl	func1_ifunc
+	.ent	func1_ifunc
+	.type	func1_ifunc, @function
+func1_ifunc:
+	addiu	$sp,$sp,-432
+	sw	$31,428($sp)
+	sw	$fp,424($sp)
+	move	$fp,$sp
+	addiu	$2,$fp,28
+	move	$4,$2
+	beq	$2,$0,$L8
+	li	$2,48			# 0x30
+	sw	$2,24($fp)
+	j	$L9
+
+$L8:
+	li	$2,3			# 0x3
+	sw	$2,24($fp)
+$L9:
+	lw	$2,24($fp)
+	andi	$2,$2,0xf0
+	beq	$2,$0,$L10
+
+	lui	$2,%hi(f1_a)
+	addiu	$2,$2,%lo(f1_a)
+	j	$L13
+
+$L10:
+	lw	$2,24($fp)
+	andi	$2,$2,0xf
+	beq	$2,$0,$L12
+
+	lui	$2,%hi(f1_b)
+	addiu	$2,$2,%lo(f1_b)
+	j	$L13
+
+$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
+	.end	func1_ifunc
+	.size	func1_ifunc, .-func1_ifunc
+
+	.type	func1, @gnu_indirect_function
+	func1 = func1_ifunc
+
+	.globl	main
+	.ent	main
+	.option	pic0
+	.type	main, @function
+main:
+	addiu	$sp,$sp,-32
+	sw	$31,28($sp)
+	sw	$fp,24($sp)
+	move	$fp,$sp
+	jal	func1
+
+	move	$sp,$fp
+	lw	$31,28($sp)
+	lw	$fp,24($sp)
+	addiu	$sp,$sp,32
+	j	$31
+
+	.end	main
+	.size	main, .-main
diff --git a/ld/testsuite/ld-mips-elf/ifunc-8-o32.got
b/ld/testsuite/ld-mips-elf/ifunc-8-o32.got
new file mode 100644
index 0000000..0a1b3df
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-8-o32.got
@@ -0,0 +1,4 @@
+#...
+Contents of section \.got:
+ 410160 00000000 80000000 004000fc .*
+#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..75ea935
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-8-o32.r
@@ -0,0 +1,3 @@
+#...
+00410168  00000080 R_MIPS_IRELATIVE *
+#pass
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..fe3d6ba
--- /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
diff --git a/ld/testsuite/ld-mips-elf/ifunc-8.s
b/ld/testsuite/ld-mips-elf/ifunc-8.s
new file mode 100644
index 0000000..667b0cd
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-8.s
@@ -0,0 +1,64 @@
+	.gnu_attribute 4, 1
+	.abicalls
+	.text
+	.ent	f1_a
+	.type	f1_a, @function
+f1_a:
+	nop
+	.end	f1_a
+	.size	f1_a, .-f1_a
+
+	.ent	f1_b
+	.type	f1_b, @function
+f1_b:
+	nop
+	.end	f1_b
+	.size	f1_b, .-f1_b
+
+	.ent	f1_c
+	.type	f1_c, @function
+f1_c:
+	nop
+	.end	f1_c
+	.size	f1_c, .-f1_c
+
+	.globl	func1_ifunc
+	.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)
+	.end	func1_ifunc
+	.size	func1_ifunc, .-func1_ifunc
+
+	.type	func1, @gnu_indirect_function
+	func1 = func1_ifunc
+
+	.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
+	.cpload	$25
+	addiu	$sp,$sp,-32
+	sw	$31,28($sp)
+	sw	$fp,24($sp)
+	move	$fp,$sp
+	.cprestore	16
+	lw	$2,%got(func1)($28)
+	move	$25,$2
+1:	jalr	$25
+	move	$sp,$fp
+	lw	$31,28($sp)
+	lw	$fp,24($sp)
+	addiu	$sp,$sp,32
+	j	$31
+
+	.end	main
+	.size	main, .-main
diff --git a/ld/testsuite/ld-mips-elf/ifunc-9-o32.got
b/ld/testsuite/ld-mips-elf/ifunc-9-o32.got
new file mode 100644
index 0000000..7be3b66
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-9-o32.got
@@ -0,0 +1,4 @@
+#...
+Contents of section \.got:
+ 410190 00000000 80000000 004000fc .*
+#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..a28c20b
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-9-o32.r
@@ -0,0 +1,3 @@
+#...
+00410198  00000080 R_MIPS_IRELATIVE *
+#pass
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..345a261
--- /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
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..865d250
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-9-o32.t
@@ -0,0 +1,7 @@
+#...
+00400180 <.iplt.func1>:
+  400180:	3c0f0041 	lui	t7,0x41
+  400184:	8df90198 	lw	t9,408\(t7\)
+  400188:	03200008 	jr	t9
+  40018c:	00000000 	nop
+#pass
diff --git a/ld/testsuite/ld-mips-elf/ifunc-9.s
b/ld/testsuite/ld-mips-elf/ifunc-9.s
new file mode 100644
index 0000000..72c8a46
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-9.s
@@ -0,0 +1,94 @@
+	.gnu_attribute 4, 1
+	.abicalls
+	.text
+	.ent	f1_a
+	.type	f1_a, @function
+f1_a:
+	nop
+	.end	f1_a
+	.size	f1_a, .-f1_a
+
+	.ent	f1_b
+	.type	f1_b, @function
+f1_b:
+	nop
+	.end	f1_b
+	.size	f1_b, .-f1_b
+
+	.ent	f1_c
+	.type	f1_c, @function
+f1_c:
+	.frame	$fp,8,$31		# vars= 0, regs= 1/0, args= 0, gp= 0
+	nop
+	.end	f1_c
+	.size	f1_c, .-f1_c
+
+	.globl	func1_ifunc
+	.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)
+	.end	func1_ifunc
+	.size	func1_ifunc, .-func1_ifunc
+
+	.type	func1, @gnu_indirect_function
+	func1 = func1_ifunc
+
+	.option	pic0
+	.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
+	addiu	$sp,$sp,-32
+	sw	$31,28($sp)
+	sw	$fp,24($sp)
+	move	$fp,$sp
+	jal	func1
+
+	move	$sp,$fp
+	lw	$31,28($sp)
+	lw	$fp,24($sp)
+	addiu	$sp,$sp,32
+	j	$31
+
+	.end	ref1
+	.size	ref1, .-ref1
+
+	.globl	main
+	.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
+	.cpload	$25
+	addiu	$sp,$sp,-32
+	sw	$31,28($sp)
+	sw	$fp,24($sp)
+	move	$fp,$sp
+	.cprestore	16
+.reloc	1f,R_MIPS16_CALL16,func1
+1:	lw	$2,%call16(func1)($28)
+	move	$25,$2
+	jalr	$25
+
+	jal	ref1
+
+	lw	$28,16($fp)
+	move	$sp,$fp
+	lw	$31,28($sp)
+	lw	$fp,24($sp)
+	addiu	$sp,$sp,32
+	j	$31
+
+	.end	main
+	.size	main, .-main
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..8f904f1
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-dyn-def.s
@@ -0,0 +1,40 @@
+	.gnu_attribute 4, 1
+	.abicalls
+	.text
+	.ent	f1_a
+	.type	f1_a, @function
+f1_a:
+	nop
+	.end	f1_a
+	.size	f1_a, .-f1_a
+
+	.ent	f1_b
+	.type	f1_b, @function
+f1_b:
+	nop
+	.end	f1_b
+	.size	f1_b, .-f1_b
+
+	.ent	f1_c
+	.type	f1_c, @function
+f1_c:
+	nop
+	.end	f1_c
+	.size	f1_c, .-f1_c
+
+	.globl	func1_ifunc
+	.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)
+	.end	func1_ifunc
+	.size	func1_ifunc, .-func1_ifunc
+
+	.globl	func1
+	.type	func1, @gnu_indirect_function
+	func1 = func1_ifunc
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..3f9afac
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-dyn-main.s
@@ -0,0 +1,21 @@
+	.gnu_attribute 4, 1
+	.abicalls
+	.option	pic0
+	.text
+	.globl	main
+	.ent	main
+	.type	main, @function
+main:
+	addiu	$sp,$sp,-32
+	sw	$31,28($sp)
+	sw	$fp,24($sp)
+	move	$fp,$sp
+	jal	ref1
+
+	move	$sp,$fp
+	lw	$31,28($sp)
+	lw	$fp,24($sp)
+	addiu	$sp,$sp,32
+	j	$31
+	.end	main
+	.size	main, .-main
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..284b016
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-dyn-ref.s
@@ -0,0 +1,24 @@
+	.gnu_attribute 4, 1
+	.abicalls
+	.text
+	.globl	ref1
+	.ent	ref1
+	.type	ref1, @function
+ref1:
+	addiu	$sp,$sp,-32
+	sw	$31,28($sp)
+	sw	$fp,24($sp)
+	move	$fp,$sp
+	lw	$2,%call16(func1)($28)
+	move	$25,$2
+	jalr	$25
+
+	lw	$28,16($fp)
+	move	$sp,$fp
+	lw	$31,28($sp)
+	lw	$fp,24($sp)
+	addiu	$sp,$sp,32
+	j	$31
+
+	.end	ref1
+	.size	ref1, .-ref1
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..4ff90bc
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-dyn.ld
@@ -0,0 +1,27 @@
+ENTRY(_start)
+SECTIONS
+{
+  . = 0 + SIZEOF_HEADERS;
+
+  . = 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..cdd8d6c
--- /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:	ddf902e0 	ld	t9,736\(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..27eb668
--- /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:	ddf902e0 	ld	t9,736\(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..672a363
--- /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:	ddf902e0 	ld	t9,736\(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..4095700
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-iplt-micromips.igot
@@ -0,0 +1,4 @@
+tmpdir/ifunc-iplt-micromips:     file format elf32-tradbigmips
+
+Contents of section .igot:
+ 4101c0 00400141 .*
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..3249116
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-iplt-micromips.t
@@ -0,0 +1,10 @@
+tmpdir/ifunc-iplt-micromips:     file format elf32-tradbigmips
+
+
+Disassembly of section .iplt:
+
+004001b0 <.iplt.comp.func1>:
+  4001b0:	41af 0041 	lui	t7,0x41
+  4001b4:	ff2f 01c0 	lw	t9,448\(t7\)
+  4001b8:	45b9      	jrc	t9
+  4001ba:	0c00      	nop
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..00b341e
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-iplt-mips16.igot
@@ -0,0 +1,4 @@
+tmpdir/ifunc-iplt-mips16:     file format elf32-tradbigmips
+
+Contents of section .igot:
+ 410190 00400125 .*
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..0ae609e
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-iplt-mips16.t
@@ -0,0 +1,10 @@
+#...
+Disassembly of section .iplt:
+
+00400170 <.iplt.comp.func1>:
+  400170:	b202      	lw	v0,400178 <.iplt.comp.func1\+0x8>
+  400172:	9a40      	lw	v0,0\(v0\)
+  400174:	ea00      	jr	v0
+  400176:	653a      	move	t9,v0
+  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..10f77b7
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-iplt-mips32r6.t
@@ -0,0 +1,10 @@
+
+tmpdir/ifunc-iplt-mips32r6:     file format elf32-tradbigmips
+
+
+Disassembly of section .iplt:
+
+00400210 <.iplt.func1>:
+  400210:	3c0f0041 	lui	t7,0x41
+  400214:	8df90220 	lw	t9,544\(t7\)
+  400218:	d8190000 	jrc	t9
diff --git a/ld/testsuite/ld-mips-elf/ifunc-iplt-mix-1.t
b/ld/testsuite/ld-mips-elf/ifunc-iplt-mix-1.t
new file mode 100644
index 0000000..dff51f6
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-iplt-mix-1.t
@@ -0,0 +1,29 @@
+#...
+Disassembly of section .iplt:
+
+00400140 <.iplt.comp.func1>:
+  400140:	lw	v0,400148 <.iplt.comp.func1\+0x8>
+  400142:	lw	v0,0\(v0\)
+  400144:	jr	v0
+  400146:	move	t9,v0
+  400148:	addiu	s0,sp,260
+  40014a:	addiu	s1,sp,512
+
+0040014c <.iplt.comp.func2>:
+  40014c:	lw	v0,400154 <.iplt.comp.func2\+0x8>
+  40014e:	lw	v0,0\(v0\)
+  400150:	jr	v0
+  400152:	move	t9,v0
+  400154:	addiu	s0,sp,260
+  400156:	addiu	s1,sp,528
+
+00400158 <.iplt.func1>:
+  400158:	lui	t7,0x41
+  40015c:	lw	t9,384\(t7\)
+  400160:	jr	t9
+
+00400164 <.iplt.func2>:
+  400164:	lui	t7,0x41
+  400168:	lw	t9,388\(t7\)
+  40016c:	jr	t9
+  400170:	nop
diff --git a/ld/testsuite/ld-mips-elf/ifunc-iplt-mix-2.t
b/ld/testsuite/ld-mips-elf/ifunc-iplt-mix-2.t
new file mode 100644
index 0000000..24d7b47
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-iplt-mix-2.t
@@ -0,0 +1,27 @@
+tmpdir/ifunc-mix-2:     file format elf32-tradbigmips
+
+
+Disassembly of section .iplt:
+
+00400140 <.iplt.comp.func1>:
+  400140:	lui	t7,0x41
+  400144:	lw	t9,384\(t7\)
+  400148:	jrc	t9
+  40014a:	nop
+
+0040014c <.iplt.comp.func2>:
+  40014c:	lui	t7,0x41
+  400150:	lw	t9,388\(t7\)
+  400154:	jrc	t9
+  400156:	nop
+
+00400158 <.iplt.func1>:
+  400158:	lui	t7,0x41
+  40015c:	lw	t9,384\(t7\)
+  400160:	jr	t9
+
+00400164 <.iplt.func2>:
+  400164:	lui	t7,0x41
+  400168:	lw	t9,388\(t7\)
+  40016c:	jr	t9
+  400170:	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..b8e9598
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-iplt.ld
@@ -0,0 +1,27 @@
+ENTRY(_start)
+SECTIONS
+{
+  . = 0 + SIZEOF_HEADERS;
+  . = 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-mix-1.igot
b/ld/testsuite/ld-mips-elf/ifunc-mix-1.igot
new file mode 100644
index 0000000..08c8f77
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-mix-1.igot
@@ -0,0 +1,3 @@
+#...
+Contents of section .igot:
+ 410180 00400100 00400109 .*
diff --git a/ld/testsuite/ld-mips-elf/ifunc-mix-1.s
b/ld/testsuite/ld-mips-elf/ifunc-mix-1.s
new file mode 100644
index 0000000..a4f6afb
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-mix-1.s
@@ -0,0 +1,53 @@
+	.abicalls
+	.option	pic0
+	.text
+	.set nomips16
+	.globl	func1_ifunc
+	.ent	func1_ifunc
+	.type	func1_ifunc, @function
+func1_ifunc:
+	j	$31
+	.end	func1_ifunc
+	.size	func1_ifunc, .-func1_ifunc
+
+	.globl func1
+	.type	func1, @gnu_indirect_function
+	func1 = func1_ifunc
+
+	.set mips16
+	.globl	func2_ifunc
+	.ent	func2_ifunc
+	.type	func2_ifunc, @function
+func2_ifunc:
+	j	$31
+	.end	func2_ifunc
+	.size	func2_ifunc, .-func2_ifunc
+
+	.type	func2, @gnu_indirect_function
+	.globl func2
+	func2 = func2_ifunc
+
+	.set	nomips16
+	.globl	main
+	.ent	main
+	.option	pic0
+	.type	main, @function
+main:
+	move	$7, $31
+	jal	func2
+	jal	func1
+	jr	$7
+	.end	main
+	.size	main, .-main
+
+	.set	mips16
+	.globl	test_mips16
+	.ent	test_mips16
+	.type	test_mips16, @function
+test_mips16:
+	move	$7, $31
+	jal	func2
+	jal	func1
+	jr	$7
+	.end	test_mips16
+	.size	test_mips16, .-test_mips16
diff --git a/ld/testsuite/ld-mips-elf/ifunc-mix-1.sym
b/ld/testsuite/ld-mips-elf/ifunc-mix-1.sym
new file mode 100644
index 0000000..a58ad3f
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-mix-1.sym
@@ -0,0 +1,15 @@
+#...
+     9: 00400158    12 FUNC    LOCAL  DEFAULT    5 \.iplt\.func1
+.*
+    11: 0040014c    12 FUNC    LOCAL  DEFAULT \[MIPS16\]     5
\.iplt\.comp\.func2
+    12: 00400140    12 FUNC    LOCAL  DEFAULT \[MIPS16\]     5
\.iplt\.comp\.func1
+    13: 00400164    16 FUNC    LOCAL  DEFAULT    5 \.iplt\.func2
+.*
+.*
+    16: 00400100     8 IFUNC   GLOBAL DEFAULT    4 func1
+.*
+.*
+.*
+.*
+    21: 00400108     4 IFUNC   GLOBAL DEFAULT \[MIPS16\]     4 func2
+#pass
diff --git a/ld/testsuite/ld-mips-elf/ifunc-mix-1.t
b/ld/testsuite/ld-mips-elf/ifunc-mix-1.t
new file mode 100644
index 0000000..e6010bb
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-mix-1.t
@@ -0,0 +1,18 @@
+#...
+0040010c <main>:
+  40010c:	move	a3,ra
+  400110:	jal	400164 <\.iplt\.func2>
+  400114:	nop
+  400118:	jal	400158 <\.iplt\.func1>
+  40011c:	nop
+  400120:	jr	a3
+  400124:	nop
+
+00400128 <test_mips16>:
+  400128:	move	a3,ra
+  40012a:	jal	40014c <\.iplt\.comp\.func2>
+  40012e:	nop
+  400130:	jal	400140 <\.iplt\.comp\.func1>
+  400134:	nop
+  400136:	jr	a3
+#pass
diff --git a/ld/testsuite/ld-mips-elf/ifunc-mix-2.igot
b/ld/testsuite/ld-mips-elf/ifunc-mix-2.igot
new file mode 100644
index 0000000..08c8f77
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-mix-2.igot
@@ -0,0 +1,3 @@
+#...
+Contents of section .igot:
+ 410180 00400100 00400109 .*
diff --git a/ld/testsuite/ld-mips-elf/ifunc-mix-2.s
b/ld/testsuite/ld-mips-elf/ifunc-mix-2.s
new file mode 100644
index 0000000..b019337
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-mix-2.s
@@ -0,0 +1,55 @@
+	.abicalls
+	.option	pic0
+	.text
+	.set nomicromips
+	.globl	func1_ifunc
+	.ent	func1_ifunc
+	.type	func1_ifunc, @function
+func1_ifunc:
+	j	$31
+	.end	func1_ifunc
+	.size	func1_ifunc, .-func1_ifunc
+
+	.globl func1
+	.type	func1, @gnu_indirect_function
+	func1 = func1_ifunc
+
+	.set micromips
+	.globl	func2_ifunc
+	.ent	func2_ifunc
+	.type	func2_ifunc, @function
+func2_ifunc:
+	j	$31
+	.end	func2_ifunc
+	.size	func2_ifunc, .-func2_ifunc
+
+	.type	func2, @gnu_indirect_function
+	.globl func2
+	func2 = func2_ifunc
+
+	.align	2
+	.set nomicromips
+	.globl	main
+	.ent	main
+	.option	pic0
+	.type	main, @function
+main:
+	move	$7, $31
+	jal	func2
+	jal	func1
+	jr	$7
+	.end	main
+	.size	main, .-main
+
+	.set	micromips
+	.globl	test_micromips
+	.ent	test_micromips
+	.option	pic0
+	.type	test_micromips, @function
+test_micromips:
+	move	$7, $31
+	jal	func2
+	jal	func1
+	jr	$7
+	.end	test_micromips
+	.size	test_micromips, .-test_micromips
diff --git a/ld/testsuite/ld-mips-elf/ifunc-mix-2.sym
b/ld/testsuite/ld-mips-elf/ifunc-mix-2.sym
new file mode 100644
index 0000000..7e1a48f
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-mix-2.sym
@@ -0,0 +1,15 @@
+#...
+     9: 00400158    12 FUNC    LOCAL  DEFAULT    5 \.iplt\.func1
+.*
+    11: 0040014c    12 FUNC    LOCAL  DEFAULT \[MICROMIPS\]     5
\.iplt\.comp\.func2
+    12: 00400140    12 FUNC    LOCAL  DEFAULT \[MICROMIPS\]     5
\.iplt\.comp\.func1
+    13: 00400164    16 FUNC    LOCAL  DEFAULT    5 \.iplt\.func2
+.*
+.*
+    16: 00400100     8 IFUNC   GLOBAL DEFAULT    4 func1
+.*
+.*
+.*
+.*
+    21: 00400108     2 IFUNC   GLOBAL DEFAULT \[MICROMIPS\]     4 func2
+#pass
diff --git a/ld/testsuite/ld-mips-elf/ifunc-mix-2.t
b/ld/testsuite/ld-mips-elf/ifunc-mix-2.t
new file mode 100644
index 0000000..03563d3
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-mix-2.t
@@ -0,0 +1,19 @@
+#...
+0040010c <main>:
+  40010c:	move	a3,ra
+  400110:	jal	400164 <\.iplt\.func2>
+  400114:	nop
+  400118:	jal	400158 <\.iplt\.func1>
+  40011c:	nop
+  400120:	jr	a3
+  400124:	nop
+
+00400128 <test_micromips>:
+  400128:	move	a3,ra
+  40012a:	jal	40014c <\.iplt\.comp\.func2>
+  40012e:	nop
+  400132:	jal	400140 <\.iplt\.comp\.func1>
+  400136:	nop
+  40013a:	jrc	a3
+  40013c:	nop
+#pass
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..6202e4e
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-static-def-mips16.s
@@ -0,0 +1,124 @@
+	.abicalls
+	.option	pic0
+	.text
+
+	.align	2
+
+	.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
+	move	$17,$sp
+	li	$2,1
+	move	$sp,$17
+	restore	8,$17
+	j	$31
+	.end	f1_a
+
+	.size	f1_a, .-f1_a
+	.align	2
+	.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
+	move	$17,$sp
+	li	$2,2
+	move	$sp,$17
+	restore	8,$17
+	j	$31
+	.end	f1_b
+
+	.size	f1_b, .-f1_b
+	.align	2
+	.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
+	move	$17,$sp
+	li	$2,3
+	move	$sp,$17
+	restore	8,$17
+	j	$31
+	.end	f1_c
+	.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
+	.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
+	move	$17,$sp
+	lw	$2,$L13
+	lw	$2,0($2)
+	beqz	$2,$L8
+	li	$2,48
+	sw	$2,8($17)
+	b	$L9
+$L8:
+	li	$2,3
+	sw	$2,8($17)
+$L9:
+	lw	$3,8($17)
+	li	$2,240
+	and	$2,$3
+	beqz	$2,$L10
+	lw	$2,$L14
+	b	$L11
+$L10:
+	lw	$3,8($17)
+	li	$2,15
+	and	$2,$3
+	beqz	$2,$L12
+	lw	$2,$L15
+	b	$L11
+$L12:
+	lw	$2,$L16
+$L11:
+	move	$sp,$17
+	restore	24,$17
+	j	$31
+	.align	2
+$L13:
+	.word	global
+$L14:
+	.word	f1_a
+$L15:
+	.word	f1_b
+$L16:
+	.word	f1_c
+	.end	func1_ifunc
+
+	.size	func1_ifunc, .-func1_ifunc
+	.globl	func1
+	.type	func1, @gnu_indirect_function
+	func1 = func1_ifunc
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..1550b04
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-static-def.s
@@ -0,0 +1,98 @@
+	.abicalls
+	.option	pic0
+	.text
+	.ent	f1_a
+	.type	f1_a, @function
+f1_a:
+	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
+	.end	f1_a
+	.size	f1_a, .-f1_a
+
+	.ent	f1_b
+	.type	f1_b, @function
+f1_b:
+	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
+	.end	f1_b
+	.size	f1_b, .-f1_b
+
+	.ent	f1_c
+	.type	f1_c, @function
+f1_c:
+	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
+	.end	f1_c
+	.size	f1_c, .-f1_c
+
+	.globl	func1_ifunc
+	.ent	func1_ifunc
+	.type	func1_ifunc, @function
+func1_ifunc:
+	addiu	$sp,$sp,-432
+	sw	$31,428($sp)
+	sw	$fp,424($sp)
+	move	$fp,$sp
+	addiu	$2,$fp,28
+	move	$4,$2
+
+	beq	$2,$0,$L8
+
+	li	$2,48			# 0x30
+	sw	$2,24($fp)
+	j	$L9
+
+$L8:
+	li	$2,3			# 0x3
+	sw	$2,24($fp)
+$L9:
+	lw	$2,24($fp)
+	andi	$2,$2,0xf0
+	beq	$2,$0,$L10
+
+	lui	$2,%hi(f1_a)
+	addiu	$2,$2,%lo(f1_a)
+	j	$L13
+
+$L10:
+	lw	$2,24($fp)
+	andi	$2,$2,0xf
+	beq	$2,$0,$L12
+
+	lui	$2,%hi(f1_b)
+	addiu	$2,$2,%lo(f1_b)
+	j	$L13
+
+$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
+
+	.end	func1_ifunc
+	.size	func1_ifunc, .-func1_ifunc
+	.globl	func1
+	.type	func1, @gnu_indirect_function
+	func1 = func1_ifunc
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..953e704
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-static-main-mips16.s
@@ -0,0 +1,18 @@
+	.abicalls
+	.option	pic0
+	.text
+	.align	2
+	.globl	main
+	.set	mips16
+	.set	nomicromips
+	.ent	main
+	.type	main, @function
+main:
+	save	32,$17,$31
+	addiu	$17,$sp,16
+	jal	func1
+	move	$sp,$17
+	restore	16,$17,$31
+	j	$31
+	.end	main
+	.size	main, .-main
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..36f6330
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-static-main.s
@@ -0,0 +1,21 @@
+	.abicalls
+	.option	pic0
+	.text
+	.globl	main
+	.ent	main
+	.type	main, @function
+main:
+	addiu	$sp,$sp,-32
+	sw	$31,28($sp)
+	sw	$fp,24($sp)
+	move	$fp,$sp
+	jal	func1
+
+	move	$sp,$fp
+	lw	$31,28($sp)
+	lw	$fp,24($sp)
+	addiu	$sp,$sp,32
+	j	$31
+
+	.end	main
+	.size	main, .-main
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..c275102
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/ifunc-static-ref.s
@@ -0,0 +1,12 @@
+	.abicalls
+	.option	pic0
+	.text
+	.globl	ref1
+	.set 	mips32r2
+	.ent	ref1
+	.type	ref1, @function
+ref1:
+	jal	func1
+	j	$31
+	.end	ref1
+	.size	ref1, .-ref1
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..31725ea
--- /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: 0000040c    24 FUNC    GLOBAL DEFAULT   1 func1_ifunc
+    2   0: 0000040c    24 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..b289382
--- /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: 000000000000040c    24 FUNC    GLOBAL DEFAULT   1 func1_ifunc
+    2   0: 000000000000040c    24 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..31725ea
--- /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: 0000040c    24 FUNC    GLOBAL DEFAULT   1 func1_ifunc
+    2   0: 0000040c    24 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..801ed0e
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/libifunc-2-n32.sym
@@ -0,0 +1,4 @@
+#...
+    2   0: 00000400    56 FUNC    GLOBAL DEFAULT   1 ref1
+    3   0: 00000440     0 FUNC    GLOBAL DEFAULT UND func1
+#pass
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..02cea64
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/libifunc-2-n64.sym
@@ -0,0 +1,4 @@
+#...
+    2   0: 0000000000000400    56 FUNC    GLOBAL DEFAULT   1 ref1
+    3   0: 0000000000000440     0 FUNC    GLOBAL DEFAULT UND func1
+#pass
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..801ed0e
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/libifunc-2-o32.sym
@@ -0,0 +1,4 @@
+#...
+    2   0: 00000400    56 FUNC    GLOBAL DEFAULT   1 ref1
+    3   0: 00000440     0 FUNC    GLOBAL DEFAULT UND func1
+#pass
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..27d5d2d
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/mips-ifunc.exp
@@ -0,0 +1,273 @@
+# Expect script for MIPS IFUNC linker tests
+#   Copyright 2016
+#   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) "-mips32"
+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 (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 (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 (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 (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 (DSO 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" \
+		"readelf -A ifunc-5-${abi}.got"] \
+	    "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 (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}" \
+	] \
+    ]
+}
+
+
+set abi o32
+run_ld_link_tests [list \
+	[list \
+	    "IFUNC 7 (Local binding with non-PIC call-only ref) ${abi}" \
+	    "$abi_ldflags($abi) -static -Bstatic" "" \
+	    "$abi_asflags($abi)" \
+	     [list ifunc-7.s] \
+	     [list "readelf -r ifunc-7-${abi}.r" \
+		 "readelf -S ifunc-7-${abi}.sec"] \
+	    "ifunc-7-${abi}" \
+	] \
+	[list \
+	    "IFUNC 8 (Local binding with PIC call-only ref) ${abi}" \
+	    "$abi_ldflags($abi) -static" "" \
+	    "$abi_asflags($abi)" \
+	     [list ifunc-8.s] \
+	     [list "readelf -r ifunc-8-${abi}.r" \
+		 "readelf -S ifunc-8-${abi}.sec" \
+		 "objdump -sj.got ifunc-8-${abi}.got"] \
+	    "ifunc-8-${abi}" \
+	] \
+	[list \
+	    "IFUNC 9 (Local binding with PIC/non-PIC call-only refs) ${abi}" \
+	    "$abi_ldflags($abi) -static -Bstatic" "" \
+	    "$abi_asflags($abi) -non_shared" \
+	    [list ifunc-9.s] \
+	    [list "readelf -r ifunc-9-${abi}.r" \
+		"readelf -S ifunc-9-${abi}.sec" \
+		"objdump -sj.got ifunc-9-${abi}.got" \
+		"objdump -dj.iplt ifunc-9-${abi}.t"] \
+	    "ifunc-9-${abi}" \
+	] \
+	[list \
+	    "IFUNC 10 (Local binding with non-PIC call/non-call refs) ${abi}" \
+	    "$abi_ldflags($abi) -static -Bstatic" "" \
+	    "$abi_asflags($abi) -non_shared" \
+	    [list ifunc-10.s] \
+	    [list "readelf -r ifunc-10-${abi}.r" \
+		"readelf -S ifunc-10-${abi}.sec"] \
+	    "ifunc-10-${abi}" \
+	] \
+	[list \
+	    "IFUNC 11 (Local binding with PIC-only call/non-call refs) ${abi}" \
+	    "$abi_ldflags($abi) -static" "" \
+	    "$abi_asflags($abi)" \
+	    [list ifunc-11.s] \
+	    [list "readelf -r ifunc-11-${abi}.r" \
+		"readelf -S ifunc-11-${abi}.sec" \
+		"objdump -sj.got ifunc-11-${abi}.got"] \
+	    "ifunc-11-${abi}" \
+	] \
+	[list \
+	    "IFUNC 12 (Local binding with PIC/non-PIC, call/non-call refs)
${abi}" \
+	    "$abi_ldflags($abi) -static -Bstatic" "" \
+	    "$abi_asflags($abi) -non_shared" \
+	    [list ifunc-12.s] \
+	    [list "readelf -r ifunc-12-${abi}.r" \
+		"readelf -S ifunc-12-${abi}.sec" \
+		"objdump -sj.got ifunc-12-${abi}.got"] \
+	    "ifunc-12-${abi}" \
+	] \
+	[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}" \
+	] \
+	[list \
+	    "IFUNC IPLT (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" \
+	] \
+	[list \
+	    "IFUNC IPLT (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 -sj.igot ifunc-iplt-micromips.igot"] \
+	    "ifunc-iplt-micromips" \
+	] \
+	[list \
+	    "IFUNC IPLT (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 -sj.igot ifunc-iplt-mips16.igot"] \
+	    "ifunc-iplt-mips16" \
+	] \
+	[list \
+	    "IFUNC IPLT Mix 1 (mips32 & mips16)" \
+	    "$abi_ldflags($abi) -static -Bstatic" "" \
+	    "$abi_asflags($abi) -mips2" \
+	    [list ifunc-mix-1.s] \
+	     { { readelf -s ifunc-mix-1.sym } \
+	      { objdump -sj.igot ifunc-mix-1.igot } \
+	      { objdump {-dj.iplt --no-show-raw-insn} ifunc-iplt-mix-1.t } \
+	      { objdump {-dj.text --no-show-raw-insn} ifunc-mix-1.t } }\
+	    "ifunc-mix-1" \
+	] \
+	[list \
+	    "IFUNC IPLT Mix 2 (mips32 & micromips)" \
+	    "$abi_ldflags($abi) -static -Bstatic" "" \
+	    "$abi_asflags($abi) -mips2" \
+	    [list ifunc-mix-2.s] \
+	     { { readelf -s ifunc-mix-2.sym } \
+	       { objdump -sj.igot ifunc-mix-2.igot } \
+	       { objdump { -dj.iplt --no-show-raw-insn } ifunc-iplt-mix-2.t } \
+	       { objdump { -dj.text --no-show-raw-insn } ifunc-mix-2.t } } \
+	    "ifunc-mix-2" \
+	] \
+]
-- 
1.7.9.5


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