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]

powerpc64 lazy link stub


Someone recently hit a limitation of the lazy linking stub generated by
powerpc64 ld, which required that .plt was within 2G of .glink.
Effectively this meant that binaries were limited to 2G of data/rodata
type sections.  It's not unreasonable to expect such large binaries to
run on a 64-bit system, so this patch replaces the stub with one that
doesn't have a size limit.

bfd/
	* elf64-ppc.c (create_linkage_sections): Align .glink to 8 bytes.
	(ppc64_elf_build_stubs): Use new lazy linking stub.
ld/testsuite/
	* ld-powerpc/tlsexe.d: Update for laze link stub change.
	* ld-powerpc/tlsexe.r: Likewise.
	* ld-powerpc/tlsexetoc.d: Likewise.
	* ld-powerpc/tlsexetoc.r: Likewise.
	* ld-powerpc/tlsso.d: Likewise.
	* ld-powerpc/tlstocso.d: Likewise.

Index: bfd/elf64-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-ppc.c,v
retrieving revision 1.243
diff -u -p -r1.243 elf64-ppc.c
--- bfd/elf64-ppc.c	17 Aug 2006 08:09:52 -0000	1.243
+++ bfd/elf64-ppc.c	17 Aug 2006 08:10:21 -0000
@@ -135,30 +135,29 @@ static bfd_vma opd_entry_value
 #define BCTR		0x4e800420	/* bctr			     */
 
 
+#define ADDIS_R12_R12	0x3d8c0000	/* addis %r12,%r12,off@ha  */
 #define ADDIS_R2_R2	0x3c420000	/* addis %r2,%r2,off@ha  */
 #define ADDI_R2_R2	0x38420000	/* addi  %r2,%r2,off@l   */
 
 #define LD_R2_40R1	0xe8410028	/* ld    %r2,40(%r1)     */
 
-/* glink call stub instructions.  We enter with the index in R0, and the
-   address of glink entry in CTR.  From that, we can calculate PLT0.  */
+/* glink call stub instructions.  We enter with the index in R0.  */
 #define GLINK_CALL_STUB_SIZE (16*4)
-#define MFCTR_R12	0x7d8902a6	/* mfctr  %r12			*/
-#define SLDI_R11_R0_3	0x780b1f24	/* sldi	  %r11,%r0,3		*/
-#define ADDIC_R2_R0_32K 0x34408000	/* addic. %r2,%r0,-32768	*/
-#define SUB_R12_R12_R11 0x7d8b6050	/* sub	  %r12,%r12,%r11	*/
-#define SRADI_R2_R2_63	0x7c42fe76	/* sradi  %r2,%r2,63		*/
-#define SLDI_R11_R0_2	0x780b1764	/* sldi	  %r11,%r0,2		*/
-#define AND_R2_R2_R11	0x7c425838	/* and	  %r2,%r2,%r11		*/
-					/* sub	  %r12,%r12,%r11	*/
-#define ADD_R12_R12_R2	0x7d8c1214	/* add	  %r12,%r12,%r2		*/
-#define ADDIS_R12_R12	0x3d8c0000	/* addis  %r12,%r12,xxx@ha	*/
-					/* ld	  %r11,xxx@l(%r12)	*/
-#define ADDI_R12_R12	0x398c0000	/* addi	  %r12,%r12,xxx@l	*/
-					/* ld	  %r2,8(%r12)		*/
-					/* mtctr  %r11			*/
-					/* ld	  %r11,16(%r12)		*/
-					/* bctr				*/
+					/* 0:				*/
+					/*  .quad plt0-1f		*/
+					/* __glink:			*/
+#define MFLR_R12	0x7d8802a6	/*  mflr %12			*/
+#define BCL_20_31	0x429f0005	/*  bcl 20,31,1f		*/
+					/* 1:				*/
+#define MFLR_R11	0x7d6802a6	/*  mflr %11			*/
+#define LD_R2_M16R11	0xe84bfff0	/*  ld %2,(0b-1b)(%11)		*/
+#define MTLR_R12	0x7d8803a6	/*  mtlr %12			*/
+#define ADD_R12_R2_R11	0x7d825a14	/*  add %12,%2,%11		*/
+					/*  ld %11,0(%12)		*/
+					/*  ld %2,8(%12)		*/
+					/*  mtctr %11			*/
+					/*  ld %11,16(%12)		*/
+					/*  bctr			*/
 
 /* Pad with this.  */
 #define NOP		0x60000000
@@ -3728,7 +3727,7 @@ create_linkage_sections (bfd *dynobj, st
   htab->glink = bfd_make_section_anyway_with_flags (dynobj, ".glink",
 						    flags);
   if (htab->glink == NULL
-      || ! bfd_set_section_alignment (dynobj, htab->glink, 2))
+      || ! bfd_set_section_alignment (dynobj, htab->glink, 3))
     return FALSE;
 
   /* Create branch lookup table for plt_branch stubs.  */
@@ -9458,18 +9457,6 @@ ppc64_elf_build_stubs (bfd_boolean emit_
       bfd_vma plt0;
 
       /* Build the .glink plt call stub.  */
-      plt0 = (htab->plt->output_section->vma
-	      + htab->plt->output_offset
-	      - (htab->glink->output_section->vma
-		 + htab->glink->output_offset
-		 + GLINK_CALL_STUB_SIZE));
-      if (plt0 + 0x80008000 > 0xffffffff)
-	{
-	  (*_bfd_error_handler) (_(".glink and .plt too far apart"));
-	  bfd_set_error (bfd_error_bad_value);
-	  return FALSE;
-	}
-
       if (htab->emit_stub_syms)
 	{
 	  struct elf_link_hash_entry *h;
@@ -9480,7 +9467,7 @@ ppc64_elf_build_stubs (bfd_boolean emit_
 	    {
 	      h->root.type = bfd_link_hash_defined;
 	      h->root.u.def.section = htab->glink;
-	      h->root.u.def.value = 0;
+	      h->root.u.def.value = 8;
 	      h->ref_regular = 1;
 	      h->def_regular = 1;
 	      h->ref_regular_nonweak = 1;
@@ -9489,29 +9476,26 @@ ppc64_elf_build_stubs (bfd_boolean emit_
 	    }
 	}
       p = htab->glink->contents;
-      bfd_put_32 (htab->glink->owner, MFCTR_R12, p);
-      p += 4;
-      bfd_put_32 (htab->glink->owner, SLDI_R11_R0_3, p);
-      p += 4;
-      bfd_put_32 (htab->glink->owner, ADDIC_R2_R0_32K, p);
-      p += 4;
-      bfd_put_32 (htab->glink->owner, SUB_R12_R12_R11, p);
-      p += 4;
-      bfd_put_32 (htab->glink->owner, SRADI_R2_R2_63, p);
-      p += 4;
-      bfd_put_32 (htab->glink->owner, SLDI_R11_R0_2, p);
+      plt0 = (htab->plt->output_section->vma
+	      + htab->plt->output_offset
+	      - (htab->glink->output_section->vma
+		 + htab->glink->output_offset
+		 + 16));
+      bfd_put_64 (htab->glink->owner, plt0, p);
+      p += 8;
+      bfd_put_32 (htab->glink->owner, MFLR_R12, p);
       p += 4;
-      bfd_put_32 (htab->glink->owner, AND_R2_R2_R11, p);
+      bfd_put_32 (htab->glink->owner, BCL_20_31, p);
       p += 4;
-      bfd_put_32 (htab->glink->owner, SUB_R12_R12_R11, p);
+      bfd_put_32 (htab->glink->owner, MFLR_R11, p);
       p += 4;
-      bfd_put_32 (htab->glink->owner, ADD_R12_R12_R2, p);
+      bfd_put_32 (htab->glink->owner, LD_R2_M16R11, p);
       p += 4;
-      bfd_put_32 (htab->glink->owner, ADDIS_R12_R12 | PPC_HA (plt0), p);
+      bfd_put_32 (htab->glink->owner, MTLR_R12, p);
       p += 4;
-      bfd_put_32 (htab->glink->owner, LD_R11_0R12 | PPC_LO (plt0), p);
+      bfd_put_32 (htab->glink->owner, ADD_R12_R2_R11, p);
       p += 4;
-      bfd_put_32 (htab->glink->owner, ADDI_R12_R12 | PPC_LO (plt0), p);
+      bfd_put_32 (htab->glink->owner, LD_R11_0R12, p);
       p += 4;
       bfd_put_32 (htab->glink->owner, LD_R2_0R12 | 8, p);
       p += 4;
@@ -9521,6 +9505,11 @@ ppc64_elf_build_stubs (bfd_boolean emit_
       p += 4;
       bfd_put_32 (htab->glink->owner, BCTR, p);
       p += 4;
+      while (p - htab->glink->contents < GLINK_CALL_STUB_SIZE)
+	{
+	  bfd_put_32 (htab->glink->owner, NOP, p);
+	  p += 4;
+	}
 
       /* Build the .glink lazy link call stubs.  */
       indx = 0;
@@ -9539,7 +9528,7 @@ ppc64_elf_build_stubs (bfd_boolean emit_
 	      p += 4;
 	    }
 	  bfd_put_32 (htab->glink->owner,
-		      B_DOT | ((htab->glink->contents - p) & 0x3fffffc), p);
+		      B_DOT | ((htab->glink->contents - p + 8) & 0x3fffffc), p);
 	  indx++;
 	  p += 4;
 	}
Index: ld/testsuite/ld-powerpc/tlsexe.d
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-powerpc/tlsexe.d,v
retrieving revision 1.5
diff -u -p -r1.5 tlsexe.d
--- ld/testsuite/ld-powerpc/tlsexe.d	16 Mar 2004 00:58:43 -0000	1.5
+++ ld/testsuite/ld-powerpc/tlsexe.d	17 Aug 2006 07:33:26 -0000
@@ -56,21 +56,22 @@ Disassembly of section \.text:
 .*	e9 4d 90 2a 	lwa     r10,-28632\(r13\)
 .*	3d 2d 00 00 	addis   r9,r13,0
 .*	a9 49 90 30 	lha     r10,-28624\(r9\)
-.*	7d 89 02 a6 	mfctr   r12
-.*	78 0b 1f 24 	rldicr  r11,r0,3,60
-.*	34 40 80 00 	addic\.  r2,r0,-32768
-.*	7d 8b 60 50 	subf    r12,r11,r12
-.*	7c 42 fe 76 	sradi   r2,r2,63
-.*	78 0b 17 64 	rldicr  r11,r0,2,61
-.*	7c 42 58 38 	and     r2,r2,r11
-.*	7d 8b 60 50 	subf    r12,r11,r12
-.*	7d 8c 12 14 	add     r12,r12,r2
-.*	3d 8c 00 01 	addis   r12,r12,1
-.*	e9 6c 01 c4 	ld      r11,452\(r12\)
-.*	39 8c 01 c4 	addi    r12,r12,452
+.*	60 00 00 00 	nop
+.*	00 00 00 00 .*
+.*	00 01 01 f0 .*
+.*	7d 88 02 a6 	mflr    r12
+.*	42 9f 00 05 	bcl-    20,4\*cr7\+so,.*
+.*	7d 68 02 a6 	mflr    r11
+.*	e8 4b ff f0 	ld      r2,-16\(r11\)
+.*	7d 88 03 a6 	mtlr    r12
+.*	7d 82 5a 14 	add     r12,r2,r11
+.*	e9 6c 00 00 	ld      r11,0\(r12\)
 .*	e8 4c 00 08 	ld      r2,8\(r12\)
 .*	7d 69 03 a6 	mtctr   r11
 .*	e9 6c 00 10 	ld      r11,16\(r12\)
 .*	4e 80 04 20 	bctr
+.*	60 00 00 00 	nop
+.*	60 00 00 00 	nop
+.*	60 00 00 00 	nop
 .*	38 00 00 00 	li      r0,0
-.*	4b ff ff bc 	b       .*
+.*	4b ff ff c4 	b       .*
Index: ld/testsuite/ld-powerpc/tlsexe.r
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-powerpc/tlsexe.r,v
retrieving revision 1.17
diff -u -p -r1.17 tlsexe.r
--- ld/testsuite/ld-powerpc/tlsexe.r	2 Jun 2006 07:53:30 -0000	1.17
+++ ld/testsuite/ld-powerpc/tlsexe.r	17 Aug 2006 07:33:26 -0000
@@ -16,7 +16,7 @@ Section Headers:
  +\[ 4\] \.dynstr +.*
  +\[ 5\] \.rela\.dyn +.*
  +\[ 6\] \.rela\.plt +.*
- +\[ 7\] \.text +PROGBITS .* 0+fc 0+ +AX +0 +0 +4
+ +\[ 7\] \.text +PROGBITS .* 0+100 0+ +AX +0 +0 +8
  +\[ 8\] \.rodata + PROGBITS .* 0+ 0+ +A +0 +0 +8
  +\[ 9\] \.tdata +PROGBITS .* 0+38 0+ WAT +0 +0 +8
  +\[10\] \.tbss +NOBITS .* 0+38 0+ WAT +0 +0 +8
Index: ld/testsuite/ld-powerpc/tlsexetoc.d
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-powerpc/tlsexetoc.d,v
retrieving revision 1.6
diff -u -p -r1.6 tlsexetoc.d
--- ld/testsuite/ld-powerpc/tlsexetoc.d	16 Mar 2004 00:58:43 -0000	1.6
+++ ld/testsuite/ld-powerpc/tlsexetoc.d	17 Aug 2006 07:33:26 -0000
@@ -40,21 +40,22 @@ Disassembly of section \.text:
 .*	89 4d 90 60 	lbz     r10,-28576\(r13\)
 .*	3d 2d 00 00 	addis   r9,r13,0
 .*	99 49 90 68 	stb     r10,-28568\(r9\)
-.*	7d 89 02 a6 	mfctr   r12
-.*	78 0b 1f 24 	rldicr  r11,r0,3,60
-.*	34 40 80 00 	addic\.  r2,r0,-32768
-.*	7d 8b 60 50 	subf    r12,r11,r12
-.*	7c 42 fe 76 	sradi   r2,r2,63
-.*	78 0b 17 64 	rldicr  r11,r0,2,61
-.*	7c 42 58 38 	and     r2,r2,r11
-.*	7d 8b 60 50 	subf    r12,r11,r12
-.*	7d 8c 12 14 	add     r12,r12,r2
-.*	3d 8c 00 01 	addis   r12,r12,1
-.*	e9 6c 01 ec 	ld      r11,492\(r12\)
-.*	39 8c 01 ec 	addi    r12,r12,492
+.*	60 00 00 00 	nop
+.*	00 00 00 00 .*
+.*	00 01 02 18 .*
+.*	7d 88 02 a6 	mflr    r12
+.*	42 9f 00 05 	bcl-    20,4\*cr7\+so,.*
+.*	7d 68 02 a6 	mflr    r11
+.*	e8 4b ff f0 	ld      r2,-16\(r11\)
+.*	7d 88 03 a6 	mtlr    r12
+.*	7d 82 5a 14 	add     r12,r2,r11
+.*	e9 6c 00 00 	ld      r11,0\(r12\)
 .*	e8 4c 00 08 	ld      r2,8\(r12\)
 .*	7d 69 03 a6 	mtctr   r11
 .*	e9 6c 00 10 	ld      r11,16\(r12\)
 .*	4e 80 04 20 	bctr
+.*	60 00 00 00 	nop
+.*	60 00 00 00 	nop
+.*	60 00 00 00 	nop
 .*	38 00 00 00 	li      r0,0
-.*	4b ff ff bc 	b       .*
+.*	4b ff ff c4 	b       .*
Index: ld/testsuite/ld-powerpc/tlsexetoc.r
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-powerpc/tlsexetoc.r,v
retrieving revision 1.18
diff -u -p -r1.18 tlsexetoc.r
--- ld/testsuite/ld-powerpc/tlsexetoc.r	2 Jun 2006 07:53:30 -0000	1.18
+++ ld/testsuite/ld-powerpc/tlsexetoc.r	17 Aug 2006 07:33:26 -0000
@@ -16,7 +16,7 @@ Section Headers:
  +\[ 4\] \.dynstr +.*
  +\[ 5\] \.rela\.dyn +.*
  +\[ 6\] \.rela\.plt +.*
- +\[ 7\] \.text +PROGBITS .* 0+bc 0+ +AX +0 +0 +4
+ +\[ 7\] \.text +PROGBITS .* 0+c0 0+ +AX +0 +0 +8
  +\[ 8\] \.rodata +PROGBITS .* 0+ 0+ +A +0 +0 +8
  +\[ 9\] \.tdata +PROGBITS .* 0+38 0+ WAT +0 +0 +8
  +\[10\] \.tbss +NOBITS .* 0+38 0+ WAT +0 +0 +8
Index: ld/testsuite/ld-powerpc/tlsso.d
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-powerpc/tlsso.d,v
retrieving revision 1.4
diff -u -p -r1.4 tlsso.d
--- ld/testsuite/ld-powerpc/tlsso.d	16 Mar 2004 00:58:43 -0000	1.4
+++ ld/testsuite/ld-powerpc/tlsso.d	17 Aug 2006 07:33:26 -0000
@@ -56,21 +56,22 @@ Disassembly of section \.text:
 .*	e9 4d 00 02 	lwa     r10,0\(r13\)
 .*	3d 2d 00 00 	addis   r9,r13,0
 .*	a9 49 00 00 	lha     r10,0\(r9\)
-.*	7d 89 02 a6 	mfctr   r12
-.*	78 0b 1f 24 	rldicr  r11,r0,3,60
-.*	34 40 80 00 	addic\.  r2,r0,-32768
-.*	7d 8b 60 50 	subf    r12,r11,r12
-.*	7c 42 fe 76 	sradi   r2,r2,63
-.*	78 0b 17 64 	rldicr  r11,r0,2,61
-.*	7c 42 58 38 	and     r2,r2,r11
-.*	7d 8b 60 50 	subf    r12,r11,r12
-.*	7d 8c 12 14 	add     r12,r12,r2
-.*	3d 8c 00 01 	addis   r12,r12,1
-.*	e9 6c 01 f4 	ld      r11,500\(r12\)
-.*	39 8c 01 f4 	addi    r12,r12,500
+.*	60 00 00 00 	nop
+.*	00 00 00 00 .*
+.*	00 01 02 20 .*
+.*	7d 88 02 a6 	mflr    r12
+.*	42 9f 00 05 	bcl-    20,4\*cr7\+so,.*
+.*	7d 68 02 a6 	mflr    r11
+.*	e8 4b ff f0 	ld      r2,-16\(r11\)
+.*	7d 88 03 a6 	mtlr    r12
+.*	7d 82 5a 14 	add     r12,r2,r11
+.*	e9 6c 00 00 	ld      r11,0\(r12\)
 .*	e8 4c 00 08 	ld      r2,8\(r12\)
 .*	7d 69 03 a6 	mtctr   r11
 .*	e9 6c 00 10 	ld      r11,16\(r12\)
 .*	4e 80 04 20 	bctr
+.*	60 00 00 00 	nop
+.*	60 00 00 00 	nop
+.*	60 00 00 00 	nop
 .*	38 00 00 00 	li      r0,0
-.*	4b ff ff bc 	b       .*
+.*	4b ff ff c4 	b       .*
Index: ld/testsuite/ld-powerpc/tlstocso.d
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-powerpc/tlstocso.d,v
retrieving revision 1.4
diff -u -p -r1.4 tlstocso.d
--- ld/testsuite/ld-powerpc/tlstocso.d	16 Mar 2004 00:58:43 -0000	1.4
+++ ld/testsuite/ld-powerpc/tlstocso.d	17 Aug 2006 07:33:26 -0000
@@ -40,21 +40,22 @@ Disassembly of section \.text:
 .*	89 4d 00 00 	lbz     r10,0\(r13\)
 .*	3d 2d 00 00 	addis   r9,r13,0
 .*	99 49 00 00 	stb     r10,0\(r9\)
-.*	7d 89 02 a6 	mfctr   r12
-.*	78 0b 1f 24 	rldicr  r11,r0,3,60
-.*	34 40 80 00 	addic\.  r2,r0,-32768
-.*	7d 8b 60 50 	subf    r12,r11,r12
-.*	7c 42 fe 76 	sradi   r2,r2,63
-.*	78 0b 17 64 	rldicr  r11,r0,2,61
-.*	7c 42 58 38 	and     r2,r2,r11
-.*	7d 8b 60 50 	subf    r12,r11,r12
-.*	7d 8c 12 14 	add     r12,r12,r2
-.*	3d 8c 00 01 	addis   r12,r12,1
-.*	e9 6c 01 ec 	ld      r11,492\(r12\)
-.*	39 8c 01 ec 	addi    r12,r12,492
+.*	60 00 00 00 	nop
+.*	00 00 00 00 .*
+.*	00 01 02 18 .*
+.*	7d 88 02 a6 	mflr    r12
+.*	42 9f 00 05 	bcl-    20,4\*cr7\+so,.*
+.*	7d 68 02 a6 	mflr    r11
+.*	e8 4b ff f0 	ld      r2,-16\(r11\)
+.*	7d 88 03 a6 	mtlr    r12
+.*	7d 82 5a 14 	add     r12,r2,r11
+.*	e9 6c 00 00 	ld      r11,0\(r12\)
 .*	e8 4c 00 08 	ld      r2,8\(r12\)
 .*	7d 69 03 a6 	mtctr   r11
 .*	e9 6c 00 10 	ld      r11,16\(r12\)
 .*	4e 80 04 20 	bctr
+.*	60 00 00 00 	nop
+.*	60 00 00 00 	nop
+.*	60 00 00 00 	nop
 .*	38 00 00 00 	li      r0,0
-.*	4b ff ff bc 	b       .*
+.*	4b ff ff c4 	b       .*

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre


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