This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
PowerPC64 plt call stubs vs SMP
- From: Alan Modra <amodra at bigpond dot net dot au>
- To: binutils at sourceware dot org
- Date: Thu, 24 Jan 2008 16:34:58 +1030
- Subject: PowerPC64 plt call stubs vs SMP
This patch cures a problem with PowerPC64 plt call stubs. Lazy PLT
resolution and multiple threads running on SMP boxes mean we can have
one thread updating a PLT entry at the same time another is performing
a call using that entry. There isn't a problem in the writer. We do
all the right things in ld.so to make it SMP safe. The problem is
that the plt call stub loading the entry can read PLT entry words out
of order, leading to an invalid TOC pointer.
So, this forces the read to be in order by making the load address of
the TOC pointer word depend on the entry point word by inserting the
low bit of the entry word into the address. The entry point must be a
multiple of four and the TOC pointer a multiple of eight so this just
replaces one zero with another.
I'm not committing this just yet. There may be a better solution than
slowing down function calls like this, eg. LD_BIND_NOW on multiple
thread apps.
bfd/
* elf64-ppc.c (PLT_CALL_STUB_SIZE): Define as 8 insns.
(RLDIMI_R12_R11, RLDIMI_R2_R11): Define.
(build_plt_stub): Add rldimi instructions.
ld/testsuite/
* ld-powerpc/tlsexe.d: Update.
* ld-powerpc/tlsexe.g: Update.
* ld-powerpc/tlsexe.r: Update.
* ld-powerpc/tlsexetoc.d: Update.
* ld-powerpc/tlsexetoc.g: Update.
* ld-powerpc/tlsexetoc.r: Update.
* ld-powerpc/tlsso.d: Update.
* ld-powerpc/tlsso.g: Update.
* ld-powerpc/tlsso.r: Update.
* ld-powerpc/tlstocso.d: Update.
* ld-powerpc/tlstocso.g: Update.
Index: bfd/elf64-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-ppc.c,v
retrieving revision 1.274
diff -u -p -r1.274 elf64-ppc.c
--- bfd/elf64-ppc.c 19 Jan 2008 10:07:25 -0000 1.274
+++ bfd/elf64-ppc.c 24 Jan 2008 01:54:35 -0000
@@ -133,25 +133,28 @@ static bfd_vma opd_entry_value
/* .plt call stub instructions. The normal stub is like this, but
sometimes the .plt entry crosses a 64k boundary and we need to
insert an addi to adjust r12. */
-#define PLT_CALL_STUB_SIZE (7*4)
-#define ADDIS_R12_R2 0x3d820000 /* addis %r12,%r2,xxx@ha */
-#define STD_R2_40R1 0xf8410028 /* std %r2,40(%r1) */
-#define LD_R11_0R12 0xe96c0000 /* ld %r11,xxx+0@l(%r12) */
-#define MTCTR_R11 0x7d6903a6 /* mtctr %r11 */
-#define LD_R2_0R12 0xe84c0000 /* ld %r2,xxx+8@l(%r12) */
- /* ld %r11,xxx+16@l(%r12) */
-#define BCTR 0x4e800420 /* bctr */
-
-
-#define ADDIS_R12_R12 0x3d8c0000 /* addis %r12,%r12,off@ha */
-#define ADDI_R12_R12 0x398c0000 /* addi %r12,%r12,off@l */
-#define ADDIS_R2_R2 0x3c420000 /* addis %r2,%r2,off@ha */
-#define ADDI_R2_R2 0x38420000 /* addi %r2,%r2,off@l */
+#define PLT_CALL_STUB_SIZE (8*4)
+#define ADDIS_R12_R2 0x3d820000 /* addis %r12,%r2,xxx@ha */
+#define STD_R2_40R1 0xf8410028 /* std %r2,40(%r1) */
+#define LD_R11_0R12 0xe96c0000 /* ld %r11,xxx+0@l(%r12) */
+#define RLDIMI_R12_R11 0x796c07ec /* rldimi %r12,%r11,0,63 */
+
+#define MTCTR_R11 0x7d6903a6 /* mtctr %r11 */
+#define LD_R2_0R12 0xe84c0000 /* ld %r2,xxx+8@l(%r12) */
+ /* ld %r11,xxx+16@l(%r12) */
+#define BCTR 0x4e800420 /* bctr */
+
+
+#define ADDIS_R12_R12 0x3d8c0000 /* addis %r12,%r12,off@ha */
+#define ADDI_R12_R12 0x398c0000 /* addi %r12,%r12,off@l */
+#define ADDIS_R2_R2 0x3c420000 /* addis %r2,%r2,off@ha */
+#define ADDI_R2_R2 0x38420000 /* addi %r2,%r2,off@l */
+
+#define RLDIMI_R2_R11 0x796207ec /* rldimi %r2,%r11,0,63 */
+#define LD_R11_0R2 0xe9620000 /* ld %r11,xxx+0(%r2) */
+#define LD_R2_0R2 0xe8420000 /* ld %r2,xxx+0(%r2) */
-#define LD_R11_0R2 0xe9620000 /* ld %r11,xxx+0(%r2) */
-#define LD_R2_0R2 0xe8420000 /* ld %r2,xxx+0(%r2) */
-
-#define LD_R2_40R1 0xe8410028 /* ld %r2,40(%r1) */
+#define LD_R2_40R1 0xe8410028 /* ld %r2,40(%r1) */
/* glink call stub instructions. We enter with the index in R0. */
#define GLINK_CALL_STUB_SIZE (16*4)
@@ -8264,6 +8267,7 @@ build_plt_stub (bfd *obfd, bfd_byte *p,
bfd_put_32 (obfd, ADDI_R12_R12 | PPC_LO (offset), p), p += 4;
offset = 0;
}
+ bfd_put_32 (obfd, RLDIMI_R12_R11, p), p += 4;
bfd_put_32 (obfd, MTCTR_R11, p), p += 4;
bfd_put_32 (obfd, LD_R2_0R12 | PPC_LO (offset + 8), p), p += 4;
bfd_put_32 (obfd, LD_R11_0R12 | PPC_LO (offset + 16), p), p += 4;
@@ -8278,6 +8282,7 @@ build_plt_stub (bfd *obfd, bfd_byte *p,
bfd_put_32 (obfd, ADDI_R2_R2 | PPC_LO (offset), p), p += 4;
offset = 0;
}
+ bfd_put_32 (obfd, RLDIMI_R2_R11, p), p += 4;
bfd_put_32 (obfd, MTCTR_R11, p), p += 4;
bfd_put_32 (obfd, LD_R11_0R2 | PPC_LO (offset + 16), p), p += 4;
bfd_put_32 (obfd, LD_R2_0R2 | PPC_LO (offset + 8), p), p += 4;
Index: ld/testsuite/ld-powerpc/tlsexe.d
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-powerpc/tlsexe.d,v
retrieving revision 1.7
diff -u -p -r1.7 tlsexe.d
--- ld/testsuite/ld-powerpc/tlsexe.d 13 Aug 2007 00:20:59 -0000 1.7
+++ ld/testsuite/ld-powerpc/tlsexe.d 24 Jan 2008 01:55:03 -0000
@@ -8,9 +8,10 @@
Disassembly of section \.text:
-.* <_start-0x18>:
+.* <_start-0x1c>:
.* f8 41 00 28 std r2,40\(r1\)
.* e9 62 80 48 ld r11,-32696\(r2\)
+.* 79 62 07 ec rldimi r2,r11,0,63
.* 7d 69 03 a6 mtctr r11
.* e9 62 80 58 ld r11,-32680\(r2\)
.* e8 42 80 50 ld r2,-32688\(r2\)
@@ -21,7 +22,7 @@ Disassembly of section \.text:
.* 60 00 00 00 nop
.* 7c 63 6a 14 add r3,r3,r13
.* 38 62 80 18 addi r3,r2,-32744
-.* 4b ff ff d9 bl .*
+.* 4b ff ff d5 bl .*
.* e8 41 00 28 ld r2,40\(r1\)
.* 3c 6d 00 00 addis r3,r13,0
.* 60 00 00 00 nop
@@ -55,6 +56,7 @@ 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\)
+.* 60 00 00 00 nop
.* 00 00 00 00 .*
.* 00 01 01 f0 .*
.* 7d 88 02 a6 mflr r12
Index: ld/testsuite/ld-powerpc/tlsexe.g
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-powerpc/tlsexe.g,v
retrieving revision 1.7
diff -u -p -r1.7 tlsexe.g
--- ld/testsuite/ld-powerpc/tlsexe.g 13 Aug 2007 00:20:59 -0000 1.7
+++ ld/testsuite/ld-powerpc/tlsexe.g 24 Jan 2008 01:55:03 -0000
@@ -7,6 +7,6 @@
.*: +file format elf64-powerpc
Contents of section \.got:
-.* 00000000 100185c8 ffffffff ffff8018 .*
+.* 00000000 100185d0 ffffffff ffff8018 .*
.* 00000000 00000000 00000000 00000000 .*
.* 00000000 00000000 00000000 00000000 .*
Index: ld/testsuite/ld-powerpc/tlsexe.r
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-powerpc/tlsexe.r,v
retrieving revision 1.21
diff -u -p -r1.21 tlsexe.r
--- ld/testsuite/ld-powerpc/tlsexe.r 30 Sep 2007 01:33:15 -0000 1.21
+++ ld/testsuite/ld-powerpc/tlsexe.r 24 Jan 2008 01:55:03 -0000
@@ -16,7 +16,7 @@ Section Headers:
+\[[ 0-9]+\] \.dynstr +.*
+\[[ 0-9]+\] \.rela\.dyn +.*
+\[[ 0-9]+\] \.rela\.plt +.*
- +\[[ 0-9]+\] \.text +PROGBITS .* 0+f8 0+ +AX +0 +0 +8
+ +\[[ 0-9]+\] \.text +PROGBITS .* 0+100 0+ +AX +0 +0 +8
+\[[ 0-9]+\] \.tdata +PROGBITS .* 0+38 0+ WAT +0 +0 +8
+\[[ 0-9]+\] \.tbss +NOBITS .* 0+38 0+ WAT +0 +0 +8
+\[[ 0-9]+\] \.dynamic +DYNAMIC .* 0+150 10 +WA +4 +0 +8
Index: ld/testsuite/ld-powerpc/tlsexetoc.d
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-powerpc/tlsexetoc.d,v
retrieving revision 1.8
diff -u -p -r1.8 tlsexetoc.d
--- ld/testsuite/ld-powerpc/tlsexetoc.d 13 Aug 2007 00:20:59 -0000 1.8
+++ ld/testsuite/ld-powerpc/tlsexetoc.d 24 Jan 2008 01:55:03 -0000
@@ -8,9 +8,10 @@
Disassembly of section \.text:
-.* <_start-0x18>:
+.* <_start-0x1c>:
.* f8 41 00 28 std r2,40\(r1\)
.* e9 62 80 70 ld r11,-32656\(r2\)
+.* 79 62 07 ec rldimi r2,r11,0,63
.* 7d 69 03 a6 mtctr r11
.* e9 62 80 80 ld r11,-32640\(r2\)
.* e8 42 80 78 ld r2,-32648\(r2\)
@@ -18,10 +19,10 @@ Disassembly of section \.text:
.* <_start>:
.* 38 62 80 08 addi r3,r2,-32760
-.* 4b ff ff e5 bl .*
+.* 4b ff ff e1 bl .*
.* e8 41 00 28 ld r2,40\(r1\)
.* 38 62 80 18 addi r3,r2,-32744
-.* 4b ff ff d9 bl .*
+.* 4b ff ff d5 bl .*
.* e8 41 00 28 ld r2,40\(r1\)
.* 3c 6d 00 00 addis r3,r13,0
.* 60 00 00 00 nop
@@ -39,6 +40,7 @@ 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\)
+.* 60 00 00 00 nop
.* 00 00 00 00 .*
.* 00 01 02 18 .*
.* 7d 88 02 a6 mflr r12
Index: ld/testsuite/ld-powerpc/tlsexetoc.g
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-powerpc/tlsexetoc.g,v
retrieving revision 1.7
diff -u -p -r1.7 tlsexetoc.g
--- ld/testsuite/ld-powerpc/tlsexetoc.g 13 Aug 2007 00:20:59 -0000 1.7
+++ ld/testsuite/ld-powerpc/tlsexetoc.g 24 Jan 2008 01:55:03 -0000
@@ -7,7 +7,7 @@
.*: +file format elf64-powerpc
Contents of section \.got:
-.* 00000000 10018568 00000000 00000000 .*
+.* 00000000 10018570 00000000 00000000 .*
.* 00000000 00000000 00000000 00000000 .*
.* 00000000 00000000 00000000 00000001 .*
.* 00000000 00000000 00000000 00000001 .*
Index: ld/testsuite/ld-powerpc/tlsexetoc.r
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-powerpc/tlsexetoc.r,v
retrieving revision 1.22
diff -u -p -r1.22 tlsexetoc.r
--- ld/testsuite/ld-powerpc/tlsexetoc.r 30 Sep 2007 01:33:15 -0000 1.22
+++ ld/testsuite/ld-powerpc/tlsexetoc.r 24 Jan 2008 01:55:03 -0000
@@ -16,7 +16,7 @@ Section Headers:
+\[[ 0-9]+\] \.dynstr +.*
+\[[ 0-9]+\] \.rela\.dyn +.*
+\[[ 0-9]+\] \.rela\.plt +.*
- +\[[ 0-9]+\] \.text +PROGBITS .* 0+b8 0+ +AX +0 +0 +8
+ +\[[ 0-9]+\] \.text +PROGBITS .* 0+c0 0+ +AX +0 +0 +8
+\[[ 0-9]+\] \.tdata +PROGBITS .* 0+38 0+ WAT +0 +0 +8
+\[[ 0-9]+\] \.tbss +NOBITS .* 0+38 0+ WAT +0 +0 +8
+\[[ 0-9]+\] \.dynamic +DYNAMIC .* 0+150 10 +WA +4 +0 +8
Index: ld/testsuite/ld-powerpc/tlsso.d
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-powerpc/tlsso.d,v
retrieving revision 1.7
diff -u -p -r1.7 tlsso.d
--- ld/testsuite/ld-powerpc/tlsso.d 6 Nov 2007 13:49:19 -0000 1.7
+++ ld/testsuite/ld-powerpc/tlsso.d 24 Jan 2008 01:55:03 -0000
@@ -11,6 +11,7 @@ Disassembly of section \.text:
.* <\.__tls_get_addr>:
.* f8 41 00 28 std r2,40\(r1\)
.* e9 62 80 78 ld r11,-32648\(r2\)
+.* 79 62 07 ec rldimi r2,r11,0,63
.* 7d 69 03 a6 mtctr r11
.* e9 62 80 88 ld r11,-32632\(r2\)
.* e8 42 80 80 ld r2,-32640\(r2\)
@@ -18,16 +19,16 @@ Disassembly of section \.text:
.* <_start>:
.* 38 62 80 20 addi r3,r2,-32736
-.* 4b ff ff e5 bl .* <\.__tls_get_addr>
+.* 4b ff ff e1 bl .* <\.__tls_get_addr>
.* e8 41 00 28 ld r2,40\(r1\)
.* 38 62 80 50 addi r3,r2,-32688
-.* 4b ff ff d9 bl .* <\.__tls_get_addr>
+.* 4b ff ff d5 bl .* <\.__tls_get_addr>
.* e8 41 00 28 ld r2,40\(r1\)
.* 38 62 80 38 addi r3,r2,-32712
-.* 4b ff ff cd bl .* <\.__tls_get_addr>
+.* 4b ff ff c9 bl .* <\.__tls_get_addr>
.* e8 41 00 28 ld r2,40\(r1\)
.* 38 62 80 50 addi r3,r2,-32688
-.* 4b ff ff c1 bl .* <\.__tls_get_addr>
+.* 4b ff ff bd bl .* <\.__tls_get_addr>
.* e8 41 00 28 ld r2,40\(r1\)
.* 39 23 80 40 addi r9,r3,-32704
.* 3d 23 00 00 addis r9,r3,0
@@ -40,10 +41,10 @@ Disassembly of section \.text:
.* 3d 2d 00 00 addis r9,r13,0
.* 99 49 00 00 stb r10,0\(r9\)
.* 38 62 80 08 addi r3,r2,-32760
-.* 4b ff ff 8d bl .* <\.__tls_get_addr>
+.* 4b ff ff 89 bl .* <\.__tls_get_addr>
.* e8 41 00 28 ld r2,40\(r1\)
.* 38 62 80 50 addi r3,r2,-32688
-.* 4b ff ff 81 bl .* <\.__tls_get_addr>
+.* 4b ff ff 7d bl .* <\.__tls_get_addr>
.* e8 41 00 28 ld r2,40\(r1\)
.* f9 43 80 08 std r10,-32760\(r3\)
.* 3d 23 00 00 addis r9,r3,0
@@ -55,6 +56,7 @@ 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\)
+.* 60 00 00 00 nop
.* 00 00 00 00 .*
.* 00 01 02 20 .*
.* 7d 88 02 a6 mflr r12
Index: ld/testsuite/ld-powerpc/tlsso.g
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-powerpc/tlsso.g,v
retrieving revision 1.8
diff -u -p -r1.8 tlsso.g
--- ld/testsuite/ld-powerpc/tlsso.g 13 Aug 2007 00:20:59 -0000 1.8
+++ ld/testsuite/ld-powerpc/tlsso.g 24 Jan 2008 01:55:03 -0000
@@ -7,7 +7,7 @@
.*: +file format elf64-powerpc
Contents of section \.got:
-.* 00000000 00018778 00000000 00000000 .*
+.* 00000000 00018780 00000000 00000000 .*
.* 00000000 00000000 00000000 00000000 .*
.* 00000000 00000000 00000000 00000000 .*
.* 00000000 00000000 00000000 00000000 .*
Index: ld/testsuite/ld-powerpc/tlsso.r
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-powerpc/tlsso.r,v
retrieving revision 1.22
diff -u -p -r1.22 tlsso.r
--- ld/testsuite/ld-powerpc/tlsso.r 6 Nov 2007 13:49:19 -0000 1.22
+++ ld/testsuite/ld-powerpc/tlsso.r 24 Jan 2008 01:55:03 -0000
@@ -49,9 +49,9 @@ Relocation section '\.rela\.dyn' at offs
[0-9a-f ]+R_PPC64_TPREL16 +0+60 le0 \+ 0
[0-9a-f ]+R_PPC64_TPREL16_HA +0+68 le1 \+ 0
[0-9a-f ]+R_PPC64_TPREL16_LO +0+68 le1 \+ 0
-[0-9a-f ]+R_PPC64_TPREL16_DS +0+105f0 \.tdata \+ 28
-[0-9a-f ]+R_PPC64_TPREL16_HA +0+105f0 \.tdata \+ 30
-[0-9a-f ]+R_PPC64_TPREL16_LO +0+105f0 \.tdata \+ 30
+[0-9a-f ]+R_PPC64_TPREL16_DS +0+105f8 \.tdata \+ 28
+[0-9a-f ]+R_PPC64_TPREL16_HA +0+105f8 \.tdata \+ 30
+[0-9a-f ]+R_PPC64_TPREL16_LO +0+105f8 \.tdata \+ 30
[0-9a-f ]+R_PPC64_DTPMOD64 +0+
[0-9a-f ]+R_PPC64_DTPREL64 +0+
[0-9a-f ]+R_PPC64_DTPREL64 +0+18
Index: ld/testsuite/ld-powerpc/tlstocso.d
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-powerpc/tlstocso.d,v
retrieving revision 1.6
diff -u -p -r1.6 tlstocso.d
--- ld/testsuite/ld-powerpc/tlstocso.d 13 Aug 2007 00:20:59 -0000 1.6
+++ ld/testsuite/ld-powerpc/tlstocso.d 24 Jan 2008 01:55:03 -0000
@@ -11,6 +11,7 @@ Disassembly of section \.text:
.* <\.__tls_get_addr>:
.* f8 41 00 28 std r2,40\(r1\)
.* e9 62 80 70 ld r11,-32656\(r2\)
+.* 79 62 07 ec rldimi r2,r11,0,63
.* 7d 69 03 a6 mtctr r11
.* e9 62 80 80 ld r11,-32640\(r2\)
.* e8 42 80 78 ld r2,-32648\(r2\)
@@ -18,16 +19,16 @@ Disassembly of section \.text:
.* <_start>:
.* 38 62 80 08 addi r3,r2,-32760
-.* 4b ff ff e5 bl .* <\.__tls_get_addr>
+.* 4b ff ff e1 bl .* <\.__tls_get_addr>
.* e8 41 00 28 ld r2,40\(r1\)
.* 38 62 80 18 addi r3,r2,-32744
-.* 4b ff ff d9 bl .* <\.__tls_get_addr>
+.* 4b ff ff d5 bl .* <\.__tls_get_addr>
.* e8 41 00 28 ld r2,40\(r1\)
.* 38 62 80 28 addi r3,r2,-32728
-.* 4b ff ff cd bl .* <\.__tls_get_addr>
+.* 4b ff ff c9 bl .* <\.__tls_get_addr>
.* e8 41 00 28 ld r2,40\(r1\)
.* 38 62 80 38 addi r3,r2,-32712
-.* 4b ff ff c1 bl .* <\.__tls_get_addr>
+.* 4b ff ff bd bl .* <\.__tls_get_addr>
.* e8 41 00 28 ld r2,40\(r1\)
.* 39 23 80 40 addi r9,r3,-32704
.* 3d 23 00 00 addis r9,r3,0
@@ -39,6 +40,7 @@ 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\)
+.* 60 00 00 00 nop
.* 00 00 00 00 .*
.* 00 01 02 18 .*
.* 7d 88 02 a6 mflr r12
Index: ld/testsuite/ld-powerpc/tlstocso.g
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-powerpc/tlstocso.g,v
retrieving revision 1.9
diff -u -p -r1.9 tlstocso.g
--- ld/testsuite/ld-powerpc/tlstocso.g 13 Aug 2007 00:20:59 -0000 1.9
+++ ld/testsuite/ld-powerpc/tlstocso.g 24 Jan 2008 01:55:03 -0000
@@ -7,7 +7,7 @@
.*: +file format elf64-powerpc
Contents of section \.got:
-.* 00000000 000186c0 00000000 00000000 .*
+.* 00000000 000186c8 00000000 00000000 .*
.* 00000000 00000000 00000000 00000000 .*
.* 00000000 00000000 00000000 00000000 .*
.* 00000000 00000000 00000000 00000000 .*
--
Alan Modra
Australia Development Lab, IBM