This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[PATCH 2/2] [RFC] Add IFUNC support for MIPS (v5)
- From: Faraz Shahbazker <faraz dot shahbazker at imgtec dot com>
- To: "Maciej W. Rozycki" <macro at imgtec dot com>
- Cc: "binutils at sourceware dot org" <binutils at sourceware dot org>, Richard Sandiford <rdsandiford at googlemail dot com>
- Date: Tue, 24 Jan 2017 12:41:09 -0800
- Subject: [PATCH 2/2] [RFC] Add IFUNC support for MIPS (v5)
- Authentication-results: sourceware.org; auth=none
- References: <5583540C.7070800@imgtec.com> <87381jtr31.fsf@googlemail.com> <55899D52.1050000@imgtec.com> <87vbeegucz.fsf@googlemail.com> <5589AFCD.10905@imgtec.com> <DCB1C42372B1674B8F912A294CCB775A71680718@BADAG02.ba.imgtec.org> <87615awnv8.fsf@googlemail.com> <5600517C.1030608@imgtec.com> <874mig14xs.fsf@googlemail.com> <561D2820.10107@imgtec.com> <871tc0acam.fsf@googlemail.com> <5678829D.4080108@imgtec.com> <877fk6jewx.fsf@googlemail.com> <568EFE7B.60708@imgtec.com> <alpine.DEB.2.00.1602101549000.15885@tp.orcam.me.uk> <56E9CE2D.1000607@imgtec.com> <alpine.DEB.2.00.1604280258340.21846@tp.orcam.me.uk> <573FD344.50801@imgtec.com> <alpine.DEB.2.00.1605231607150.6794@tp.orcam.me.uk>
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