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]

[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


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