svn commit: r203332 - in projects/ppc64/lib/libc/powerpc64: . sys

Nathan Whitehorn nwhitehorn at FreeBSD.org
Mon Feb 1 01:06:37 UTC 2010


Author: nwhitehorn
Date: Mon Feb  1 01:06:36 2010
New Revision: 203332
URL: http://svn.freebsd.org/changeset/base/203332

Log:
  Restoration of the TOC value is done by a linker-rewritten nop after
  branch instructions. Setting of the TOC is done by a linker-written
  trampoline, and the old value stored in the stack. If two TOC-based
  function calls were made back-to-back with the same stack frame, this
  resulted in corruption of the TOC pointer.
  
  This happened predominently with cerror, so fix some additional bugs here.
  With these changes, all dynamically linked executables seem to work, given
  LD_BIND_NOW. Next up: fix lazy PLT loading.

Modified:
  projects/ppc64/lib/libc/powerpc64/SYS.h
  projects/ppc64/lib/libc/powerpc64/sys/cerror.S

Modified: projects/ppc64/lib/libc/powerpc64/SYS.h
==============================================================================
--- projects/ppc64/lib/libc/powerpc64/SYS.h	Mon Feb  1 00:13:30 2010	(r203331)
+++ projects/ppc64/lib/libc/powerpc64/SYS.h	Mon Feb  1 01:06:36 2010	(r203332)
@@ -42,8 +42,15 @@
 #define	SYSCALL(x)						\
 	.text;							\
 	.align 2;						\
-2:	b	PIC_PLT(CNAME(HIDENAME(cerror)));		\
+2:	mflr	%r0;						\
+	std	%r0,16(%r1);					\
+	stdu	%r1,-48(%r1);					\
+	bl	PIC_PLT(CNAME(HIDENAME(cerror)));		\
 	nop;							\
+	addi	%r1,%r1,48;					\
+	ld	%r0,16(%r1);					\
+	mtlr	%r0;						\
+	blr;							\
 ENTRY(__CONCAT(__sys_,x));					\
 	.weak	CNAME(x);					\
 	.set	CNAME(x),CNAME(__CONCAT(__sys_,x));		\
@@ -66,14 +73,19 @@ ENTRY(__CONCAT(__sys_,x));					\
 	.set	CNAME(__CONCAT(._,x)),CNAME(__CONCAT(.__sys_,x));\
 	_SYSCALL(x);						\
 	bnslr;							\
-	b	PIC_PLT(CNAME(HIDENAME(cerror)));		\
-	nop
+	mflr	%r0;						\
+	std	%r0,16(%r1);					\
+	stdu	%r1,-48(%r1);					\
+	bl	PIC_PLT(CNAME(HIDENAME(cerror)));		\
+	nop;							\
+	addi	%r1,%r1,48;					\
+	ld	%r0,16(%r1);					\
+	mtlr	%r0;						\
+	blr;
 
 #define	RSYSCALL(x)						\
 	.text;							\
 	.align 2;						\
-2:	b	PIC_PLT(CNAME(HIDENAME(cerror)));		\
-	nop;							\
 ENTRY(__CONCAT(__sys_,x));					\
 	.weak	CNAME(x);					\
 	.set	CNAME(x),CNAME(__CONCAT(__sys_,x));		\
@@ -85,5 +97,13 @@ ENTRY(__CONCAT(__sys_,x));					\
 	.set	CNAME(__CONCAT(._,x)),CNAME(__CONCAT(.__sys_,x));\
 	_SYSCALL(x);						\
 	bnslr;							\
-	b	PIC_PLT(CNAME(HIDENAME(cerror)));		\
-	nop
+								\
+	mflr	%r0;						\
+	std	%r0,16(%r1);					\
+	stdu	%r1,-48(%r1);					\
+	bl	PIC_PLT(CNAME(HIDENAME(cerror)));		\
+	nop;							\
+	addi	%r1,%r1,48;					\
+	ld	%r0,16(%r1);					\
+	mtlr	%r0;						\
+	blr;

Modified: projects/ppc64/lib/libc/powerpc64/sys/cerror.S
==============================================================================
--- projects/ppc64/lib/libc/powerpc64/sys/cerror.S	Mon Feb  1 00:13:30 2010	(r203331)
+++ projects/ppc64/lib/libc/powerpc64/sys/cerror.S	Mon Feb  1 01:06:36 2010	(r203332)
@@ -40,19 +40,21 @@ __FBSDID("$FreeBSD$");
 	 */
 ENTRY(HIDENAME(cerror))
 	mflr	%r0
+	std	%r0,16(%r1)		/* save lr */
 	stdu	%r1,-56(%r1)		/* allocate new stack frame */
-	std	%r0,16(%r1)		/* and save lr, r31 */
 	std	%r31,48(%r1)
+
 	mr	%r31,%r3          /* stash errval in callee-saved register */
 	bl	PIC_PLT(CNAME(__error))
 	nop
-	std	%r31,0(%r3)		/* store errval into &errno */
-	ld	%r0,16(%r1)
+	stw	%r31,0(%r3)		/* store errval into &errno */
+
 	ld	%r31,48(%r1)
-	mtlr	%r0
 	ld	%r1,0(%r1)
+	ld	%r0,16(%r1)
+	mtlr	%r0
 	li	%r3,-1
 	li	%r4,-1
-	blr				/* return to callers caller */
+	blr
 
 


More information about the svn-src-projects mailing list