about summary refs log tree commit diff
path: root/sysdeps/powerpc/powerpc64
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2010-08-12 09:19:19 -0700
committerUlrich Drepper <drepper@redhat.com>2010-08-12 09:19:19 -0700
commitbebff237c522e4e8e23204ca1e5104896389158e (patch)
treea4edee831e0476277cc372a46fa8281ab0bc229a /sysdeps/powerpc/powerpc64
parent026373745eab50a683536d950cb7e17dc98c4259 (diff)
downloadglibc-bebff237c522e4e8e23204ca1e5104896389158e.tar.gz
glibc-bebff237c522e4e8e23204ca1e5104896389158e.tar.xz
glibc-bebff237c522e4e8e23204ca1e5104896389158e.zip
PowerPC64 ABI fixes
Diffstat (limited to 'sysdeps/powerpc/powerpc64')
-rw-r--r--sysdeps/powerpc/powerpc64/bsd-_setjmp.S67
-rw-r--r--sysdeps/powerpc/powerpc64/bsd-setjmp.S46
-rw-r--r--sysdeps/powerpc/powerpc64/dl-trampoline.S76
-rw-r--r--sysdeps/powerpc/powerpc64/fpu/s_copysign.S7
-rw-r--r--sysdeps/powerpc/powerpc64/setjmp-common.S41
-rw-r--r--sysdeps/powerpc/powerpc64/setjmp.S13
-rw-r--r--sysdeps/powerpc/powerpc64/sysdep.h59
7 files changed, 155 insertions, 154 deletions
diff --git a/sysdeps/powerpc/powerpc64/bsd-_setjmp.S b/sysdeps/powerpc/powerpc64/bsd-_setjmp.S
index 82b79a8098..86d49b1c6e 100644
--- a/sysdeps/powerpc/powerpc64/bsd-_setjmp.S
+++ b/sysdeps/powerpc/powerpc64/bsd-_setjmp.S
@@ -1,66 +1 @@
-/* BSD `_setjmp' entry point to `sigsetjmp (..., 0)'.  PowerPC32/64 version.
-   Copyright (C) 1994, 1997, 1999, 2000, 2002, 2003, 2004
-   Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-   02111-1307 USA.  */
-#include <shlib-compat.h>
-#include <libc-symbols.h>
-#include <sysdep.h>
-#include <bp-sym.h>
-
-#if defined NOT_IN_libc
-/* Build a non-versioned object for rtld-*.  */
-ENTRY (BP_SYM (_setjmp))
-	CALL_MCOUNT 1
-	li r4,0			/* Set second argument to 0.  */
-	b JUMPTARGET (__sigsetjmp_ent)
-END (BP_SYM (_setjmp))
-libc_hidden_def (_setjmp)
-
-#else
-/* Build a versioned object for libc.  */
-# if defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_3, GLIBC_2_3_4)
-symbol_version (__novmx_setjmp,_setjmp,GLIBC_2.3);
-
-ENTRY (BP_SYM (__novmx_setjmp))
-	CALL_MCOUNT 1
-	li r4,0			/* Set second argument to 0.  */
-	b JUMPTARGET (__novmx__sigsetjmp_ent)
-END (BP_SYM (__novmx_setjmp))
-libc_hidden_def (__novmx_setjmp)
-# endif /* defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_3, GLIBC_2_3_4) */
-
-default_symbol_version (__vmx_setjmp,_setjmp,GLIBC_2.3.4)
-/* __GI__setjmp prototype is needed for ntpl i.e. _setjmp is defined
-   as a libc_hidden_proto & is used in sysdeps/generic/libc-start.c
-   if HAVE_CLEANUP_JMP_BUF is defined */
-ENTRY (BP_SYM (__GI__setjmp))
-#if defined SHARED && !defined IS_IN_rtld
-	std r2,40(r1)	/* Save the callers TOC in the save area.  */
-#endif
-	CALL_MCOUNT 1
-	li r4,0			/* Set second argument to 0.  */
-	b JUMPTARGET (__vmx__sigsetjmp_ent)
-END (BP_SYM (__GI__setjmp))
-
-ENTRY (BP_SYM (__vmx_setjmp))
-	CALL_MCOUNT 1
-	li r4,0			/* Set second argument to 0.  */
-	b JUMPTARGET (__vmx__sigsetjmp_ent)
-END (BP_SYM (__vmx_setjmp))
-libc_hidden_def (__vmx_setjmp)
-#endif /* !NOT_IN_libc */
+/* _setjmp moved to setjmp-common.S */
diff --git a/sysdeps/powerpc/powerpc64/bsd-setjmp.S b/sysdeps/powerpc/powerpc64/bsd-setjmp.S
index 543e83faa3..38b734fcb4 100644
--- a/sysdeps/powerpc/powerpc64/bsd-setjmp.S
+++ b/sysdeps/powerpc/powerpc64/bsd-setjmp.S
@@ -1,45 +1 @@
-/* BSD `setjmp' entry point to `sigsetjmp (..., 1)'.  PowerPC32/64 version.
-   Copyright (C) 1994,1997,1999,2000,2003,2004 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-   02111-1307 USA.  */
-#include <shlib-compat.h>
-#include <libc-symbols.h>
-#include <sysdep.h>
-#include <bp-sym.h>
-
-#if defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_3, GLIBC_2_3_4)
-
-
-ENTRY (__novmxsetjmp)
-	CALL_MCOUNT 1
-	li r4,1			/* Set second argument to 1.  */
-	b JUMPTARGET (__novmx__sigsetjmp_ent)
-END (__novmxsetjmp)
-strong_alias (__novmxsetjmp, __novmx__setjmp)
-symbol_version (__novmxsetjmp, setjmp, GLIBC_2.3)
-
-#endif  /*  defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_3, GLIBC_2_3_4) */
-
-
-ENTRY (__vmxsetjmp)
-	CALL_MCOUNT 1
-	li r4,1			/* Set second argument to 1.  */
-	b JUMPTARGET (__vmx__sigsetjmp_ent)
-END (__vmxsetjmp)
-strong_alias (__vmxsetjmp, __vmx__setjmp)
-strong_alias (__vmx__sigsetjmp, __setjmp)
-default_symbol_version (__vmxsetjmp, setjmp, GLIBC_2.3.4)
+/* setjmp moved to setjmp-common.S */
diff --git a/sysdeps/powerpc/powerpc64/dl-trampoline.S b/sysdeps/powerpc/powerpc64/dl-trampoline.S
index 9ca394dda2..abe746b6ad 100644
--- a/sysdeps/powerpc/powerpc64/dl-trampoline.S
+++ b/sysdeps/powerpc/powerpc64/dl-trampoline.S
@@ -27,42 +27,50 @@
    parm1 (r3) and the index (r0) need to be converted to an offset
    (index * 24) in parm2 (r4).  */
 
-EALIGN(_dl_runtime_resolve, 4, 0)
+#define FRAME_SIZE 176
 /* We need to save the registers used to pass parameters, ie. r3 thru
-   r10; the registers are saved in a stack frame.  */
-	stdu	r1,-128(r1)
-	cfi_adjust_cfa_offset (128)
-	std	r3,48(r1)
+   r10;  Use local var space rather than the parameter save area,
+   because gcc as of 2010/05 doesn't allocate a proper stack frame for
+   a function that makes no calls except for __tls_get_addr and we
+   might be here resolving the __tls_get_addr call.  */
+#define INT_PARMS 112
+EALIGN(_dl_runtime_resolve, 4, 0)
+	stdu	r1,-FRAME_SIZE(r1)
+	cfi_adjust_cfa_offset (FRAME_SIZE)
+	std	r3,INT_PARMS+0(r1)
 	mr	r3,r11
-	std	r4,56(r1)
+	std	r4,INT_PARMS+8(r1)
 	sldi	r4,r0,1
-	std	r5,64(r1)
+	std	r5,INT_PARMS+16(r1)
 	add	r4,r4,r0
-	std	r6,72(r1)
+	std	r6,INT_PARMS+24(r1)
 	sldi	r4,r4,3
-	std	r7,80(r1)
+	std	r7,INT_PARMS+32(r1)
 	mflr	r0
-	std	r8,88(r1)
-/* Store the LR in the LR Save area of the previous frame.  */
-	std	r0,128+16(r1)
+	std	r8,INT_PARMS+40(r1)
+/* Store the LR in the LR Save area.  */
+	std	r0,FRAME_SIZE+16(r1)
 	cfi_offset (lr, 16)
 	mfcr	r0
-	std	r9,96(r1)
-	std	r10,104(r1)
+	std	r9,INT_PARMS+48(r1)
+	std	r10,INT_PARMS+56(r1)
 /* I'm almost certain we don't have to save cr...  be safe.  */
-	std	r0,8(r1)
+	std	r0,FRAME_SIZE+8(r1)
 	bl	JUMPTARGET(_dl_fixup)
+#ifndef SHARED
+	nop
+#endif
 /* Put the registers back.  */
-	ld	r0,128+16(r1)
-	ld	r10,104(r1)
-	ld	r9,96(r1)
-	ld	r8,88(r1)
-	ld	r7,80(r1)
+	ld	r0,FRAME_SIZE+16(r1)
+	ld	r10,INT_PARMS+56(r1)
+	ld	r9,INT_PARMS+48(r1)
+	ld	r8,INT_PARMS+40(r1)
+	ld	r7,INT_PARMS+32(r1)
 	mtlr	r0
-	ld	r0,8(r1)
-	ld	r6,72(r1)
-	ld	r5,64(r1)
-	ld	r4,56(r1)
+	ld	r0,FRAME_SIZE+8(r1)
+	ld	r6,INT_PARMS+24(r1)
+	ld	r5,INT_PARMS+16(r1)
+	ld	r4,INT_PARMS+8(r1)
 	mtcrf	0xFF,r0
 /* Load the target address, toc and static chain reg from the function
    descriptor returned by fixup.  */
@@ -70,11 +78,13 @@ EALIGN(_dl_runtime_resolve, 4, 0)
 	ld	r2,8(r3)
 	mtctr	r0
 	ld	r11,16(r3)
-	ld	r3,48(r1)
+	ld	r3,INT_PARMS+0(r1)
 /* Unwind the stack frame, and jump.  */
-	addi	r1,r1,128
+	addi	r1,r1,FRAME_SIZE
 	bctr
 END(_dl_runtime_resolve)
+#undef FRAME_SIZE
+#undef INT_PARMS
 
 	/* Stack layout:
 	  +592   previous backchain
@@ -176,13 +186,13 @@ EALIGN(_dl_profile_resolve, 4, 0)
 /* Spill r30, r31 to preserve the link_map* and reloc_addr, in case we
    need to call _dl_call_pltexit.  */
 	std	r31,-8(r1)
-	cfi_offset(r31,-8)
 	std	r30,-16(r1)
-	cfi_offset(r30,-16)
 /* We need to save the registers used to pass parameters, ie. r3 thru
    r10; the registers are saved in a stack frame.  */
 	stdu	r1,-FRAME_SIZE(r1)
 	cfi_adjust_cfa_offset (FRAME_SIZE)
+	cfi_offset(r31,-8)
+	cfi_offset(r30,-16)
 	std	r3,INT_PARMS+0(r1)
 	mr	r3,r11
 	std	r4,INT_PARMS+8(r1)
@@ -205,7 +215,7 @@ EALIGN(_dl_profile_resolve, 4, 0)
 	std	r10,INT_PARMS+56(r1)
 	std	r8,CALLING_SP(r1)
 /* I'm almost certain we don't have to save cr...  be safe.  */
-	std	r0,8(r1)
+	std	r0,FRAME_SIZE+8(r1)
 	ld	r12,.LC__dl_hwcap@toc(r2)
 #ifdef SHARED
 	/* Load _rtld-global._dl_hwcap.  */
@@ -265,7 +275,9 @@ L(saveFP):
 	mr	r30,r4
 	std	r0,0(r7)
 	bl	JUMPTARGET(_dl_profile_fixup)
+#ifndef SHARED
 	nop
+#endif
 /* Test *framesizep > 0 to see if need to do pltexit processing.  */
 	ld	r0,STACK_FRAME(r1)
 /* Put the registers back.  */
@@ -306,7 +318,7 @@ L(restoreFXR):
 	ld	r8,INT_PARMS+40(r1)
 	ld	r7,INT_PARMS+32(r1)
 	mtlr	r0
-	ld	r0,8(r1)
+	ld	r0,FRAME_SIZE+8(r1)
 	ld	r6,INT_PARMS+24(r1)
 	ld	r5,INT_PARMS+16(r1)
 	ld	r4,INT_PARMS+8(r1)
@@ -370,7 +382,7 @@ L(restoreFXR2):
 	ld	r8,INT_PARMS+40(r1)
 	ld	r7,INT_PARMS+32(r1)
 	mtlr	r0
-	ld	r0,8(r1)
+	ld	r0,FRAME_SIZE+8(r1)
 	ld	r6,INT_PARMS+24(r1)
 	ld	r5,INT_PARMS+16(r1)
 	ld	r4,INT_PARMS+8(r1)
@@ -418,7 +430,9 @@ L(callpltexit):
 	addi	r5,r1,INT_PARMS
 	addi	r6,r1,INT_RTN
 	bl	JUMPTARGET(_dl_call_pltexit)
+#ifndef SHARED
 	nop
+#endif
 /* Restore the return values from target function.  */
 	lwz	r12,VR_VRSAVE(r1)
 	ld	r3,INT_RTN(r1)
diff --git a/sysdeps/powerpc/powerpc64/fpu/s_copysign.S b/sysdeps/powerpc/powerpc64/fpu/s_copysign.S
index 38171e31d7..ff7490629e 100644
--- a/sysdeps/powerpc/powerpc64/fpu/s_copysign.S
+++ b/sysdeps/powerpc/powerpc64/fpu/s_copysign.S
@@ -28,15 +28,12 @@ ENTRY(__copysign)
 /* double [f1] copysign (double [f1] x, double [f2] y);
    copysign(x,y) returns a value with the magnitude of x and
    with the sign bit of y.  */
-	stdu	r1,-48(r1)
-	cfi_adjust_cfa_offset (48)
-	stfd	fp2,24(r1)
+	stfd	fp2,56(r1)
 	nop
 	nop
 	nop
-	ld	r3,24(r1)
+	ld	r3,56(r1)
 	cmpdi   r3,0
-	addi    r1,r1,48
 	blt     L(0)
 	fabs    fp1,fp1
 	blr
diff --git a/sysdeps/powerpc/powerpc64/setjmp-common.S b/sysdeps/powerpc/powerpc64/setjmp-common.S
index 606eef5935..a059a91f8b 100644
--- a/sysdeps/powerpc/powerpc64/setjmp-common.S
+++ b/sysdeps/powerpc/powerpc64/setjmp-common.S
@@ -39,10 +39,33 @@
 #endif
 
 	.machine	"altivec"
+ENTRY (setjmp)
+	CALL_MCOUNT 1
+	li r4,1			/* Set second argument to 1.  */
+	b JUMPTARGET (GLUE(__sigsetjmp,_ent))
+END (setjmp)
+
+#if defined SHARED && !defined IS_IN_rtld && !defined __NO_VMX__
+/* When called from within libc we need a special version of _setjmp
+   that saves r2 since the call won't go via a plt call stub.  See
+   bugz #269.  __GI__setjmp is used in csu/libc-start.c when
+   HAVE_CLEANUP_JMP_BUF is defined.  */
+ENTRY (BP_SYM (__GI__setjmp))
+	std r2,40(r1)		/* Save the callers TOC in the save area.  */
+	cfi_endproc
+END_2 (BP_SYM (__GI__setjmp))
+/* Fall thru. */
+#endif
+
+ENTRY (BP_SYM (_setjmp))
+	CALL_MCOUNT 1
+	li r4,0			/* Set second argument to 0.  */
+	b JUMPTARGET (GLUE(__sigsetjmp,_ent))
+END (BP_SYM (_setjmp))
+libc_hidden_def (_setjmp)
+
 ENTRY (BP_SYM (__sigsetjmp))
 	CALL_MCOUNT 2
-	.globl JUMPTARGET(GLUE(__sigsetjmp,_ent))
-	.hidden JUMPTARGET(GLUE(__sigsetjmp,_ent))
 JUMPTARGET(GLUE(__sigsetjmp,_ent)):
 	CHECK_BOUNDS_BOTH_WIDE_LIT (r3, r8, r9, JB_SIZE)
 #ifdef PTR_MANGLE
@@ -190,7 +213,19 @@ L(no_vmx):
 #if defined NOT_IN_libc && defined IS_IN_rtld
 	li	r3,0
 	blr
+#elif defined SHARED
+	b	JUMPTARGET (BP_SYM (__sigjmp_save))
 #else
-	b JUMPTARGET (BP_SYM (__sigjmp_save))
+	mflr	r0
+	std	r0,16(r1)
+	stdu	r1,-112(r1)
+	cfi_adjust_cfa_offset(112)
+	cfi_offset(lr,16)
+	bl	JUMPTARGET (BP_SYM (__sigjmp_save))
+	nop
+	ld	r0,112+16(r1)
+	addi	r1,r1,112
+	mtlr	r0
+	blr
 #endif
 END (BP_SYM (__sigsetjmp))
diff --git a/sysdeps/powerpc/powerpc64/setjmp.S b/sysdeps/powerpc/powerpc64/setjmp.S
index acbf3728e5..83b237ba2a 100644
--- a/sysdeps/powerpc/powerpc64/setjmp.S
+++ b/sysdeps/powerpc/powerpc64/setjmp.S
@@ -27,19 +27,32 @@
 
 #else /* !NOT_IN_libc */
 /* Build a versioned object for libc.  */
+default_symbol_version (__vmxsetjmp, setjmp, GLIBC_2.3.4)
+default_symbol_version (__vmx_setjmp,_setjmp,GLIBC_2.3.4)
 default_symbol_version (__vmx__sigsetjmp,__sigsetjmp,GLIBC_2.3.4)
+# define setjmp __vmxsetjmp
+# define _setjmp __vmx_setjmp
 # define __sigsetjmp __vmx__sigsetjmp
 # define __sigjmp_save __vmx__sigjmp_save
 # include "setjmp-common.S"
+strong_alias (__vmxsetjmp, __vmx__setjmp)
+strong_alias (__vmx__sigsetjmp, __setjmp)
 
 # if defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_3, GLIBC_2_3_4)
+#  undef setjmp
+#  undef _setjmp
 #  undef __sigsetjmp
 #  undef __sigjmp_save
 #  undef JB_SIZE
 #  define __NO_VMX__
+symbol_version (__novmxsetjmp, setjmp, GLIBC_2.3)
+symbol_version (__novmx_setjmp,_setjmp,GLIBC_2.3);
 symbol_version (__novmx__sigsetjmp,__sigsetjmp,GLIBC_2.3)
+#  define setjmp __novmxsetjmp
+#  define _setjmp __novmx_setjmp
 #  define __sigsetjmp __novmx__sigsetjmp
 #  define __sigjmp_save __novmx__sigjmp_save
 #  include "setjmp-common.S"
+strong_alias (__novmxsetjmp, __novmx__setjmp)
 # endif
 #endif /* !NOT_IN_libc */
diff --git a/sysdeps/powerpc/powerpc64/sysdep.h b/sysdeps/powerpc/powerpc64/sysdep.h
index 2745d7eb71..5fc6e4f2f3 100644
--- a/sysdeps/powerpc/powerpc64/sysdep.h
+++ b/sysdeps/powerpc/powerpc64/sysdep.h
@@ -27,14 +27,28 @@
 	.macro SAVE_ARG NARG
 	.if \NARG
 	SAVE_ARG \NARG-1
-	std	2+\NARG,-72+8*(\NARG)(1)
+	std	2+\NARG,40+8*(\NARG)(1)
 	.endif
 	.endm
 
 	.macro REST_ARG NARG
 	.if \NARG
 	REST_ARG \NARG-1
-	ld	2+\NARG,40+8*(\NARG)(1)
+	ld	2+\NARG,112+40+8*(\NARG)(1)
+	.endif
+	.endm
+
+	.macro CFI_SAVE_ARG NARG
+	.if \NARG
+	CFI_SAVE_ARG \NARG-1
+	cfi_offset(2+\NARG,40+8*(\NARG))
+	.endif
+	.endm
+
+	.macro CFI_REST_ARG NARG
+	.if \NARG
+	CFI_REST_ARG \NARG-1
+	cfi_restore(2+\NARG)
 	.endif
 	.endm
 
@@ -46,11 +60,20 @@
 	SAVE_ARG \NARG
 	std	r0,16(r1)
 	stdu	r1,-112(r1)
+	cfi_adjust_cfa_offset(112)
+	cfi_offset(lr,16)
+	CFI_SAVE_ARG \NARG
 	bl	JUMPTARGET (_mcount)
+#ifndef SHARED
+	nop
+#endif
 	ld	r0,128(r1)
 	REST_ARG \NARG
-	addi	r1,r1,112
 	mtlr	r0
+	addi	r1,r1,112
+	cfi_adjust_cfa_offset(-112)
+	cfi_restore(lr)
+	CFI_REST_ARG \NARG
 #endif
 	.endm
 
@@ -198,9 +221,37 @@ LT_LABELSUFFIX(name,_name_end): ; \
   ENTRY (name) \
   DO_CALL (SYS_ify (syscall_name));
 
+#ifdef SHARED
+#define TAIL_CALL_SYSCALL_ERROR \
+    b JUMPTARGET(__syscall_error)
+#else
+/* Static version might be linked into a large app with a toc exceeding
+   64k.  We can't put a toc adjusting stub on a plain branch, so can't
+   tail call __syscall_error.  */
+#define TAIL_CALL_SYSCALL_ERROR \
+    .ifdef .Local_syscall_error; \
+    b .Local_syscall_error; \
+    .else; \
+.Local_syscall_error: \
+    mflr 0; \
+    std 0,16(1); \
+    stdu 1,-112(1); \
+    cfi_adjust_cfa_offset(112); \
+    cfi_offset(lr,16); \
+    bl JUMPTARGET(__syscall_error); \
+    nop; \
+    ld 0,112+16(1); \
+    addi 1,1,112; \
+    cfi_adjust_cfa_offset(-112); \
+    mtlr 0; \
+    cfi_restore(lr); \
+    blr; \
+    .endif
+#endif
+
 #define PSEUDO_RET \
     bnslr+; \
-    b JUMPTARGET(__syscall_error)
+    TAIL_CALL_SYSCALL_ERROR
 
 #define ret PSEUDO_RET