This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[Committed] S/390: Optimize symbolic pointer reads from the GOT with larl
- From: Andreas Krebbel <krebbel at linux dot vnet dot ibm dot com>
- To: binutils at sourceware dot org
- Date: Fri, 5 Jul 2013 11:58:46 +0200
- Subject: [Committed] S/390: Optimize symbolic pointer reads from the GOT with larl
Hi,
with the attached patch various symbolic pointer reads from the GOT
are rewritten using larl instruction.
This could be further improved by also trying to get rid of the GOT
slot in the end.
No testsuite regressions on s390 and s390x.
Applied to mainline binutils.
Bye,
-Andreas-
2013-07-05 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
bfd/
* elf32-s390.c: Rewrite GOT accesses using larl if possible.
* elf64-s390.c: Likewise.
ld/testsuite/
* ld-s390/gotreloc-1.s: New file.
* ld-s390/gotreloc-1.ver: New file.
* ld-s390/gotreloc_31-1.dd: New file.
* ld-s390/gotreloc_64-1.dd: New file.
* ld-s390/s390.exp: Run the new tests. Run 31 bit tests also on 64
bit.
---
bfd/elf32-s390.c | 30 ++++++++++++++++++++++++++++++
bfd/elf64-s390.c | 31 +++++++++++++++++++++++++++++++
ld/testsuite/ld-s390/gotreloc-1.s | 11 +++++++++++
ld/testsuite/ld-s390/gotreloc-1.ver | 1 +
ld/testsuite/ld-s390/gotreloc_31-1.dd | 14 ++++++++++++++
ld/testsuite/ld-s390/gotreloc_64-1.dd | 12 ++++++++++++
ld/testsuite/ld-s390/s390.exp | 11 +++++++++++
7 files changed, 110 insertions(+)
Index: binutils/bfd/elf64-s390.c
===================================================================
--- binutils.orig/bfd/elf64-s390.c
+++ binutils/bfd/elf64-s390.c
@@ -2496,6 +2496,37 @@ elf_s390_relocate_section (bfd *output_b
base_got->contents + off);
h->got.offset |= 1;
}
+
+ if ((h->def_regular
+ && info->shared
+ && SYMBOL_REFERENCES_LOCAL (info, h))
+ /* lgrl rx,sym@GOTENT -> larl rx, sym */
+ && ((r_type == R_390_GOTENT
+ && (bfd_get_16 (input_bfd,
+ contents + rel->r_offset - 2)
+ & 0xff0f) == 0xc408)
+ /* lg rx, sym@GOT(r12) -> larl rx, sym */
+ || (r_type == R_390_GOT20
+ && (bfd_get_32 (input_bfd,
+ contents + rel->r_offset - 2)
+ & 0xff00f000) == 0xe300c000
+ && bfd_get_8 (input_bfd,
+ contents + rel->r_offset + 3) == 0x04)))
+
+ {
+ unsigned short new_insn =
+ (0xc000 | (bfd_get_8 (input_bfd,
+ contents + rel->r_offset - 1) & 0xf0));
+ bfd_put_16 (output_bfd, new_insn,
+ contents + rel->r_offset - 2);
+ r_type = R_390_PC32DBL;
+ rel->r_addend = 2;
+ howto = elf_howto_table + r_type;
+ relocation = h->root.u.def.value
+ + h->root.u.def.section->output_section->vma
+ + h->root.u.def.section->output_offset;
+ goto do_relocation;
+ }
}
else
unresolved_reloc = FALSE;
Index: binutils/bfd/elf32-s390.c
===================================================================
--- binutils.orig/bfd/elf32-s390.c
+++ binutils/bfd/elf32-s390.c
@@ -2536,6 +2536,36 @@ elf_s390_relocate_section (bfd *output_b
base_got->contents + off);
h->got.offset |= 1;
}
+
+ if ((h->def_regular
+ && info->shared
+ && SYMBOL_REFERENCES_LOCAL (info, h))
+ /* lrl rx,sym@GOTENT -> larl rx, sym */
+ && ((r_type == R_390_GOTENT
+ && (bfd_get_16 (input_bfd,
+ contents + rel->r_offset - 2)
+ & 0xff0f) == 0xc40d)
+ /* ly rx, sym@GOT(r12) -> larl rx, sym */
+ || (r_type == R_390_GOT20
+ && (bfd_get_32 (input_bfd,
+ contents + rel->r_offset - 2)
+ & 0xff00f000) == 0xe300c000
+ && bfd_get_8 (input_bfd,
+ contents + rel->r_offset + 3) == 0x58)))
+ {
+ unsigned short new_insn =
+ (0xc000 | (bfd_get_8 (input_bfd,
+ contents + rel->r_offset - 1) & 0xf0));
+ bfd_put_16 (output_bfd, new_insn,
+ contents + rel->r_offset - 2);
+ r_type = R_390_PC32DBL;
+ rel->r_addend = 2;
+ howto = elf_howto_table + r_type;
+ relocation = h->root.u.def.value
+ + h->root.u.def.section->output_section->vma
+ + h->root.u.def.section->output_offset;
+ goto do_relocation;
+ }
}
else
unresolved_reloc = FALSE;
Index: binutils/ld/testsuite/ld-s390/gotreloc-1.ver
===================================================================
--- /dev/null
+++ binutils/ld/testsuite/ld-s390/gotreloc-1.ver
@@ -0,0 +1 @@
+{ local: bar; };
Index: binutils/ld/testsuite/ld-s390/gotreloc-1.s
===================================================================
--- /dev/null
+++ binutils/ld/testsuite/ld-s390/gotreloc-1.s
@@ -0,0 +1,11 @@
+ .text
+ .globl foo
+foo:
+ lgrl %r1,bar@GOTENT
+ lg %r1,bar@GOT(%r12)
+ lrl %r1,bar@GOTENT
+ l %r1,bar@GOT(%r12)
+ ly %r1,bar@GOT(%r12)
+
+.globl bar
+bar: .long 0x123
Index: binutils/ld/testsuite/ld-s390/s390.exp
===================================================================
--- binutils.orig/ld/testsuite/ld-s390/s390.exp
+++ binutils/ld/testsuite/ld-s390/s390.exp
@@ -48,6 +48,11 @@ set s390tests {
{{readelf -Ssrl tlsbin.rd} {objdump -dzrj.text tlsbin.dd}
{objdump -sj.got tlsbin.sd} {objdump -sj.tdata tlsbin.td}}
"tlsbin"}
+ {"GOT: symbol address load from got to larl"
+ "-shared -melf_s390 --version-script=gotreloc-1.ver" ""
+ "-m31" {gotreloc-1.s}
+ {{objdump -dzrj.text gotreloc_31-1.dd}}
+ "gotreloc_31-1"}
}
set s390xtests {
@@ -64,6 +69,11 @@ set s390xtests {
{{readelf -WSsrl tlsbin_64.rd} {objdump -dzrj.text tlsbin_64.dd}
{objdump -sj.got tlsbin_64.sd} {objdump -sj.tdata tlsbin_64.td}}
"tlsbin_64"}
+ {"GOT: symbol address load from got to larl"
+ "-shared -melf64_s390 --version-script=gotreloc-1.ver" ""
+ "-m64" {gotreloc-1.s}
+ {{objdump -dzrj.text gotreloc_64-1.dd}}
+ "gotreloc_64-1"}
}
if [istarget "s390-*-*"] {
@@ -71,5 +81,6 @@ if [istarget "s390-*-*"] {
}
if [istarget "s390x-*-*"] {
+ run_ld_link_tests $s390tests
run_ld_link_tests $s390xtests
}
Index: binutils/ld/testsuite/ld-s390/gotreloc_64-1.dd
===================================================================
--- /dev/null
+++ binutils/ld/testsuite/ld-s390/gotreloc_64-1.dd
@@ -0,0 +1,12 @@
+tmpdir/gotreloc_64-1: file format elf64-s390
+
+Disassembly of section .text:
+
+.* <foo>:
+.*: c0 10 00 00 00 0e [ ]*larl %r1,.* <bar>
+.*: c0 10 00 00 00 0b [ ]*larl %r1,.* <bar>
+.*: c4 1d 00 00 08 86 [ ]*lrl %r1,.* <_GLOBAL_OFFSET_TABLE_\+0x18>
+.*: 58 10 c0 18 [ ]*l %r1,24\(%r12\)
+.*: e3 10 c0 18 00 58 [ ]*ly %r1,24\(%r12\)
+.* <bar>:
+.*: 00 00 01 23 .long 0x00000123
Index: binutils/ld/testsuite/ld-s390/gotreloc_31-1.dd
===================================================================
--- /dev/null
+++ binutils/ld/testsuite/ld-s390/gotreloc_31-1.dd
@@ -0,0 +1,14 @@
+
+tmpdir/gotreloc_31-1: file format elf32-s390
+
+Disassembly of section .text:
+
+.* <foo>:
+.*: c4 18 00 00 .long 0xc4180000
+.*: 08 4e e3 10 .long 0x084ee310
+.*: c0 0c 00 04 .long 0xc00c0004
+.*: c0 10 00 00 00 08 [ ]*larl %r1,168 <bar>
+.*: 58 10 c0 0c [ ]*l %r1,12\(%r12\)
+.*: c0 10 00 00 00 03 [ ]*larl %r1,168 <bar>
+.* <bar>:
+.*: 00 00 01 23 .long 0x00000123