summaryrefslogtreecommitdiff
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
parent026373745eab50a683536d950cb7e17dc98c4259 (diff)
downloadglibc-bebff237c522e4e8e23204ca1e5104896389158e.tar.gz
PowerPC64 ABI fixes
-rw-r--r--ChangeLog37
-rw-r--r--nptl/ChangeLog11
-rw-r--r--nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h69
-rw-r--r--sysdeps/powerpc/powerpc32/power4/memcmp.S2
-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
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc64/brk.S7
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S73
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc64/makecontext.S1
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc64/socket.S39
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc64/vfork.S2
16 files changed, 315 insertions, 235 deletions
diff --git a/ChangeLog b/ChangeLog
index 85bda58b6d..712657959f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,40 @@
+2010-05-01 Alan Modra <amodra@gmail.com>
+
+ * sysdeps/powerpc/powerpc32/power4/memcmp.S: Correct cfi for r24.
+ * sysdeps/powerpc/powerpc64/bsd-_setjmp.S: Move contents..
+ * sysdeps/powerpc/powerpc64/bsd-setjmp.S: ..and these too..
+ * sysdeps/powerpc/powerpc64/setjmp.S: ..to here..
+ * sysdeps/powerpc/powerpc64/setjmp-common.S: ..and here, with some
+ tidying. Don't tail-call __sigjmp_save for static lib.
+ * sysdeps/powerpc/powerpc64/sysdep.h (SAVE_ARG, REST_ARG): Correct
+ save location.
+ (CFI_SAVE_ARG, CFI_REST_ARG): New macros.
+ (CALL_MCOUNT): Add eh info, and nop after bl.
+ (TAIL_CALL_SYSCALL_ERROR): New macro.
+ (PSEUDO_RET): Use it.
+ * sysdeps/powerpc/powerpc64/dl-trampoline.S (_dl_runtime_resolve):
+ Correct save location of integer regs and cr.
+ (_dl_profile_resolve): Correct cr save location. Delete nops
+ after bl when SHARED. Reduce cfi size a little by better
+ placement of cfi directives.
+ * sysdeps/powerpc/powerpc64/fpu/s_copysign.S (__copysign): Don't
+ make a stack frame. Instead use parm save area as a temp.
+ * sysdeps/unix/sysv/linux/powerpc/powerpc64/brk.S (__brk): Don't
+ make a stack frame. Use TAIL_CALL_SYSCALL_ERROR.
+ * sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S (__clone):
+ Don't make a stack frame for parent, use parm save area.
+ Increase child stack frame to 112 bytes. Don't save unused reg,
+ and adjust reg usage. Set up cfi on error recovery and
+ epilogue of parent, and use TAIL_CALL_SYSCALL_ERROR, PSEUDO_RET.
+ * sysdeps/unix/sysv/linux/powerpc/powerpc64/makecontext.S
+ (__makecontext): Add dummy nop after jump to exit.
+ * sysdeps/unix/sysv/linux/powerpc/powerpc64/socket.S (__socket):
+ Use correct parm save area and cr save, reduce stack frame.
+ Correct cfi for possible PSEUDO_RET frame setup.
+ * sysdeps/unix/sysv/linux/powerpc/powerpc64/vfork.S (__vfork):
+ Branch to local label emitted by PSEUDO_RET rather than
+ __syscall_error.
+
2010-08-12 Andreas Schwab <schwab@redhat.com>
[BZ #11904]
diff --git a/nptl/ChangeLog b/nptl/ChangeLog
index c1f8620eb4..848084e977 100644
--- a/nptl/ChangeLog
+++ b/nptl/ChangeLog
@@ -1,3 +1,14 @@
+2010-05-01 Alan Modra <amodra@gmail.com>
+
+ * sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h
+ (PSEUDO): Use correct cr save. Don't use wrong parm save area
+ to save temps. Correct cfi for possible later frame manipulation.
+ (DOCARGS_1, UNDOCARGS_1): Use the correct parm save area.
+ (DOCARGS_2, UNDOCARGS_2, DOCARGS_3, UNDOCARGS_3): Likewise.
+ (DOCARGS_4, UNDOCARGS_4, DOCARGS_5, UNDOCARGS_5): Likewise.
+ (DOCARGS_6, UNDOCARGS_6): Likewise.
+ (CENABLE, CDISABLE): Add nops for non-shared calls.
+
2010-07-06 Andreas Schwab <schwab@redhat.com>
* sysdeps/unix/sysv/linux/pthread_getname.c (pthread_getname_np):
diff --git a/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h b/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h
index 707765ab58..597630cea4 100644
--- a/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h
+++ b/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h
@@ -52,51 +52,70 @@
cfi_offset (lr, 16); \
DOCARGS_##args; /* save syscall args around CENABLE. */ \
CENABLE; \
- std 3,72(1); /* store CENABLE return value (MASK). */ \
+ std 3,112(1); /* store CENABLE return value (MASK). */ \
UNDOCARGS_##args; /* restore syscall args. */ \
DO_CALL (SYS_ify (syscall_name)); \
mfcr 0; /* save CR/R3 around CDISABLE. */ \
- std 3,64(1); \
- std 0,8(1); \
- ld 3,72(1); /* pass MASK to CDISABLE. */ \
+ std 3,120(1); \
+ std 0,128+8(1); \
+ cfi_offset (cr, 8); \
+ ld 3,112(1); /* pass MASK to CDISABLE. */ \
CDISABLE; \
ld 9,128+16(1); \
- ld 0,8(1); /* restore CR/R3. */ \
- ld 3,64(1); \
+ ld 0,128+8(1); /* restore CR/R3. */ \
+ ld 3,120(1); \
mtlr 9; \
mtcr 0; \
- addi 1,1,128;
+ addi 1,1,128; \
+ cfi_adjust_cfa_offset (-128); \
+ cfi_restore (lr); \
+ cfi_restore (cr)
# define DOCARGS_0
# define UNDOCARGS_0
-# define DOCARGS_1 std 3,80(1); DOCARGS_0
-# define UNDOCARGS_1 ld 3,80(1); UNDOCARGS_0
+# define DOCARGS_1 std 3,128+48(1); DOCARGS_0
+# define UNDOCARGS_1 ld 3,128+48(1); UNDOCARGS_0
-# define DOCARGS_2 std 4,88(1); DOCARGS_1
-# define UNDOCARGS_2 ld 4,88(1); UNDOCARGS_1
+# define DOCARGS_2 std 4,128+56(1); DOCARGS_1
+# define UNDOCARGS_2 ld 4,128+56(1); UNDOCARGS_1
-# define DOCARGS_3 std 5,96(1); DOCARGS_2
-# define UNDOCARGS_3 ld 5,96(1); UNDOCARGS_2
+# define DOCARGS_3 std 5,128+64(1); DOCARGS_2
+# define UNDOCARGS_3 ld 5,128+64(1); UNDOCARGS_2
-# define DOCARGS_4 std 6,104(1); DOCARGS_3
-# define UNDOCARGS_4 ld 6,104(1); UNDOCARGS_3
+# define DOCARGS_4 std 6,128+72(1); DOCARGS_3
+# define UNDOCARGS_4 ld 6,128+72(1); UNDOCARGS_3
-# define DOCARGS_5 std 7,112(1); DOCARGS_4
-# define UNDOCARGS_5 ld 7,112(1); UNDOCARGS_4
+# define DOCARGS_5 std 7,128+80(1); DOCARGS_4
+# define UNDOCARGS_5 ld 7,128+80(1); UNDOCARGS_4
-# define DOCARGS_6 std 8,120(1); DOCARGS_5
-# define UNDOCARGS_6 ld 8,120(1); UNDOCARGS_5
+# define DOCARGS_6 std 8,128+88(1); DOCARGS_5
+# define UNDOCARGS_6 ld 8,128+88(1); UNDOCARGS_5
# ifdef IS_IN_libpthread
-# define CENABLE bl JUMPTARGET(__pthread_enable_asynccancel)
-# define CDISABLE bl JUMPTARGET(__pthread_disable_asynccancel)
+# ifdef SHARED
+# define CENABLE bl JUMPTARGET(__pthread_enable_asynccancel)
+# define CDISABLE bl JUMPTARGET(__pthread_disable_asynccancel)
+# else
+# define CENABLE bl JUMPTARGET(__pthread_enable_asynccancel); nop
+# define CDISABLE bl JUMPTARGET(__pthread_disable_asynccancel); nop
+# endif
# elif !defined NOT_IN_libc
-# define CENABLE bl JUMPTARGET(__libc_enable_asynccancel)
-# define CDISABLE bl JUMPTARGET(__libc_disable_asynccancel)
+# ifdef SHARED
+# define CENABLE bl JUMPTARGET(__libc_enable_asynccancel)
+# define CDISABLE bl JUMPTARGET(__libc_disable_asynccancel)
+# else
+# define CENABLE bl JUMPTARGET(__libc_enable_asynccancel); nop
+# define CDISABLE bl JUMPTARGET(__libc_disable_asynccancel); nop
+# endif
# elif defined IS_IN_librt
-# define CENABLE bl JUMPTARGET(__librt_enable_asynccancel)
-# define CDISABLE bl JUMPTARGET(__librt_disable_asynccancel)
+# ifdef SHARED
+# define CENABLE bl JUMPTARGET(__librt_enable_asynccancel)
+# define CDISABLE bl JUMPTARGET(__librt_disable_asynccancel)
+# else
+# define CENABLE bl JUMPTARGET(__librt_enable_asynccancel); nop
+# define CDISABLE bl JUMPTARGET(__librt_disable_asynccancel); nop
+# endif
# else
# error Unsupported library
# endif
diff --git a/sysdeps/powerpc/powerpc32/power4/memcmp.S b/sysdeps/powerpc/powerpc32/power4/memcmp.S
index 75b328403a..fe67833dff 100644
--- a/sysdeps/powerpc/powerpc32/power4/memcmp.S
+++ b/sysdeps/powerpc/powerpc32/power4/memcmp.S
@@ -646,7 +646,7 @@ L(Wunaligned):
cfi_offset(r25,(24-64))
andi. rBITDIF, rN, 12 /* Get the W remainder */
stw r24,20(r1)
- cfi_offset(r24,(24-64))
+ cfi_offset(r24,(20-64))
slwi rSHL, rSHL, 3
lwz rWORD6, 0(rSTR2)
lwzu rWORD8, 4(rSTR2)
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
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/brk.S b/sysdeps/unix/sysv/linux/powerpc/powerpc64/brk.S
index f2ac00d4c7..ef574c14fc 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/brk.S
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/brk.S
@@ -32,19 +32,16 @@ ENTRY (BP_SYM (__brk))
CALL_MCOUNT 1
DISCARD_BOUNDS (r3) /* the bounds are meaningless, so toss 'em. */
- stdu r1,-64(r1)
- cfi_adjust_cfa_offset (64)
std r3,48(r1)
DO_CALL(SYS_ify(brk))
- ld r6,48(r1)
+ ld r6,48(r1)
ld r5,.LC__curbrk@toc(r2)
std r3,0(r5)
cmpld r6,r3
- addi r1,r1,64
li r3,0
blelr+
li r3,ENOMEM
- b JUMPTARGET(__syscall_error)
+ TAIL_CALL_SYSCALL_ERROR
END (BP_SYM (__brk))
weak_alias (BP_SYM (__brk), BP_SYM (brk))
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S b/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S
index f1a55e64db..d14da54fd7 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S
@@ -46,35 +46,32 @@ ENTRY (BP_SYM (__clone))
cror cr0*4+eq,cr1*4+eq,cr0*4+eq
beq- cr0,L(badargs)
- /* Set up stack frame for parent. */
- stdu r1,-80(r1)
- cfi_adjust_cfa_offset (80)
- std r29,56(r1)
- std r30,64(r1)
- std r31,72(r1)
- cfi_offset(r29,-56)
- cfi_offset(r30,-64)
- cfi_offset(r31,-72)
+ /* Save some regs in parm save area. */
#ifdef RESET_PID
- std r28,48(r1)
- cfi_offset(r28,-48)
+ std r29,48(r1)
#endif
+ std r30,56(r1)
+ std r31,64(r1)
+#ifdef RESET_PID
+ cfi_offset(r29,48)
+#endif
+ cfi_offset(r30,56)
+ cfi_offset(r31,64)
/* Set up stack frame for child. */
clrrdi r4,r4,4
li r0,0
- stdu r0,-48(r4) /* min stack frame is 48 bytes per ABI */
+ stdu r0,-112(r4) /* min stack frame is 112 bytes per ABI */
/* Save fn, args, stack across syscall. */
- mr r29,r3 /* Function in r29. */
- mr r30,r4 /* Stack pointer in r30. */
+ mr r30,r3 /* Function in r30. */
#ifdef RESET_PID
- mr r28,r5 /* Flags in r28. */
+ mr r29,r5 /* Flags in r29. */
#endif
mr r31,r6 /* Argument in r31. */
- /* 'flags' argument is first parameter to clone syscall. (The other
- argument is the stack pointer, already in r4.) */
+ /* 'flags' argument is first parameter to clone syscall.
+ Second is the stack pointer, already in r4. */
mr r3,r5
/* Move the parent_tid, child_tid and tls arguments. */
mr r5,r7
@@ -94,9 +91,9 @@ ENTRY (BP_SYM (__clone))
bne- cr1,L(parent) /* The '-' is to minimise the race. */
#ifdef RESET_PID
- andis. r0,r28,CLONE_THREAD>>16
+ andis. r0,r29,CLONE_THREAD>>16
bne+ cr0,L(oldpid)
- andi. r0,r28,CLONE_VM
+ andi. r0,r29,CLONE_VM
li r3,-1
bne- cr0,L(nomoregetpid)
DO_CALL(SYS_ify(getpid))
@@ -108,8 +105,8 @@ L(oldpid):
std r2,40(r1)
/* Call procedure. */
- ld r0,0(r29)
- ld r2,8(r29)
+ ld r0,0(r30)
+ ld r2,8(r30)
mtctr r0
mr r3,r31
bctrl
@@ -119,25 +116,35 @@ L(oldpid):
b JUMPTARGET(__GI__exit)
#else
b JUMPTARGET(_exit)
+ /* We won't ever get here but provide a nop so that the linker
+ will insert a toc adjusting stub if necessary. */
+ nop
#endif
+L(badargs):
+ cfi_startproc
+ li r3,EINVAL
+ TAIL_CALL_SYSCALL_ERROR
+
L(parent):
/* Parent. Restore registers & return. */
#ifdef RESET_PID
- ld r28,48(r1)
+ cfi_offset(r29,48)
#endif
- ld r31,72(r1)
- ld r30,64(r1)
- ld r29,56(r1)
- addi r1,r1,80
- bnslr+
- b JUMPTARGET(__syscall_error)
-
-L(badargs):
- li r3,EINVAL
- b JUMPTARGET(__syscall_error)
+ cfi_offset(r30,56)
+ cfi_offset(r31,64)
+#ifdef RESET_PID
+ ld r29,48(r1)
+#endif
+ ld r30,56(r1)
+ ld r31,64(r1)
+#ifdef RESET_PID
+ cfi_restore(r29)
+#endif
+ cfi_restore(r30)
+ cfi_restore(r31)
+ PSEUDO_RET
- cfi_startproc
END (BP_SYM (__clone))
weak_alias (BP_SYM (__clone), BP_SYM (clone))
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/makecontext.S b/sysdeps/unix/sysv/linux/powerpc/powerpc64/makecontext.S
index 4a82802d96..18baa39d6a 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/makecontext.S
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/makecontext.S
@@ -154,6 +154,7 @@ L(BADSTATUS):
b JUMPTARGET(__GI_exit);
#else
b JUMPTARGET(exit);
+ nop
#endif
/* The address of the exit code is in the link register. Store the lr
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/socket.S b/sysdeps/unix/sysv/linux/powerpc/powerpc64/socket.S
index 15d8e84c1f..a0ae11594a 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/socket.S
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/socket.S
@@ -39,8 +39,6 @@
#define NARGS 3
#endif
-#define stackblock 80 /* offset to socket parm area. */
-
#ifndef __socket
# ifndef NO_WEAK_ALIAS
# define __socket P(__,socket)
@@ -49,11 +47,14 @@
# endif
#endif
+#define FRAMESIZE 128
+#define stackblock FRAMESIZE+48 /* offset to parm save area. */
+
.text
ENTRY(__socket)
CALL_MCOUNT NARGS
- stdu r1,-144(r1)
- cfi_adjust_cfa_offset(144)
+ stdu r1,-FRAMESIZE(r1)
+ cfi_adjust_cfa_offset(FRAMESIZE)
#if NARGS >= 1
std r3,stackblock(r1)
#endif
@@ -87,33 +88,39 @@ ENTRY(__socket)
bne- .Lsocket_cancel
#endif
- li r3,P(SOCKOP_,socket)
+ li r3,P(SOCKOP_,socket)
addi r4,r1,stackblock
DO_CALL(SYS_ify(socketcall))
- addi r1,r1,144
+ addi r1,r1,FRAMESIZE
+ cfi_adjust_cfa_offset(-FRAMESIZE)
PSEUDO_RET
#if defined NEED_CANCELLATION && defined CENABLE
.Lsocket_cancel:
+ cfi_adjust_cfa_offset(FRAMESIZE)
mflr r9
- std r9,144+16(r1)
+ std r9,FRAMESIZE+16(r1)
cfi_offset (lr, 16)
CENABLE
- std r3,72(r1)
- li r3,P(SOCKOP_,socket)
+ std r3,120(r1)
+ li r3,P(SOCKOP_,socket)
addi r4,r1,stackblock
DO_CALL(SYS_ify(socketcall))
mfcr r0
- std r3,64(r1)
- std r0,8(r1)
- ld r3,72(r1)
+ std r3,112(r1)
+ std r0,FRAMESIZE+8(r1)
+ cfi_offset (cr, 8)
+ ld r3,120(r1)
CDISABLE
- ld r4,144+16(r1)
- ld r0,8(r1)
- ld r3,64(r1)
+ ld r4,FRAMESIZE+16(r1)
+ ld r0,FRAMESIZE+8(r1)
+ ld r3,112(r1)
mtlr r4
mtcr r0
- addi r1,r1,144
+ addi r1,r1,FRAMESIZE
+ cfi_adjust_cfa_offset(-FRAMESIZE)
+ cfi_restore(lr)
+ cfi_restore(cr)
PSEUDO_RET
#endif
PSEUDO_END (__socket)
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/vfork.S b/sysdeps/unix/sysv/linux/powerpc/powerpc64/vfork.S
index 2f5df38cf8..14d0c2bf10 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/vfork.S
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/vfork.S
@@ -39,7 +39,7 @@ ENTRY (__vfork)
bnslr+
/* Check if vfork syscall is known at all. */
cmpdi r3,ENOSYS
- bne JUMPTARGET(__syscall_error)
+ bne .Local_syscall_error
# endif
#endif