diff -rup binutils.orig/bfd/elf32-s390.c binutils-2.25.1/bfd/elf32-s390.c
--- binutils.orig/bfd/elf32-s390.c 2017-05-09 11:06:34.741540539 +0100
+++ binutils-2.25.1/bfd/elf32-s390.c 2017-05-09 11:08:21.140239839 +0100
@@ -2728,7 +2728,7 @@ elf_s390_relocate_section (bfd *output_b
&& s390_is_ifunc_symbol_p (h)
&& h->def_regular)
{
- if (!info->shared || !h->non_got_ref)
+ if (!info->shared)
{
/* For a non-shared object STT_GNU_IFUNC symbol must
go through PLT. */
diff -rup binutils.orig/bfd/elf64-s390.c binutils-2.25.1/bfd/elf64-s390.c
--- binutils.orig/bfd/elf64-s390.c 2017-05-09 11:06:34.711540906 +0100
+++ binutils-2.25.1/bfd/elf64-s390.c 2017-05-09 11:09:23.495477558 +0100
@@ -2693,10 +2693,11 @@ elf_s390_relocate_section (bfd *output_b
&& s390_is_ifunc_symbol_p (h)
&& h->def_regular)
{
- if (!info->shared || !h->non_got_ref)
+ if (!info->shared)
{
- /* For a non-shared object STT_GNU_IFUNC symbol must
- go through PLT. */
+ /* For a non-shared object the symbol will not
+ change. Hence we can write the address of the
+ target IPLT slot now. */
relocation = (htab->elf.iplt->output_section->vma
+ htab->elf.iplt->output_offset
+ h ->plt.offset);
diff -rup binutils.orig/bfd/elf-s390-common.c binutils-2.25.1/bfd/elf-s390-common.c
--- binutils.orig/bfd/elf-s390-common.c 2017-05-09 11:06:34.715540857 +0100
+++ binutils-2.25.1/bfd/elf-s390-common.c 2017-05-09 11:07:34.079815141 +0100
@@ -159,9 +159,7 @@ keep:
h->type = STT_FUNC;
}
- /* We need dynamic relocation for STT_GNU_IFUNC symbol only when
- there is a non-GOT reference in a shared object. */
- if (!info->shared || !h->non_got_ref)
+ if (!info->shared)
*head = NULL;
/* Finally, allocate space. */
diff -rupN binutils.orig/ld/testsuite/ld-s390/pltoffset-1.dd binutils-2.25.1/ld/testsuite/ld-s390/pltoffset-1.dd
--- binutils.orig/ld/testsuite/ld-s390/pltoffset-1.dd 1970-01-01 01:00:00.000000000 +0100
+++ binutils-2.25.1/ld/testsuite/ld-s390/pltoffset-1.dd 2017-05-09 11:16:02.644598050 +0100
@@ -0,0 +1,8 @@
+tmpdir/pltoffset-1: file format elf64-s390
+
+Disassembly of section .text:
+
+.* <.text>:
+.*: 00 00 00 00 [ ]*.long 0x00000000
+.*: e3 10 f0 38 00 24 [ ]*stg %r1,56\(%r15\)
+.*: c0 10 00 00 00 27 [ ]*larl %r1,58 <_GLOBAL_OFFSET_TABLE_>
diff -rupN binutils.orig/ld/testsuite/ld-s390/pltoffset-1.ld binutils-2.25.1/ld/testsuite/ld-s390/pltoffset-1.ld
--- binutils.orig/ld/testsuite/ld-s390/pltoffset-1.ld 1970-01-01 01:00:00.000000000 +0100
+++ binutils-2.25.1/ld/testsuite/ld-s390/pltoffset-1.ld 2017-05-09 11:16:02.644598050 +0100
@@ -0,0 +1,34 @@
+SECTIONS
+{
+ .text : {
+ . = . + 4;
+ *(.plt)
+ }
+ .test : {
+ *(.text)
+ *(.got)
+ *(.got.plt)
+ *(.rodata)
+ *(.eh_frame)
+ *(.interp)
+ *(.data)
+ *(.bss)
+ }
+
+ /* For old binutils which otherwise complain about nonrepresentable
+ sections. */
+ .dynsym : { *(.dynsym) }
+ .gnu.version : { *(.gnu.version) }
+
+ /DISCARD/ : {
+ *(.rela.text)
+ *(.rela.plt)
+ *(.rela.got.plt)
+ *(.rela.data)
+ *(.rela.rodata)
+ *(.rela.bss)
+ *(.rela.text)
+ *(.comment*)
+ *(.note*)
+ }
+}
diff -rupN binutils.orig/ld/testsuite/ld-s390/pltoffset-1.s binutils-2.25.1/ld/testsuite/ld-s390/pltoffset-1.s
--- binutils.orig/ld/testsuite/ld-s390/pltoffset-1.s 1970-01-01 01:00:00.000000000 +0100
+++ binutils-2.25.1/ld/testsuite/ld-s390/pltoffset-1.s 2017-05-09 11:16:02.645598038 +0100
@@ -0,0 +1,12 @@
+ .file "hello.c"
+.text
+ .align 8
+.globl main
+ .type main, @function
+main:
+ brasl %r5,foo@PLT
+ br %r4
+ .size main, .-main
+
+.globl foo
+foo: .long 123