diff options
author | Alan Modra <amodra@gmail.com> | 2010-08-12 09:19:19 -0700 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2010-08-12 09:19:19 -0700 |
commit | bebff237c522e4e8e23204ca1e5104896389158e (patch) | |
tree | a4edee831e0476277cc372a46fa8281ab0bc229a | |
parent | 026373745eab50a683536d950cb7e17dc98c4259 (diff) | |
download | glibc-bebff237c522e4e8e23204ca1e5104896389158e.tar.gz |
PowerPC64 ABI fixes
-rw-r--r-- | ChangeLog | 37 | ||||
-rw-r--r-- | nptl/ChangeLog | 11 | ||||
-rw-r--r-- | nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h | 69 | ||||
-rw-r--r-- | sysdeps/powerpc/powerpc32/power4/memcmp.S | 2 | ||||
-rw-r--r-- | sysdeps/powerpc/powerpc64/bsd-_setjmp.S | 67 | ||||
-rw-r--r-- | sysdeps/powerpc/powerpc64/bsd-setjmp.S | 46 | ||||
-rw-r--r-- | sysdeps/powerpc/powerpc64/dl-trampoline.S | 76 | ||||
-rw-r--r-- | sysdeps/powerpc/powerpc64/fpu/s_copysign.S | 7 | ||||
-rw-r--r-- | sysdeps/powerpc/powerpc64/setjmp-common.S | 41 | ||||
-rw-r--r-- | sysdeps/powerpc/powerpc64/setjmp.S | 13 | ||||
-rw-r--r-- | sysdeps/powerpc/powerpc64/sysdep.h | 59 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/powerpc/powerpc64/brk.S | 7 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S | 73 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/powerpc/powerpc64/makecontext.S | 1 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/powerpc/powerpc64/socket.S | 39 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/powerpc/powerpc64/vfork.S | 2 |
16 files changed, 315 insertions, 235 deletions
@@ -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 |