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 /sysdeps/powerpc/powerpc64 | |
parent | 026373745eab50a683536d950cb7e17dc98c4259 (diff) | |
download | glibc-bebff237c522e4e8e23204ca1e5104896389158e.tar glibc-bebff237c522e4e8e23204ca1e5104896389158e.tar.gz glibc-bebff237c522e4e8e23204ca1e5104896389158e.tar.bz2 glibc-bebff237c522e4e8e23204ca1e5104896389158e.zip |
PowerPC64 ABI fixes
Diffstat (limited to 'sysdeps/powerpc/powerpc64')
-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 |
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 |