diff options
Diffstat (limited to 'sysdeps/unix/sysv/linux/powerpc/powerpc32')
24 files changed, 1478 insertions, 1439 deletions
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/Dist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/Dist new file mode 100644 index 0000000000..297e031620 --- /dev/null +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/Dist @@ -0,0 +1,3 @@ +clone.S +kernel_stat.h +fe_nomask.c diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/brk.S b/sysdeps/unix/sysv/linux/powerpc/powerpc32/brk.S index e945834945..8ecbb548a2 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/brk.S +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/brk.S @@ -1,5 +1,5 @@ /* brk system call for Linux/ppc. - Copyright (C) 1995-97, 1999, 2000, 2006 Free Software Foundation, Inc. + Copyright (C) 1995, 1996, 1997, 1999, 2000 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 @@ -14,8 +14,8 @@ 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., 51 Franklin Street, Fifth Floor, Boston MA - 02110-1301 USA. */ + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ #include <sysdep.h> #define _ERRNO_H 1 @@ -27,38 +27,28 @@ .section ".text" ENTRY (BP_SYM (__brk)) DISCARD_BOUNDS (r3) /* the bounds are meaningless, so toss 'em */ - mflr r0 + stwu r1,-16(r1) - cfi_adjust_cfa_offset (16) stw r3,8(r1) - stw r0,20(r1) - cfi_offset (lr, 4) DO_CALL(SYS_ify(brk)) lwz r6,8(r1) #ifdef PIC -# ifdef HAVE_ASM_PPC_REL16 - bcl 20,31,1f -1: mflr r5 - addis r5,r5,__curbrk-1b@ha - stw r3,__curbrk-1b@l(r5) -# else + mflr r4 bl _GLOBAL_OFFSET_TABLE_@local-4 mflr r5 lwz r5,__curbrk@got(r5) + mtlr r4 stw r3,0(r5) -# endif #else lis r4,__curbrk@ha stw r3,__curbrk@l(r4) #endif - lwz r0,20(r1) cmplw r6,r3 addi r1,r1,16 - mtlr r0 li r3,0 blelr+ li r3,ENOMEM - b __syscall_error@local + b JUMPTARGET(__syscall_error) END (BP_SYM (__brk)) weak_alias (BP_SYM (__brk), BP_SYM (brk)) diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/clone.S b/sysdeps/unix/sysv/linux/powerpc/powerpc32/clone.S index 37b777799c..f232284747 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/clone.S +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/clone.S @@ -1,5 +1,5 @@ /* Wrapper around clone system call. - Copyright (C) 1997,98,99,2000,02,04,2006 Free Software Foundation, Inc. + Copyright (C) 1997,98,99,2000,02,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 @@ -14,8 +14,8 @@ 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., 51 Franklin Street, Fifth Floor, Boston MA - 02110-1301 USA. */ + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ #include <sysdep.h> #define _ERRNO_H 1 @@ -49,7 +49,6 @@ ENTRY (BP_SYM (__clone)) /* Set up stack frame for parent. */ stwu r1,-32(r1) - cfi_adjust_cfa_offset (32) #ifdef RESET_PID stmw r28,16(r1) #else @@ -84,10 +83,6 @@ ENTRY (BP_SYM (__clone)) mr r6,r8 mr r7,r9 - /* End FDE now, because in the child the unwind info will be - wrong. */ - cfi_endproc - /* Do the call. */ DO_CALL(SYS_ify(clone)) @@ -137,13 +132,11 @@ L(parent): #endif addi r1,r1,32 bnslr+ - b __syscall_error@local + b JUMPTARGET(__syscall_error) L(badargs): li r3,EINVAL - b __syscall_error@local - - cfi_startproc + b JUMPTARGET(__syscall_error) END (BP_SYM (__clone)) weak_alias (BP_SYM (__clone), BP_SYM (clone)) diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fe_nomask.c b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fe_nomask.c index 8d3b9ad1f4..2c85a3a9e9 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fe_nomask.c +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fe_nomask.c @@ -1,5 +1,5 @@ /* Procedure definition for FE_NOMASK_ENV for Linux/ppc. - Copyright (C) 2000, 2006 Free Software Foundation, Inc. + Copyright (C) 2000 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 @@ -23,11 +23,11 @@ #include <unistd.h> #include <sysdep.h> #include <sys/prctl.h> -#include <kernel-features.h> +#include "kernel-features.h" #if __ASSUME_NEW_PRCTL_SYSCALL == 0 /* This is rather fiddly under Linux. We don't have direct access, - and there is no system call, but we can change the bits + and there is no system call, but we can change the bits in a signal handler's context... */ static struct sigaction oact; diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/Implies b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/Implies deleted file mode 100644 index 9f70f795bc..0000000000 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/Implies +++ /dev/null @@ -1,2 +0,0 @@ -# Override ldbl-opt with powerpc32 specific routines. -powerpc/powerpc32/fpu diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/ftruncate64.c b/sysdeps/unix/sysv/linux/powerpc/powerpc32/ftruncate64.c index e83f7f04b7..e79d74cb75 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/ftruncate64.c +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/ftruncate64.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1997-2002,2005,2006 Free Software Foundation, Inc. +/* Copyright (C) 1997,1998,1999,2000,2001,2002 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 @@ -23,12 +23,12 @@ #include <sysdep.h> #include <sys/syscall.h> -#include <kernel-features.h> +#include "kernel-features.h" #ifdef __NR_ftruncate64 #ifndef __ASSUME_TRUNCATE64_SYSCALL /* The variable is shared between all wrappers around *truncate64 calls. */ -extern int __have_no_truncate64; +extern int have_no_truncate64; #endif @@ -39,7 +39,7 @@ __ftruncate64 (fd, length) off64_t length; { #ifndef __ASSUME_TRUNCATE64_SYSCALL - if (! __have_no_truncate64) + if (! have_no_truncate64) #endif { #ifndef __ASSUME_TRUNCATE64_SYSCALL @@ -57,7 +57,7 @@ __ftruncate64 (fd, length) #ifndef __ASSUME_TRUNCATE64_SYSCALL __set_errno (saved_errno); - __have_no_truncate64 = 1; + have_no_truncate64 = 1; #endif } @@ -74,5 +74,5 @@ weak_alias (__ftruncate64, ftruncate64) #else /* Use the generic implementation. */ -# include <misc/ftruncate64.c> +# include <sysdeps/generic/ftruncate64.c> #endif diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fxstatat.c b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fxstatat.c deleted file mode 100644 index 0f8b3135d8..0000000000 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fxstatat.c +++ /dev/null @@ -1 +0,0 @@ -#include <sysdeps/unix/sysv/linux/i386/fxstatat.c> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/getcontext-common.S b/sysdeps/unix/sysv/linux/powerpc/powerpc32/getcontext-common.S deleted file mode 100644 index c28c34664c..0000000000 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/getcontext-common.S +++ /dev/null @@ -1,286 +0,0 @@ -/* Save current context, powerpc32 common. - Copyright (C) 2005, 2006 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., 51 Franklin Street, Fifth Floor, Boston MA - 02110-1301 USA. */ - -/* This is the common implementation of getcontext for powerpc32. - It not complete in itself should be included in to a framework that - defines: - __CONTEXT_FUNC_NAME - and if appropriate: - __CONTEXT_ENABLE_FPRS - __CONTEXT_ENABLE_VRS - Any archecture that implements the Vector unit is assumed to also - implement the floating unit. */ - -/* Stack frame offsets. */ -#define _FRAME_BACKCHAIN 0 -#define _FRAME_LR_SAVE 4 -#define _FRAME_PARM_SAVE1 8 -#define _FRAME_PARM_SAVE2 12 -#define _FRAME_PARM_SAVE3 16 -#define _FRAME_PARM_SAVE4 20 - -#ifdef __CONTEXT_ENABLE_VRS - .machine "altivec" -#endif -ENTRY(__CONTEXT_FUNC_NAME) - stwu r1,-16(r1) - cfi_adjust_cfa_offset (16) -/* Insure that the _UC_REGS start on a quadword boundary. */ - stw r3,_FRAME_PARM_SAVE1(r1) - addi r3,r3,_UC_REG_SPACE+12 - clrrwi r3,r3,4 - -/* Save the general purpose registers */ - stw r0,_UC_GREGS+(PT_R0*4)(r3) - mflr r0 - stw r2,_UC_GREGS+(PT_R2*4)(r3) - stw r4,_UC_GREGS+(PT_R4*4)(r3) -/* Set the callers LR_SAVE, and the ucontext LR and NIP to the callers - return address. */ - stw r0,_UC_GREGS+(PT_LNK*4)(r3) - stw r0,_UC_GREGS+(PT_NIP*4)(r3) - stw r0,_FRAME_LR_SAVE+16(r1) - cfi_offset (lr, _FRAME_LR_SAVE) - stw r5,_UC_GREGS+(PT_R5*4)(r3) - stw r6,_UC_GREGS+(PT_R6*4)(r3) - stw r7,_UC_GREGS+(PT_R7*4)(r3) - stw r8,_UC_GREGS+(PT_R8*4)(r3) - stw r9,_UC_GREGS+(PT_R9*4)(r3) - stw r10,_UC_GREGS+(PT_R10*4)(r3) - stw r11,_UC_GREGS+(PT_R11*4)(r3) - stw r12,_UC_GREGS+(PT_R12*4)(r3) - stw r13,_UC_GREGS+(PT_R13*4)(r3) - stw r14,_UC_GREGS+(PT_R14*4)(r3) - stw r15,_UC_GREGS+(PT_R15*4)(r3) - stw r16,_UC_GREGS+(PT_R16*4)(r3) - stw r17,_UC_GREGS+(PT_R17*4)(r3) - stw r18,_UC_GREGS+(PT_R18*4)(r3) - stw r19,_UC_GREGS+(PT_R19*4)(r3) - stw r20,_UC_GREGS+(PT_R20*4)(r3) - stw r21,_UC_GREGS+(PT_R21*4)(r3) - stw r22,_UC_GREGS+(PT_R22*4)(r3) - stw r23,_UC_GREGS+(PT_R23*4)(r3) - stw r24,_UC_GREGS+(PT_R24*4)(r3) - stw r25,_UC_GREGS+(PT_R25*4)(r3) - stw r26,_UC_GREGS+(PT_R26*4)(r3) - stw r27,_UC_GREGS+(PT_R27*4)(r3) - stw r28,_UC_GREGS+(PT_R28*4)(r3) - stw r29,_UC_GREGS+(PT_R29*4)(r3) - stw r30,_UC_GREGS+(PT_R30*4)(r3) - stw r31,_UC_GREGS+(PT_R31*4)(r3) -/* Save the value of R1. We had to push the stack before we - had the address of uc_reg_space. So compute the address of - the callers stack pointer and save it as R1. */ - addi r8,r1,16 - li r0,0 -/* Save the count, exception and condition registers. */ - mfctr r11 - mfxer r10 - mfcr r9 - stw r8,_UC_GREGS+(PT_R1*4)(r3) - stw r11,_UC_GREGS+(PT_CTR*4)(r3) - stw r10,_UC_GREGS+(PT_XER*4)(r3) - stw r9,_UC_GREGS+(PT_CCR*4)(r3) -/* Set the return value of getcontext to "success". R3 is the only - register whose value is not preserved in the saved context. */ - stw r0,_UC_GREGS+(PT_R3*4)(r3) - -/* Zero fill fields that can't be set in user state. */ - stw r0,_UC_GREGS+(PT_MSR*4)(r3) - stw r0,_UC_GREGS+(PT_MQ*4)(r3) - -#ifdef __CONTEXT_ENABLE_FPRS -/* Save the floating-point registers */ - stfd fp0,_UC_FREGS+(0*8)(r3) - stfd fp1,_UC_FREGS+(1*8)(r3) - stfd fp2,_UC_FREGS+(2*8)(r3) - stfd fp3,_UC_FREGS+(3*8)(r3) - stfd fp4,_UC_FREGS+(4*8)(r3) - stfd fp5,_UC_FREGS+(5*8)(r3) - stfd fp6,_UC_FREGS+(6*8)(r3) - stfd fp7,_UC_FREGS+(7*8)(r3) - stfd fp8,_UC_FREGS+(8*8)(r3) - stfd fp9,_UC_FREGS+(9*8)(r3) - stfd fp10,_UC_FREGS+(10*8)(r3) - stfd fp11,_UC_FREGS+(11*8)(r3) - stfd fp12,_UC_FREGS+(12*8)(r3) - stfd fp13,_UC_FREGS+(13*8)(r3) - stfd fp14,_UC_FREGS+(14*8)(r3) - stfd fp15,_UC_FREGS+(15*8)(r3) - stfd fp16,_UC_FREGS+(16*8)(r3) - stfd fp17,_UC_FREGS+(17*8)(r3) - stfd fp18,_UC_FREGS+(18*8)(r3) - stfd fp19,_UC_FREGS+(19*8)(r3) - stfd fp20,_UC_FREGS+(20*8)(r3) - stfd fp21,_UC_FREGS+(21*8)(r3) - stfd fp22,_UC_FREGS+(22*8)(r3) - stfd fp23,_UC_FREGS+(23*8)(r3) - stfd fp24,_UC_FREGS+(24*8)(r3) - stfd fp25,_UC_FREGS+(25*8)(r3) - stfd fp26,_UC_FREGS+(26*8)(r3) - stfd fp27,_UC_FREGS+(27*8)(r3) - stfd fp28,_UC_FREGS+(28*8)(r3) - stfd fp29,_UC_FREGS+(29*8)(r3) - mffs fp0 - stfd fp30,_UC_FREGS+(30*8)(r3) - stfd fp31,_UC_FREGS+(31*8)(r3) - stfd fp0,_UC_FREGS+(32*8)(r3) - -# ifdef __CONTEXT_ENABLE_VRS -# ifdef PIC - mflr r8 -# ifdef HAVE_ASM_PPC_REL16 - bcl 20,31,1f -1: mflr r7 - addis r7,r7,_GLOBAL_OFFSET_TABLE_-1b@ha - addi r7,r7,_GLOBAL_OFFSET_TABLE_-1b@l -# else - bl _GLOBAL_OFFSET_TABLE_@local-4 - mflr r7 -# endif -# ifdef SHARED - lwz r7,_rtld_global_ro@got(r7) - mtlr r8 - lwz r7,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r7) -# else - lwz r7,_dl_hwcap@got(r7) - mtlr r8 - lwz r7,0(r7) -# endif -# else - lis r7,_dl_hwcap@ha - lwz r7,_dl_hwcap@l(r7) -# endif - andis. r7,r7,(PPC_FEATURE_HAS_ALTIVEC >> 16) - - la r10,(_UC_VREGS)(r3) - la r9,(_UC_VREGS+16)(r3) - - beq 2f /* L(no_vec) */ -/* address of the combined VSCR/VSAVE quadword. */ - la r8,(_UC_VREGS+512)(r3) - -/* Save the vector registers */ - stvx v0,0,r10 - stvx v1,0,r9 - addi r10,r10,32 - addi r9,r9,32 -/* We need to get the Vector Status and Control Register early to avoid - store order problems later with the VSAVE register that shares the - same quadword. */ - mfvscr v0 - - stvx v2,0,r10 - stvx v3,0,r9 - addi r10,r10,32 - addi r9,r9,32 - - stvx v0,0,r8 - - stvx v4,0,r10 - stvx v5,0,r9 - addi r10,r10,32 - addi r9,r9,32 - - stvx v6,0,r10 - stvx v7,0,r9 - addi r10,r10,32 - addi r9,r9,32 - - stvx v8,0,r10 - stvx v9,0,r9 - addi r10,r10,32 - addi r9,r9,32 - - stvx v10,0,r10 - stvx v11,0,r9 - addi r10,r10,32 - addi r9,r9,32 - - stvx v12,0,r10 - stvx v13,0,r9 - addi r10,r10,32 - addi r9,r9,32 - - stvx v14,0,r10 - stvx v15,0,r9 - addi r10,r10,32 - addi r9,r9,32 - - stvx v16,0,r10 - stvx v17,0,r9 - addi r10,r10,32 - addi r9,r9,32 - - stvx v18,0,r10 - stvx v19,0,r9 - addi r10,r10,32 - addi r9,r9,32 - - stvx v20,0,r10 - stvx v21,0,r9 - addi r10,r10,32 - addi r9,r9,32 - - stvx v22,0,r10 - stvx v23,0,r9 - addi r10,r10,32 - addi r9,r9,32 - - stvx v24,0,r10 - stvx v25,0,r9 - addi r10,r10,32 - addi r9,r9,32 - - stvx v26,0,r10 - stvx v27,0,r9 - addi r10,r10,32 - addi r9,r9,32 - - stvx v28,0,r10 - stvx v29,0,r9 - addi r10,r10,32 - addi r9,r9,32 - - mfspr r0,VRSAVE - stvx v30,0,r10 - stvx v31,0,r9 - - stw r0,0(r8) - -2: /* L(no_vec): */ -# endif -#endif -/* We need to set up parms and call sigprocmask which will clobber - volatile registers. So before the call we need to retrieve the - original ucontext ptr (parm1) from stack and store the UC_REGS_PTR - (current R3). */ - lwz r12,_FRAME_PARM_SAVE1(r1) - li r4,0 - stw r3,_UC_REGS_PTR(r12) - addi r5,r12,_UC_SIGMASK - li r3,SIG_BLOCK - bl __sigprocmask@local - - lwz r0,_FRAME_LR_SAVE+16(r1) - addi r1,r1,16 - mtlr r0 - blr -END(__CONTEXT_FUNC_NAME) - diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/getcontext.S b/sysdeps/unix/sysv/linux/powerpc/powerpc32/getcontext.S index dad1074034..4c75354a5f 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/getcontext.S +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/getcontext.S @@ -1,5 +1,5 @@ /* Save current context. - Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2002, 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 @@ -14,53 +14,362 @@ 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., 51 Franklin Street, Fifth Floor, Boston MA - 02110-1301 USA. */ + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ #include <sysdep.h> #include <rtld-global-offsets.h> #include <shlib-compat.h> -#include <kernel-features.h> #define __ASSEMBLY__ #include <asm/ptrace.h> #include "ucontext_i.h" -#define __CONTEXT_FUNC_NAME __getcontext -#define __CONTEXT_ENABLE_FPRS 1 -#define __CONTEXT_ENABLE_VRS 1 + .machine "altivec" +ENTRY(__getcontext) + stwu r1,-16(r1) +/* Insure that the _UC_REGS start on a quadword boundary. */ + stw r3,_FRAME_PARM_SAVE1(r1) + addi r3,r3,_UC_REG_SPACE+12 + clrrwi r3,r3,4 -/* Size of ucontext in GLIBC_2.3.4 and later. */ -#define _UC_SIZE_2_3_4 1184 +/* Save the general purpose registers */ + stw r0,_UC_GREGS+(PT_R0*4)(r3) + mflr r0 + stw r2,_UC_GREGS+(PT_R2*4)(r3) + stw r4,_UC_GREGS+(PT_R4*4)(r3) +/* Set the callers LR_SAVE, and the ucontext LR and NIP to the callers + return address. */ + stw r0,_UC_GREGS+(PT_LNK*4)(r3) + stw r0,_UC_GREGS+(PT_NIP*4)(r3) + stw r0,_FRAME_LR_SAVE+16(r1) + stw r5,_UC_GREGS+(PT_R5*4)(r3) + stw r6,_UC_GREGS+(PT_R6*4)(r3) + stw r7,_UC_GREGS+(PT_R7*4)(r3) + stw r8,_UC_GREGS+(PT_R8*4)(r3) + stw r9,_UC_GREGS+(PT_R9*4)(r3) + stw r10,_UC_GREGS+(PT_R10*4)(r3) + stw r11,_UC_GREGS+(PT_R11*4)(r3) + stw r12,_UC_GREGS+(PT_R12*4)(r3) + stw r13,_UC_GREGS+(PT_R13*4)(r3) + stw r14,_UC_GREGS+(PT_R14*4)(r3) + stw r15,_UC_GREGS+(PT_R15*4)(r3) + stw r16,_UC_GREGS+(PT_R16*4)(r3) + stw r17,_UC_GREGS+(PT_R17*4)(r3) + stw r18,_UC_GREGS+(PT_R18*4)(r3) + stw r19,_UC_GREGS+(PT_R19*4)(r3) + stw r20,_UC_GREGS+(PT_R20*4)(r3) + stw r21,_UC_GREGS+(PT_R21*4)(r3) + stw r22,_UC_GREGS+(PT_R22*4)(r3) + stw r23,_UC_GREGS+(PT_R23*4)(r3) + stw r24,_UC_GREGS+(PT_R24*4)(r3) + stw r25,_UC_GREGS+(PT_R25*4)(r3) + stw r26,_UC_GREGS+(PT_R26*4)(r3) + stw r27,_UC_GREGS+(PT_R27*4)(r3) + stw r28,_UC_GREGS+(PT_R28*4)(r3) + stw r29,_UC_GREGS+(PT_R29*4)(r3) + stw r30,_UC_GREGS+(PT_R30*4)(r3) + stw r31,_UC_GREGS+(PT_R31*4)(r3) +/* Save the value of R1. We had to push the stack before we + had the address of uc_reg_space. So compute the address of + the callers stack pointer and save it as R1. */ + addi r8,r1,16 + li r0,0 +/* Save the count, exception and condition registers. */ + mfctr r11 + mfxer r10 + mfcr r9 + stw r8,_UC_GREGS+(PT_R1*4)(r3) + stw r11,_UC_GREGS+(PT_CTR*4)(r3) + stw r10,_UC_GREGS+(PT_XER*4)(r3) + stw r9,_UC_GREGS+(PT_CCR*4)(r3) +/* Set the return value of getcontext to "success". R3 is the only + register whose value is not preserved in the saved context. */ + stw r0,_UC_GREGS+(PT_R3*4)(r3) -#ifdef __ASSUME_SWAPCONTEXT_SYSCALL - .section ".text"; -ENTRY (__getcontext) +/* Zero fill fields that can't be set in user state. */ + stw r0,_UC_GREGS+(PT_MSR*4)(r3) + stw r0,_UC_GREGS+(PT_MQ*4)(r3) + +/* Save the floating-point registers */ + stfd fp0,_UC_FREGS+(0*8)(r3) + stfd fp1,_UC_FREGS+(1*8)(r3) + stfd fp2,_UC_FREGS+(2*8)(r3) + stfd fp3,_UC_FREGS+(3*8)(r3) + stfd fp4,_UC_FREGS+(4*8)(r3) + stfd fp5,_UC_FREGS+(5*8)(r3) + stfd fp6,_UC_FREGS+(6*8)(r3) + stfd fp7,_UC_FREGS+(7*8)(r3) + stfd fp8,_UC_FREGS+(8*8)(r3) + stfd fp9,_UC_FREGS+(9*8)(r3) + stfd fp10,_UC_FREGS+(10*8)(r3) + stfd fp11,_UC_FREGS+(11*8)(r3) + stfd fp12,_UC_FREGS+(12*8)(r3) + stfd fp13,_UC_FREGS+(13*8)(r3) + stfd fp14,_UC_FREGS+(14*8)(r3) + stfd fp15,_UC_FREGS+(15*8)(r3) + stfd fp16,_UC_FREGS+(16*8)(r3) + stfd fp17,_UC_FREGS+(17*8)(r3) + stfd fp18,_UC_FREGS+(18*8)(r3) + stfd fp19,_UC_FREGS+(19*8)(r3) + stfd fp20,_UC_FREGS+(20*8)(r3) + stfd fp21,_UC_FREGS+(21*8)(r3) + stfd fp22,_UC_FREGS+(22*8)(r3) + stfd fp23,_UC_FREGS+(23*8)(r3) + stfd fp24,_UC_FREGS+(24*8)(r3) + stfd fp25,_UC_FREGS+(25*8)(r3) + stfd fp26,_UC_FREGS+(26*8)(r3) + stfd fp27,_UC_FREGS+(27*8)(r3) + stfd fp28,_UC_FREGS+(28*8)(r3) + stfd fp29,_UC_FREGS+(29*8)(r3) + mffs fp0 + stfd fp30,_UC_FREGS+(30*8)(r3) + stfd fp31,_UC_FREGS+(31*8)(r3) + stfd fp0,_UC_FREGS+(32*8)(r3) + +#ifdef PIC + mflr r8 + bl _GLOBAL_OFFSET_TABLE_@local-4 + mflr r7 +# ifdef SHARED + lwz r7,_rtld_global_ro@got(r7) + mtlr r8 + lwz r7,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r7) +# else + lwz r7,_dl_hwcap@got(r7) + mtlr r8 + lwz r7,0(r7) +# endif +#else + lis r7,_dl_hwcap@ha + lwz r7,_dl_hwcap@l(r7) +#endif + andis. r7,r7,(PPC_FEATURE_HAS_ALTIVEC >> 16) + + la r10,(_UC_VREGS)(r3) + la r9,(_UC_VREGS+16)(r3) + + beq L(no_vec) +/* address of the combined VSCR/VSAVE quadword. */ + la r8,(_UC_VREGS+512)(r3) + +/* Save the vector registers */ + stvx v0,0,r10 + stvx v1,0,r9 + addi r10,r10,32 + addi r9,r9,32 +/* We need to get the Vector Status and Control Register early to avoid + store order problems later with the VSAVE register that shares the + same quadword. */ + mfvscr v0 + + stvx v2,0,r10 + stvx v3,0,r9 + addi r10,r10,32 + addi r9,r9,32 + + stvx v0,0,r8 + + stvx v4,0,r10 + stvx v5,0,r9 + addi r10,r10,32 + addi r9,r9,32 + + stvx v6,0,r10 + stvx v7,0,r9 + addi r10,r10,32 + addi r9,r9,32 + + stvx v8,0,r10 + stvx v9,0,r9 + addi r10,r10,32 + addi r9,r9,32 + + stvx v10,0,r10 + stvx v11,0,r9 + addi r10,r10,32 + addi r9,r9,32 + + stvx v12,0,r10 + stvx v13,0,r9 + addi r10,r10,32 + addi r9,r9,32 + + stvx v14,0,r10 + stvx v15,0,r9 + addi r10,r10,32 + addi r9,r9,32 + + stvx v16,0,r10 + stvx v17,0,r9 + addi r10,r10,32 + addi r9,r9,32 + + stvx v18,0,r10 + stvx v19,0,r9 + addi r10,r10,32 + addi r9,r9,32 + + stvx v20,0,r10 + stvx v21,0,r9 + addi r10,r10,32 + addi r9,r9,32 + + stvx v22,0,r10 + stvx v23,0,r9 + addi r10,r10,32 + addi r9,r9,32 + + stvx v24,0,r10 + stvx v25,0,r9 + addi r10,r10,32 + addi r9,r9,32 + + stvx v26,0,r10 + stvx v27,0,r9 + addi r10,r10,32 + addi r9,r9,32 + + stvx v28,0,r10 + stvx v29,0,r9 + addi r10,r10,32 + addi r9,r9,32 + + mfspr r0,VRSAVE + stvx v30,0,r10 + stvx v31,0,r9 + + stw r0,0(r8) + +L(no_vec): +/* We need to set up parms and call sigprocmask which will clobber + volatile registers. So before the call we need to retrieve the + original ucontext ptr (parm1) from stack and store the UC_REGS_PTR + (current R3). */ + lwz r12,_FRAME_PARM_SAVE1(r1) li r4,0 - li r5,_UC_SIZE_2_3_4; - DO_CALL (SYS_ify (swapcontext)); - bso- cr0,1f -/* the kernel does not set the return code for the success case */ - li r3,0 + stw r3,_UC_REGS_PTR(r12) + addi r5,r12,_UC_SIGMASK + li r3,SIG_BLOCK + bl JUMPTARGET(__sigprocmask) + + lwz r0,_FRAME_LR_SAVE+16(r1) + addi r1,r1,16 + mtlr r0 blr -1: - b __syscall_error@local END(__getcontext) -#else -# include "getcontext-common.S" -#endif versioned_symbol (libc, __getcontext, getcontext, GLIBC_2_3_4) #if SHLIB_COMPAT (libc, GLIBC_2_3_3, GLIBC_2_3_4) + compat_text_section - -# undef __CONTEXT_FUNC_NAME -# define __CONTEXT_FUNC_NAME __novec_getcontext -# undef __CONTEXT_ENABLE_VRS +ENTRY(__novec_getcontext) + /* + * Since we are not attempting to save the altivec registers, + * there is no need to get the register storage space + * aligned on a 16-byte boundary. + */ + addi r3,r3,_UC_REG_SPACE + stw r3,_UC_REGS_PTR - _UC_REG_SPACE(r3) + stw r0,_UC_GREGS+(PT_R0*4)(r3) + stw r1,_UC_GREGS+(PT_R1*4)(r3) + mflr r0 + stwu r1,-16(r1) + stw r0,20(r1) + stw r0,_UC_GREGS+(PT_LNK*4)(r3) + stw r0,_UC_GREGS+(PT_NIP*4)(r3) + stw r2,_UC_GREGS+(PT_R2*4)(r3) + stw r4,_UC_GREGS+(PT_R4*4)(r3) + stw r5,_UC_GREGS+(PT_R5*4)(r3) + stw r6,_UC_GREGS+(PT_R6*4)(r3) + stw r7,_UC_GREGS+(PT_R7*4)(r3) + stw r8,_UC_GREGS+(PT_R8*4)(r3) + stw r9,_UC_GREGS+(PT_R9*4)(r3) + stw r10,_UC_GREGS+(PT_R10*4)(r3) + stw r11,_UC_GREGS+(PT_R11*4)(r3) + stw r12,_UC_GREGS+(PT_R12*4)(r3) + stw r13,_UC_GREGS+(PT_R13*4)(r3) + stw r14,_UC_GREGS+(PT_R14*4)(r3) + stw r15,_UC_GREGS+(PT_R15*4)(r3) + stw r16,_UC_GREGS+(PT_R16*4)(r3) + stw r17,_UC_GREGS+(PT_R17*4)(r3) + stw r18,_UC_GREGS+(PT_R18*4)(r3) + stw r19,_UC_GREGS+(PT_R19*4)(r3) + stw r20,_UC_GREGS+(PT_R20*4)(r3) + stw r21,_UC_GREGS+(PT_R21*4)(r3) + stw r22,_UC_GREGS+(PT_R22*4)(r3) + stw r23,_UC_GREGS+(PT_R23*4)(r3) + stw r24,_UC_GREGS+(PT_R24*4)(r3) + stw r25,_UC_GREGS+(PT_R25*4)(r3) + stw r26,_UC_GREGS+(PT_R26*4)(r3) + stw r27,_UC_GREGS+(PT_R27*4)(r3) + stw r28,_UC_GREGS+(PT_R28*4)(r3) + stw r29,_UC_GREGS+(PT_R29*4)(r3) + stw r30,_UC_GREGS+(PT_R30*4)(r3) + stw r31,_UC_GREGS+(PT_R31*4)(r3) + mfctr r0 + stw r0,_UC_GREGS+(PT_CTR*4)(r3) + mfxer r0 + stw r0,_UC_GREGS+(PT_XER*4)(r3) + mfcr r0 + stw r0,_UC_GREGS+(PT_CCR*4)(r3) + + /* Set the return value of getcontext to "success". R3 is the only + register whose value is not preserved in the saved context. */ + li r0,0 + stw r0,_UC_GREGS+(PT_R3*4)(r3) -# clude "getcontext-common.S" + /* Zero fill fields that can't be set in user state. */ + stw r0,_UC_GREGS+(PT_MSR*4)(r3) + stw r0,_UC_GREGS+(PT_MQ*4)(r3) + /* Save the floating-point registers */ + stfd fp0,_UC_FREGS+(0*8)(r3) + stfd fp1,_UC_FREGS+(1*8)(r3) + stfd fp2,_UC_FREGS+(2*8)(r3) + stfd fp3,_UC_FREGS+(3*8)(r3) + stfd fp4,_UC_FREGS+(4*8)(r3) + stfd fp5,_UC_FREGS+(5*8)(r3) + stfd fp6,_UC_FREGS+(6*8)(r3) + stfd fp7,_UC_FREGS+(7*8)(r3) + stfd fp8,_UC_FREGS+(8*8)(r3) + stfd fp9,_UC_FREGS+(9*8)(r3) + stfd fp10,_UC_FREGS+(10*8)(r3) + stfd fp11,_UC_FREGS+(11*8)(r3) + stfd fp12,_UC_FREGS+(12*8)(r3) + stfd fp13,_UC_FREGS+(13*8)(r3) + stfd fp14,_UC_FREGS+(14*8)(r3) + stfd fp15,_UC_FREGS+(15*8)(r3) + stfd fp16,_UC_FREGS+(16*8)(r3) + stfd fp17,_UC_FREGS+(17*8)(r3) + stfd fp18,_UC_FREGS+(18*8)(r3) + stfd fp19,_UC_FREGS+(19*8)(r3) + stfd fp20,_UC_FREGS+(20*8)(r3) + stfd fp21,_UC_FREGS+(21*8)(r3) + stfd fp22,_UC_FREGS+(22*8)(r3) + stfd fp23,_UC_FREGS+(23*8)(r3) + stfd fp24,_UC_FREGS+(24*8)(r3) + stfd fp25,_UC_FREGS+(25*8)(r3) + stfd fp26,_UC_FREGS+(26*8)(r3) + stfd fp27,_UC_FREGS+(27*8)(r3) + stfd fp28,_UC_FREGS+(28*8)(r3) + stfd fp29,_UC_FREGS+(29*8)(r3) + mffs fp0 + stfd fp30,_UC_FREGS+(30*8)(r3) + stfd fp31,_UC_FREGS+(31*8)(r3) + stfd fp0,_UC_FREGS+(32*8)(r3) + + addi r5,r3,_UC_SIGMASK - _UC_REG_SPACE + li r4,0 + li r3,SIG_BLOCK + bl JUMPTARGET(__sigprocmask) + + lwz r0,20(r1) + addi r1,r1,16 + mtlr r0 + blr +END(__novec_getcontext) .previous compat_symbol (libc, __novec_getcontext, getcontext, GLIBC_2_3_3) @@ -69,13 +378,13 @@ compat_symbol (libc, __novec_getcontext, getcontext, GLIBC_2_3_3) #if SHLIB_COMPAT (libc, GLIBC_2_1, GLIBC_2_3_3) -# define _ERRNO_H 1 -# include <bits/errno.h> +#define _ERRNO_H 1 +#include <bits/errno.h> compat_text_section ENTRY (__getcontext_stub) li r3,ENOSYS - b __syscall_error@local + b JUMPTARGET(__syscall_error) END (__getcontext_stub) .previous diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/makecontext.S b/sysdeps/unix/sysv/linux/powerpc/powerpc32/makecontext.S index 9451f9eb36..5615718e11 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/makecontext.S +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/makecontext.S @@ -1,5 +1,5 @@ /* Set up a context to call a function. - Copyright (C) 2002, 2004, 2006 Free Software Foundation, Inc. + Copyright (C) 2002, 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 @@ -14,8 +14,8 @@ 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., 51 Franklin Street, Fifth Floor, Boston MA - 02110-1301 USA. */ + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ #include <sysdep.h> #include <shlib-compat.h> @@ -26,7 +26,9 @@ ENTRY(__makecontext) /* Set up the first 7 args to the function in its registers */ - lwz r11,_UC_REGS_PTR(r3) + addi r11,r3,_UC_REG_SPACE+12 + clrrwi r11,r11,4 + stw r11,_UC_REGS_PTR(r3) stw r6,_UC_GREGS+(PT_R3*4)(r11) stw r7,_UC_GREGS+(PT_R4*4)(r11) stw r8,_UC_GREGS+(PT_R5*4)(r11) @@ -47,12 +49,10 @@ ENTRY(__makecontext) /* Set the function's LR to point to the exitcode below. */ #ifdef PIC mflr r0 - cfi_register(lr,r0) bl 1f 1: mflr r6 addi r6,r6,L(exitcode)-1b mtlr r0 - cfi_same_value (lr) #else lis r6,L(exitcode)@ha addi r6,r6,L(exitcode)@l @@ -101,7 +101,7 @@ ENTRY(__makecontext) L(exitcode): mr. r3,r31 beq 4f - bl __setcontext@local + bl JUMPTARGET(__setcontext) 4: bl HIDDEN_JUMPTARGET(exit) b 4b @@ -136,12 +136,10 @@ ENTRY(__novec_makecontext) /* Set the function's LR to point to the exitcode below. */ #ifdef PIC mflr r0 - cfi_register(lr,r0) bl 1f 1: mflr r6 addi r6,r6,L(novec_exitcode)-1b mtlr r0 - cfi_same_value (lr) #else lis r6,L(novec_exitcode)@ha addi r6,r6,L(novec_exitcode)@l @@ -190,7 +188,7 @@ ENTRY(__novec_makecontext) L(novec_exitcode): mr. r3,r31 beq 4f - bl __novec_setcontext@local + bl JUMPTARGET(__novec_setcontext) 4: bl HIDDEN_JUMPTARGET(exit) b 4b @@ -208,7 +206,7 @@ compat_symbol (libc, __novec_makecontext, makecontext, GLIBC_2_3_3) compat_text_section ENTRY (__makecontext_stub) li r3,ENOSYS - b __syscall_error@local + b JUMPTARGET(__syscall_error) END (__makecontext_stub) .previous diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/pread.c b/sysdeps/unix/sysv/linux/powerpc/powerpc32/pread.c index 4d9fa263c4..495c98ab97 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/pread.c +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/pread.c @@ -1,5 +1,5 @@ -/* Copyright (C) 1997,1998,1999,2000,2002,2003,2006 - Free Software Foundation, Inc. +/* Copyright (C) 1997, 1998, 1999, 2000, 2002, 2003 + Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. @@ -26,7 +26,7 @@ #include <sys/syscall.h> #include <bp-checks.h> -#include <kernel-features.h> +#include "kernel-features.h" #if defined __NR_pread || __ASSUME_PREAD_SYSCALL > 0 @@ -58,7 +58,7 @@ __libc_pread (fd, buf, count, offset) return result; } - + int oldtype = LIBC_CANCEL_ASYNC (); /* On PPC32 64bit values are aligned in odd/even register pairs. */ diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/pread64.c b/sysdeps/unix/sysv/linux/powerpc/powerpc32/pread64.c index 9527554e9b..d4fe1eea2d 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/pread64.c +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/pread64.c @@ -1,5 +1,5 @@ -/* Copyright (C) 1997,1998,1999,2000,2002,2003,2006 - Free Software Foundation, Inc. +/* Copyright (C) 1997, 1998, 1999, 2000, 2002, 2003 + Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. @@ -25,7 +25,7 @@ #include <sys/syscall.h> #include <bp-checks.h> -#include <kernel-features.h> +#include "kernel-features.h" #if defined __NR_pread || __ASSUME_PREAD_SYSCALL > 0 diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/pwrite.c b/sysdeps/unix/sysv/linux/powerpc/powerpc32/pwrite.c index 32383f4301..3727fa7a42 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/pwrite.c +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/pwrite.c @@ -1,5 +1,5 @@ -/* Copyright (C) 1997,1998,1999,2000,2002,2003,2006 - Free Software Foundation, Inc. +/* Copyright (C) 1997, 1998, 1999, 2000, 2002, 2003 + Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. @@ -26,7 +26,7 @@ #include <sys/syscall.h> #include <bp-checks.h> -#include <kernel-features.h> +#include "kernel-features.h" #if defined __NR_pwrite || __ASSUME_PWRITE_SYSCALL > 0 diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/pwrite64.c b/sysdeps/unix/sysv/linux/powerpc/powerpc32/pwrite64.c index acc250a88f..080c88cf29 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/pwrite64.c +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/pwrite64.c @@ -1,5 +1,5 @@ -/* Copyright (C) 1997,1998,1999,2000,2002,2003,2006 - Free Software Foundation, Inc. +/* Copyright (C) 1997, 1998, 1999, 2000, 2002, 2003 + Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. @@ -25,7 +25,7 @@ #include <sys/syscall.h> #include <bp-checks.h> -#include <kernel-features.h> +#include "kernel-features.h" #if defined __NR_pwrite || __ASSUME_PWRITE_SYSCALL > 0 diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext-common.S b/sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext-common.S deleted file mode 100644 index 40a7a24f19..0000000000 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext-common.S +++ /dev/null @@ -1,293 +0,0 @@ -/* Jump to a new context powerpc32 common. - Copyright (C) 2005, 2006 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., 51 Franklin Street, Fifth Floor, Boston MA - 02110-1301 USA. */ - -/* This is the common implementation of setcontext for powerpc32. - It not complete in itself should be included in to a framework that - defines: - __CONTEXT_FUNC_NAME - and if appropriate: - __CONTEXT_ENABLE_FPRS - __CONTEXT_ENABLE_VRS - Any archecture that implements the Vector unit is assumed to also - implement the floating unit. */ - -/* Stack frame offsets. */ -#define _FRAME_BACKCHAIN 0 -#define _FRAME_LR_SAVE 4 -#define _FRAME_PARM_SAVE1 8 -#define _FRAME_PARM_SAVE2 12 -#define _FRAME_PARM_SAVE3 16 -#define _FRAME_PARM_SAVE4 20 - -#ifdef __CONTEXT_ENABLE_VRS - .machine "altivec" -#endif -ENTRY(__CONTEXT_FUNC_NAME) - mflr r0 - stwu r1,-16(r1) - cfi_adjust_cfa_offset (16) - stw r0,20(r1) - cfi_offset (lr, _FRAME_LR_SAVE) - stw r31,12(r1) - cfi_offset(r31,-4) - lwz r31,_UC_REGS_PTR(r3) - - /* - * If this ucontext refers to the point where we were interrupted - * by a signal, we have to use the rt_sigreturn system call to - * return to the context so we get both LR and CTR restored. - * - * Otherwise, the context we are restoring is either just after - * a procedure call (getcontext/swapcontext) or at the beginning - * of a procedure call (makecontext), so we don't need to restore - * r0, xer, ctr. We don't restore r2 since it will be used as - * the TLS pointer. - */ - lwz r0,_UC_GREGS+(PT_MSR*4)(r31) - cmpwi r0,0 - bne 4f /* L(do_sigret) */ - - /* Restore the signal mask */ - li r5,0 - addi r4,r3,_UC_SIGMASK - li r3,SIG_SETMASK - bl __sigprocmask@local - cmpwi r3,0 - bne 3f /* L(error_exit) */ - -#ifdef __CONTEXT_ENABLE_FPRS -# ifdef __CONTEXT_ENABLE_VRS -# ifdef PIC - mflr r8 -# ifdef HAVE_ASM_PPC_REL16 - bcl 20,31,1f -1: mflr r7 - addis r7,r7,_GLOBAL_OFFSET_TABLE_-1b@ha - addi r7,r7,_GLOBAL_OFFSET_TABLE_-1b@l -# else - bl _GLOBAL_OFFSET_TABLE_@local-4 - mflr r7 -# endif -# ifdef SHARED - lwz r7,_rtld_global_ro@got(r7) - mtlr r8 - lwz r7,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r7) -# else - lwz r7,_dl_hwcap@got(r7) - mtlr r8 - lwz r7,0(r7) -# endif -# else - lis r7,_dl_hwcap@ha - lwz r7,_dl_hwcap@l(r7) -# endif - andis. r7,r7,(PPC_FEATURE_HAS_ALTIVEC >> 16) - la r10,(_UC_VREGS)(r31) - beq 2f /* L(has_no_vec) */ - - lwz r0,(32*16)(r10) - li r9,(32*16) - cmpwi r0,0 - mtspr VRSAVE,r0 - beq 2f /* L(has_no_vec) */ - - lvx v19,r9,r10 - la r9,(16)(r10) - - lvx v0,0,r10 - lvx v1,0,r9 - addi r10,r10,32 - addi r9,r9,32 - - mtvscr v19 - lvx v2,0,r10 - lvx v3,0,r9 - addi r10,r10,32 - addi r9,r9,32 - - lvx v4,0,r10 - lvx v5,0,r9 - addi r10,r10,32 - addi r9,r9,32 - - lvx v6,0,r10 - lvx v7,0,r9 - addi r10,r10,32 - addi r9,r9,32 - - lvx v8,0,r10 - lvx v9,0,r9 - addi r10,r10,32 - addi r9,r9,32 - - lvx v10,0,r10 - lvx v11,0,r9 - addi r10,r10,32 - addi r9,r9,32 - - lvx v12,0,r10 - lvx v13,0,r9 - addi r10,r10,32 - addi r9,r9,32 - - lvx v14,0,r10 - lvx v15,0,r9 - addi r10,r10,32 - addi r9,r9,32 - - lvx v16,0,r10 - lvx v17,0,r9 - addi r10,r10,32 - addi r9,r9,32 - - lvx v18,0,r10 - lvx v19,0,r9 - addi r10,r10,32 - addi r9,r9,32 - - lvx v20,0,r10 - lvx v21,0,r9 - addi r10,r10,32 - addi r9,r9,32 - - lvx v22,0,r10 - lvx v23,0,r9 - addi r10,r10,32 - addi r9,r9,32 - - lvx v24,0,r10 - lvx v25,0,r9 - addi r10,r10,32 - addi r9,r9,32 - - lvx v26,0,r10 - lvx v27,0,r9 - addi r10,r10,32 - addi r9,r9,32 - - lvx v28,0,r10 - lvx v29,0,r9 - addi r10,r10,32 - addi r9,r9,32 - - lvx v30,0,r10 - lvx v31,0,r9 - addi r10,r10,32 - addi r9,r9,32 - - lvx v10,0,r10 - lvx v11,0,r9 - -2: /* L(has_no_vec): */ -# endif /* __CONTEXT_ENABLE_VRS */ - /* Restore the floating-point registers */ - lfd fp31,_UC_FREGS+(32*8)(r31) - lfd fp0,_UC_FREGS+(0*8)(r31) - mtfsf 0xff,fp31 - lfd fp1,_UC_FREGS+(1*8)(r31) - lfd fp2,_UC_FREGS+(2*8)(r31) - lfd fp3,_UC_FREGS+(3*8)(r31) - lfd fp4,_UC_FREGS+(4*8)(r31) - lfd fp5,_UC_FREGS+(5*8)(r31) - lfd fp6,_UC_FREGS+(6*8)(r31) - lfd fp7,_UC_FREGS+(7*8)(r31) - lfd fp8,_UC_FREGS+(8*8)(r31) - lfd fp9,_UC_FREGS+(9*8)(r31) - lfd fp10,_UC_FREGS+(10*8)(r31) - lfd fp11,_UC_FREGS+(11*8)(r31) - lfd fp12,_UC_FREGS+(12*8)(r31) - lfd fp13,_UC_FREGS+(13*8)(r31) - lfd fp14,_UC_FREGS+(14*8)(r31) - lfd fp15,_UC_FREGS+(15*8)(r31) - lfd fp16,_UC_FREGS+(16*8)(r31) - lfd fp17,_UC_FREGS+(17*8)(r31) - lfd fp18,_UC_FREGS+(18*8)(r31) - lfd fp19,_UC_FREGS+(19*8)(r31) - lfd fp20,_UC_FREGS+(20*8)(r31) - lfd fp21,_UC_FREGS+(21*8)(r31) - lfd fp22,_UC_FREGS+(22*8)(r31) - lfd fp23,_UC_FREGS+(23*8)(r31) - lfd fp24,_UC_FREGS+(24*8)(r31) - lfd fp25,_UC_FREGS+(25*8)(r31) - lfd fp26,_UC_FREGS+(26*8)(r31) - lfd fp27,_UC_FREGS+(27*8)(r31) - lfd fp28,_UC_FREGS+(28*8)(r31) - lfd fp29,_UC_FREGS+(29*8)(r31) - lfd fp30,_UC_FREGS+(30*8)(r31) - lfd fp31,_UC_FREGS+(31*8)(r31) -#endif /* __CONTEXT_ENABLE_FPRS */ - - /* Restore LR and CCR, and set CTR to the NIP value */ - lwz r3,_UC_GREGS+(PT_LNK*4)(r31) - lwz r4,_UC_GREGS+(PT_NIP*4)(r31) - lwz r5,_UC_GREGS+(PT_CCR*4)(r31) - mtlr r3 - mtctr r4 - mtcr r5 - - /* Restore the general registers */ - lwz r1,_UC_GREGS+(PT_R1*4)(r31) - lwz r3,_UC_GREGS+(PT_R3*4)(r31) - lwz r4,_UC_GREGS+(PT_R4*4)(r31) - lwz r5,_UC_GREGS+(PT_R5*4)(r31) - lwz r6,_UC_GREGS+(PT_R6*4)(r31) - lwz r7,_UC_GREGS+(PT_R7*4)(r31) - lwz r8,_UC_GREGS+(PT_R8*4)(r31) - lwz r9,_UC_GREGS+(PT_R9*4)(r31) - lwz r10,_UC_GREGS+(PT_R10*4)(r31) - lwz r11,_UC_GREGS+(PT_R11*4)(r31) - lwz r12,_UC_GREGS+(PT_R12*4)(r31) - lwz r13,_UC_GREGS+(PT_R13*4)(r31) - lwz r14,_UC_GREGS+(PT_R14*4)(r31) - lwz r15,_UC_GREGS+(PT_R15*4)(r31) - lwz r16,_UC_GREGS+(PT_R16*4)(r31) - lwz r17,_UC_GREGS+(PT_R17*4)(r31) - lwz r18,_UC_GREGS+(PT_R18*4)(r31) - lwz r19,_UC_GREGS+(PT_R19*4)(r31) - lwz r20,_UC_GREGS+(PT_R20*4)(r31) - lwz r21,_UC_GREGS+(PT_R21*4)(r31) - lwz r22,_UC_GREGS+(PT_R22*4)(r31) - lwz r23,_UC_GREGS+(PT_R23*4)(r31) - lwz r24,_UC_GREGS+(PT_R24*4)(r31) - lwz r25,_UC_GREGS+(PT_R25*4)(r31) - lwz r26,_UC_GREGS+(PT_R26*4)(r31) - lwz r27,_UC_GREGS+(PT_R27*4)(r31) - lwz r28,_UC_GREGS+(PT_R28*4)(r31) - lwz r29,_UC_GREGS+(PT_R29*4)(r31) - lwz r30,_UC_GREGS+(PT_R30*4)(r31) - lwz r31,_UC_GREGS+(PT_R31*4)(r31) - - bctr - -3: /* L(error_exit): */ - lwz r31,12(r1) - lwz r0,20(r1) - addi r1,r1,16 - mtlr r0 - blr - - -4: /* L(do_sigret): */ - addi r1,r3,-0xd0 - li r0,SYS_ify(rt_sigreturn) - sc - /* NOTREACHED */ - -END (__CONTEXT_FUNC_NAME) - diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext.S b/sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext.S index 1f2e250057..2d4fa9910e 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext.S +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext.S @@ -1,5 +1,5 @@ /* Jump to a new context. - Copyright (C) 2002, 2004, 2005, 2006 Free Software Foundation, Inc. + Copyright (C) 2002, 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 @@ -14,55 +14,383 @@ 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., 51 Franklin Street, Fifth Floor, Boston MA - 02110-1301 USA. */ + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ #include <sysdep.h> #include <rtld-global-offsets.h> #include <shlib-compat.h> -#include <kernel-features.h> #define __ASSEMBLY__ #include <asm/ptrace.h> #include "ucontext_i.h" -#define __CONTEXT_FUNC_NAME __setcontext -#define __CONTEXT_ENABLE_FPRS 1 -#define __CONTEXT_ENABLE_VRS 1 - -/* Size of ucontext in GLIBC_2.3.4 and later. */ -#define _UC_SIZE_2_3_4 1184 - -#ifdef __ASSUME_SWAPCONTEXT_SYSCALL - .section ".text"; -ENTRY (__setcontext) - mr r4,r3 - li r3,0 - li r5,_UC_SIZE_2_3_4; - DO_CALL (SYS_ify (swapcontext)); - bso- cr0,1f -/* the kernel does not set the return code for the success case */ - li r3,0 - blr -1: - b __syscall_error@local -END(__setcontext) + .machine "altivec" +ENTRY(__setcontext) + mflr r0 + stwu r1,-16(r1) + stw r0,20(r1) + stw r31,12(r1) + lwz r31,_UC_REGS_PTR(r3) + + /* + * If this ucontext refers to the point where we were interrupted + * by a signal, we have to use the rt_sigreturn system call to + * return to the context so we get both LR and CTR restored. + * + * Otherwise, the context we are restoring is either just after + * a procedure call (getcontext/swapcontext) or at the beginning + * of a procedure call (makecontext), so we don't need to restore + * r0, xer, ctr. We don't restore r2 since it will be used as + * the TLS pointer. + */ + lwz r0,_UC_GREGS+(PT_MSR*4)(r31) + cmpwi r0,0 + bne L(do_sigret) + + /* Restore the signal mask */ + li r5,0 + addi r4,r3,_UC_SIGMASK + li r3,SIG_SETMASK + bl JUMPTARGET(__sigprocmask) + cmpwi r3,0 + bne L(error_exit) + +#ifdef PIC + mflr r8 + bl _GLOBAL_OFFSET_TABLE_@local-4 + mflr r7 +# ifdef SHARED + lwz r7,_rtld_global_ro@got(r7) + mtlr r8 + lwz r7,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r7) +# else + lwz r7,_dl_hwcap@got(r7) + mtlr r8 + lwz r7,0(r7) +# endif #else -# include "setcontext-common.S" + lis r7,_dl_hwcap@ha + lwz r7,_dl_hwcap@l(r7) #endif + andis. r7,r7,(PPC_FEATURE_HAS_ALTIVEC >> 16) + la r10,(_UC_VREGS)(r31) + beq L(has_no_vec) + + lwz r0,(32*16)(r10) + li r9,(32*16) + cmpwi r0,0 + mtspr VRSAVE,r0 + beq L(has_no_vec) + + lvx v19,r9,r10 + la r9,(16)(r10) + + lvx v0,0,r10 + lvx v1,0,r9 + addi r10,r10,32 + addi r9,r9,32 + + mtvscr v19 + lvx v2,0,r10 + lvx v3,0,r9 + addi r10,r10,32 + addi r9,r9,32 + + lvx v4,0,r10 + lvx v5,0,r9 + addi r10,r10,32 + addi r9,r9,32 + + lvx v6,0,r10 + lvx v7,0,r9 + addi r10,r10,32 + addi r9,r9,32 + + lvx v8,0,r10 + lvx v9,0,r9 + addi r10,r10,32 + addi r9,r9,32 + + lvx v10,0,r10 + lvx v11,0,r9 + addi r10,r10,32 + addi r9,r9,32 + + lvx v12,0,r10 + lvx v13,0,r9 + addi r10,r10,32 + addi r9,r9,32 + + lvx v14,0,r10 + lvx v15,0,r9 + addi r10,r10,32 + addi r9,r9,32 + + lvx v16,0,r10 + lvx v17,0,r9 + addi r10,r10,32 + addi r9,r9,32 + + lvx v18,0,r10 + lvx v19,0,r9 + addi r10,r10,32 + addi r9,r9,32 + + lvx v20,0,r10 + lvx v21,0,r9 + addi r10,r10,32 + addi r9,r9,32 + + lvx v22,0,r10 + lvx v23,0,r9 + addi r10,r10,32 + addi r9,r9,32 + + lvx v24,0,r10 + lvx v25,0,r9 + addi r10,r10,32 + addi r9,r9,32 + + lvx v26,0,r10 + lvx v27,0,r9 + addi r10,r10,32 + addi r9,r9,32 + + lvx v28,0,r10 + lvx v29,0,r9 + addi r10,r10,32 + addi r9,r9,32 + + lvx v30,0,r10 + lvx v31,0,r9 + addi r10,r10,32 + addi r9,r9,32 + + lvx v10,0,r10 + lvx v11,0,r9 + +L(has_no_vec): + /* Restore the floating-point registers */ + lfd fp31,_UC_FREGS+(32*8)(r31) + lfd fp0,_UC_FREGS+(0*8)(r31) + mtfsf 0xff,fp31 + lfd fp1,_UC_FREGS+(1*8)(r31) + lfd fp2,_UC_FREGS+(2*8)(r31) + lfd fp3,_UC_FREGS+(3*8)(r31) + lfd fp4,_UC_FREGS+(4*8)(r31) + lfd fp5,_UC_FREGS+(5*8)(r31) + lfd fp6,_UC_FREGS+(6*8)(r31) + lfd fp7,_UC_FREGS+(7*8)(r31) + lfd fp8,_UC_FREGS+(8*8)(r31) + lfd fp9,_UC_FREGS+(9*8)(r31) + lfd fp10,_UC_FREGS+(10*8)(r31) + lfd fp11,_UC_FREGS+(11*8)(r31) + lfd fp12,_UC_FREGS+(12*8)(r31) + lfd fp13,_UC_FREGS+(13*8)(r31) + lfd fp14,_UC_FREGS+(14*8)(r31) + lfd fp15,_UC_FREGS+(15*8)(r31) + lfd fp16,_UC_FREGS+(16*8)(r31) + lfd fp17,_UC_FREGS+(17*8)(r31) + lfd fp18,_UC_FREGS+(18*8)(r31) + lfd fp19,_UC_FREGS+(19*8)(r31) + lfd fp20,_UC_FREGS+(20*8)(r31) + lfd fp21,_UC_FREGS+(21*8)(r31) + lfd fp22,_UC_FREGS+(22*8)(r31) + lfd fp23,_UC_FREGS+(23*8)(r31) + lfd fp24,_UC_FREGS+(24*8)(r31) + lfd fp25,_UC_FREGS+(25*8)(r31) + lfd fp26,_UC_FREGS+(26*8)(r31) + lfd fp27,_UC_FREGS+(27*8)(r31) + lfd fp28,_UC_FREGS+(28*8)(r31) + lfd fp29,_UC_FREGS+(29*8)(r31) + lfd fp30,_UC_FREGS+(30*8)(r31) + lfd fp31,_UC_FREGS+(31*8)(r31) + + /* Restore LR and CCR, and set CTR to the NIP value */ + lwz r3,_UC_GREGS+(PT_LNK*4)(r31) + lwz r4,_UC_GREGS+(PT_NIP*4)(r31) + lwz r5,_UC_GREGS+(PT_CCR*4)(r31) + mtlr r3 + mtctr r4 + mtcr r5 + + /* Restore the general registers */ + lwz r1,_UC_GREGS+(PT_R1*4)(r31) + lwz r3,_UC_GREGS+(PT_R3*4)(r31) + lwz r4,_UC_GREGS+(PT_R4*4)(r31) + lwz r5,_UC_GREGS+(PT_R5*4)(r31) + lwz r6,_UC_GREGS+(PT_R6*4)(r31) + lwz r7,_UC_GREGS+(PT_R7*4)(r31) + lwz r8,_UC_GREGS+(PT_R8*4)(r31) + lwz r9,_UC_GREGS+(PT_R9*4)(r31) + lwz r10,_UC_GREGS+(PT_R10*4)(r31) + lwz r11,_UC_GREGS+(PT_R11*4)(r31) + lwz r12,_UC_GREGS+(PT_R12*4)(r31) + lwz r13,_UC_GREGS+(PT_R13*4)(r31) + lwz r14,_UC_GREGS+(PT_R14*4)(r31) + lwz r15,_UC_GREGS+(PT_R15*4)(r31) + lwz r16,_UC_GREGS+(PT_R16*4)(r31) + lwz r17,_UC_GREGS+(PT_R17*4)(r31) + lwz r18,_UC_GREGS+(PT_R18*4)(r31) + lwz r19,_UC_GREGS+(PT_R19*4)(r31) + lwz r20,_UC_GREGS+(PT_R20*4)(r31) + lwz r21,_UC_GREGS+(PT_R21*4)(r31) + lwz r22,_UC_GREGS+(PT_R22*4)(r31) + lwz r23,_UC_GREGS+(PT_R23*4)(r31) + lwz r24,_UC_GREGS+(PT_R24*4)(r31) + lwz r25,_UC_GREGS+(PT_R25*4)(r31) + lwz r26,_UC_GREGS+(PT_R26*4)(r31) + lwz r27,_UC_GREGS+(PT_R27*4)(r31) + lwz r28,_UC_GREGS+(PT_R28*4)(r31) + lwz r29,_UC_GREGS+(PT_R29*4)(r31) + lwz r30,_UC_GREGS+(PT_R30*4)(r31) + lwz r31,_UC_GREGS+(PT_R31*4)(r31) + + bctr + +L(error_exit): + lwz r31,12(r1) + lwz r0,20(r1) + addi r1,r1,16 + mtlr r0 + blr + +L(do_sigret): + addi r1,r3,-0xd0 + li r0,SYS_ify(rt_sigreturn) + sc + /* NOTREACHED */ + +END (__setcontext) versioned_symbol (libc, __setcontext, setcontext, GLIBC_2_3_4) #if SHLIB_COMPAT (libc, GLIBC_2_3_3, GLIBC_2_3_4) compat_text_section - -# undef __CONTEXT_FUNC_NAME -# define __CONTEXT_FUNC_NAME __novec_setcontext -# undef __CONTEXT_ENABLE_VRS +ENTRY(__novec_setcontext) + mflr r0 + stwu r1,-16(r1) + stw r0,20(r1) + stw r31,12(r1) + lwz r31,_UC_REGS_PTR(r3) + + /* + * If this ucontext refers to the point where we were interrupted + * by a signal, we have to use the rt_sigreturn system call to + * return to the context so we get both LR and CTR restored. + * + * Otherwise, the context we are restoring is either just after + * a procedure call (getcontext/swapcontext) or at the beginning + * of a procedure call (makecontext), so we don't need to restore + * r0, xer, ctr. We don't restore r2 since it will be used as + * the TLS pointer. + */ + lwz r0,_UC_GREGS+(PT_MSR*4)(r31) + cmpwi r0,0 + bne L(novec_do_sigret) + + /* Restore the signal mask */ + li r5,0 + addi r4,r3,_UC_SIGMASK + li r3,SIG_SETMASK + bl JUMPTARGET(__sigprocmask) + cmpwi r3,0 + bne L(novec_error_exit) + + /* Restore the floating-point registers */ + lfd fp31,_UC_FREGS+(32*8)(r31) + lfd fp0,_UC_FREGS+(0*8)(r31) + mtfsf 0xff,fp31 + lfd fp1,_UC_FREGS+(1*8)(r31) + lfd fp2,_UC_FREGS+(2*8)(r31) + lfd fp3,_UC_FREGS+(3*8)(r31) + lfd fp4,_UC_FREGS+(4*8)(r31) + lfd fp5,_UC_FREGS+(5*8)(r31) + lfd fp6,_UC_FREGS+(6*8)(r31) + lfd fp7,_UC_FREGS+(7*8)(r31) + lfd fp8,_UC_FREGS+(8*8)(r31) + lfd fp9,_UC_FREGS+(9*8)(r31) + lfd fp10,_UC_FREGS+(10*8)(r31) + lfd fp11,_UC_FREGS+(11*8)(r31) + lfd fp12,_UC_FREGS+(12*8)(r31) + lfd fp13,_UC_FREGS+(13*8)(r31) + lfd fp14,_UC_FREGS+(14*8)(r31) + lfd fp15,_UC_FREGS+(15*8)(r31) + lfd fp16,_UC_FREGS+(16*8)(r31) + lfd fp17,_UC_FREGS+(17*8)(r31) + lfd fp18,_UC_FREGS+(18*8)(r31) + lfd fp19,_UC_FREGS+(19*8)(r31) + lfd fp20,_UC_FREGS+(20*8)(r31) + lfd fp21,_UC_FREGS+(21*8)(r31) + lfd fp22,_UC_FREGS+(22*8)(r31) + lfd fp23,_UC_FREGS+(23*8)(r31) + lfd fp24,_UC_FREGS+(24*8)(r31) + lfd fp25,_UC_FREGS+(25*8)(r31) + lfd fp26,_UC_FREGS+(26*8)(r31) + lfd fp27,_UC_FREGS+(27*8)(r31) + lfd fp28,_UC_FREGS+(28*8)(r31) + lfd fp29,_UC_FREGS+(29*8)(r31) + lfd fp30,_UC_FREGS+(30*8)(r31) + lfd fp31,_UC_FREGS+(31*8)(r31) + + /* Restore LR and CCR, and set CTR to the NIP value */ + lwz r3,_UC_GREGS+(PT_LNK*4)(r31) + lwz r4,_UC_GREGS+(PT_NIP*4)(r31) + lwz r5,_UC_GREGS+(PT_CCR*4)(r31) + mtlr r3 + mtctr r4 + mtcr r5 + + /* Restore the general registers */ + lwz r1,_UC_GREGS+(PT_R1*4)(r31) + lwz r3,_UC_GREGS+(PT_R3*4)(r31) + lwz r4,_UC_GREGS+(PT_R4*4)(r31) + lwz r5,_UC_GREGS+(PT_R5*4)(r31) + lwz r6,_UC_GREGS+(PT_R6*4)(r31) + lwz r7,_UC_GREGS+(PT_R7*4)(r31) + lwz r8,_UC_GREGS+(PT_R8*4)(r31) + lwz r9,_UC_GREGS+(PT_R9*4)(r31) + lwz r10,_UC_GREGS+(PT_R10*4)(r31) + lwz r11,_UC_GREGS+(PT_R11*4)(r31) + lwz r12,_UC_GREGS+(PT_R12*4)(r31) + lwz r13,_UC_GREGS+(PT_R13*4)(r31) + lwz r14,_UC_GREGS+(PT_R14*4)(r31) + lwz r15,_UC_GREGS+(PT_R15*4)(r31) + lwz r16,_UC_GREGS+(PT_R16*4)(r31) + lwz r17,_UC_GREGS+(PT_R17*4)(r31) + lwz r18,_UC_GREGS+(PT_R18*4)(r31) + lwz r19,_UC_GREGS+(PT_R19*4)(r31) + lwz r20,_UC_GREGS+(PT_R20*4)(r31) + lwz r21,_UC_GREGS+(PT_R21*4)(r31) + lwz r22,_UC_GREGS+(PT_R22*4)(r31) + lwz r23,_UC_GREGS+(PT_R23*4)(r31) + lwz r24,_UC_GREGS+(PT_R24*4)(r31) + lwz r25,_UC_GREGS+(PT_R25*4)(r31) + lwz r26,_UC_GREGS+(PT_R26*4)(r31) + lwz r27,_UC_GREGS+(PT_R27*4)(r31) + lwz r28,_UC_GREGS+(PT_R28*4)(r31) + lwz r29,_UC_GREGS+(PT_R29*4)(r31) + lwz r30,_UC_GREGS+(PT_R30*4)(r31) + lwz r31,_UC_GREGS+(PT_R31*4)(r31) + + bctr + +L(novec_error_exit): + lwz r31,12(r1) + lwz r0,20(r1) + addi r1,r1,16 + mtlr r0 + blr -# include "setcontext-common.S" +L(novec_do_sigret): + addi r1,r3,-0xd0 + li r0,SYS_ify(rt_sigreturn) + sc + /* NOTREACHED */ +END (__novec_setcontext) .previous compat_symbol (libc, __novec_setcontext, setcontext, GLIBC_2_3_3) @@ -71,13 +399,13 @@ compat_symbol (libc, __novec_setcontext, setcontext, GLIBC_2_3_3) #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_3) -# define _ERRNO_H 1 -# include <bits/errno.h> +#define _ERRNO_H 1 +#include <bits/errno.h> compat_text_section ENTRY (__setcontext_stub) li r3,ENOSYS - b __syscall_error@local + b JUMPTARGET(__syscall_error) END (__setcontext_stub) .previous diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/socket.S b/sysdeps/unix/sysv/linux/powerpc/powerpc32/socket.S index 0bb5bef78b..c52ad9babf 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/socket.S +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/socket.S @@ -1,4 +1,4 @@ -/* Copyright (C) 1995,96,97,99, 2003, 2006 Free Software Foundation, Inc. +/* Copyright (C) 1995, 1996, 1997, 1999, 2003 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 @@ -13,8 +13,8 @@ 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., 51 Franklin Street, Fifth Floor, Boston MA - 02110-1301 USA. */ + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ #include <sysdep-cancel.h> #include <socketcall.h> @@ -39,20 +39,15 @@ #define NARGS 3 #endif -/* 0(r1) and 4(r1) are reserved by the ABI, 8(r1), 12(r1), 16(r1) are used - for temp saves. 44(r1) is used to save r30. */ #define stackblock 20 #ifndef __socket -# ifndef NO_WEAK_ALIAS -# define __socket P(__,socket) -# else -# define __socket socket -# endif +#define __socket P(__,socket) #endif .text ENTRY(__socket) + cfi_startproc stwu r1,-48(r1) cfi_adjust_cfa_offset(48) #if NARGS >= 1 @@ -74,6 +69,12 @@ ENTRY(__socket) stw r8,20+stackblock(r1) #endif #if NARGS >= 7 + stw r9,24+stackblock(r1) +#endif +#if NARGS >= 8 + stw r10,28+stackblock(r1) +#endif +#if NARGS >= 9 #error too many arguments! #endif @@ -93,7 +94,6 @@ ENTRY(__socket) mflr r9 stw r9,52(r1) cfi_offset (lr, 4) - CGOTSETUP CENABLE stw r3,16(r1) li r3,P(SOCKOP_,socket) @@ -107,15 +107,13 @@ ENTRY(__socket) lwz r4,52(r1) lwz r0,12(r1) lwz r3,8(r1) - CGOTRESTORE mtlr r4 mtcr r0 addi r1,r1,48 PSEUDO_RET #endif + cfi_endproc PSEUDO_END (__socket) -#ifndef NO_WEAK_ALIAS weak_alias (__socket, socket) -#endif diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/swapcontext-common.S b/sysdeps/unix/sysv/linux/powerpc/powerpc32/swapcontext-common.S deleted file mode 100644 index 0c7b945ed2..0000000000 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/swapcontext-common.S +++ /dev/null @@ -1,517 +0,0 @@ -/* Save current context and jump to a new context. - Copyright (C) 2005, 2006 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., 51 Franklin Street, Fifth Floor, Boston MA - 02110-1301 USA. */ - -/* This is the common implementation of setcontext for powerpc32. - It not complete in itself should be included in to a framework that - defines: - __CONTEXT_FUNC_NAME - and if appropriate: - __CONTEXT_ENABLE_FPRS - __CONTEXT_ENABLE_VRS - Any archecture that implements the Vector unit is assumed to also - implement the floating unit. */ - -/* Stack frame offsets. */ -#define _FRAME_BACKCHAIN 0 -#define _FRAME_LR_SAVE 4 -#define _FRAME_PARM_SAVE1 8 -#define _FRAME_PARM_SAVE2 12 -#define _FRAME_PARM_SAVE3 16 -#define _FRAME_PARM_SAVE4 20 - -#ifdef __CONTEXT_ENABLE_VRS - .machine "altivec" -#endif -ENTRY(__CONTEXT_FUNC_NAME) - stwu r1,-16(r1) - cfi_adjust_cfa_offset (16) -/* Insure that the _UC_REGS start on a quadword boundary. */ - stw r3,_FRAME_PARM_SAVE1(r1) - addi r3,r3,_UC_REG_SPACE+12 - stw r4,_FRAME_PARM_SAVE2(r1) /* new context pointer */ - clrrwi r3,r3,4 - -/* Save the general purpose registers */ - stw r0,_UC_GREGS+(PT_R0*4)(r3) - mflr r0 - stw r2,_UC_GREGS+(PT_R2*4)(r3) - stw r4,_UC_GREGS+(PT_R4*4)(r3) -/* Set the callers LR_SAVE, and the ucontext LR and NIP to the callers - return address. */ - stw r0,_UC_GREGS+(PT_LNK*4)(r3) - stw r0,_UC_GREGS+(PT_NIP*4)(r3) - stw r0,_FRAME_LR_SAVE+16(r1) - cfi_offset (lr, _FRAME_LR_SAVE) - stw r5,_UC_GREGS+(PT_R5*4)(r3) - stw r6,_UC_GREGS+(PT_R6*4)(r3) - stw r7,_UC_GREGS+(PT_R7*4)(r3) - stw r8,_UC_GREGS+(PT_R8*4)(r3) - stw r9,_UC_GREGS+(PT_R9*4)(r3) - stw r10,_UC_GREGS+(PT_R10*4)(r3) - stw r11,_UC_GREGS+(PT_R11*4)(r3) - stw r12,_UC_GREGS+(PT_R12*4)(r3) - stw r13,_UC_GREGS+(PT_R13*4)(r3) - stw r14,_UC_GREGS+(PT_R14*4)(r3) - stw r15,_UC_GREGS+(PT_R15*4)(r3) - stw r16,_UC_GREGS+(PT_R16*4)(r3) - stw r17,_UC_GREGS+(PT_R17*4)(r3) - stw r18,_UC_GREGS+(PT_R18*4)(r3) - stw r19,_UC_GREGS+(PT_R19*4)(r3) - stw r20,_UC_GREGS+(PT_R20*4)(r3) - stw r21,_UC_GREGS+(PT_R21*4)(r3) - stw r22,_UC_GREGS+(PT_R22*4)(r3) - stw r23,_UC_GREGS+(PT_R23*4)(r3) - stw r24,_UC_GREGS+(PT_R24*4)(r3) - stw r25,_UC_GREGS+(PT_R25*4)(r3) - stw r26,_UC_GREGS+(PT_R26*4)(r3) - stw r27,_UC_GREGS+(PT_R27*4)(r3) - stw r28,_UC_GREGS+(PT_R28*4)(r3) - stw r29,_UC_GREGS+(PT_R29*4)(r3) - stw r30,_UC_GREGS+(PT_R30*4)(r3) - stw r31,_UC_GREGS+(PT_R31*4)(r3) - -/* Save the value of R1. We had to push the stack before we - had the address of uc_reg_space. So compute the address of - the callers stack pointer and save it as R1. */ - addi r8,r1,16 - li r0,0 -/* Save the count, exception and condition registers. */ - mfctr r11 - mfxer r10 - mfcr r9 - stw r8,_UC_GREGS+(PT_R1*4)(r3) - stw r11,_UC_GREGS+(PT_CTR*4)(r3) - stw r10,_UC_GREGS+(PT_XER*4)(r3) - stw r9,_UC_GREGS+(PT_CCR*4)(r3) -/* Set the return value of getcontext to "success". R3 is the only - register whose value is not preserved in the saved context. */ - stw r0,_UC_GREGS+(PT_R3*4)(r3) - - /* Zero fill fields that can't be set in user state. */ - stw r0,_UC_GREGS+(PT_MSR*4)(r3) - stw r0,_UC_GREGS+(PT_MQ*4)(r3) - -#ifdef __CONTEXT_ENABLE_FPRS - /* Save the floating-point registers */ - stfd fp0,_UC_FREGS+(0*8)(r3) - stfd fp1,_UC_FREGS+(1*8)(r3) - stfd fp2,_UC_FREGS+(2*8)(r3) - stfd fp3,_UC_FREGS+(3*8)(r3) - stfd fp4,_UC_FREGS+(4*8)(r3) - stfd fp5,_UC_FREGS+(5*8)(r3) - stfd fp6,_UC_FREGS+(6*8)(r3) - stfd fp7,_UC_FREGS+(7*8)(r3) - stfd fp8,_UC_FREGS+(8*8)(r3) - stfd fp9,_UC_FREGS+(9*8)(r3) - stfd fp10,_UC_FREGS+(10*8)(r3) - stfd fp11,_UC_FREGS+(11*8)(r3) - stfd fp12,_UC_FREGS+(12*8)(r3) - stfd fp13,_UC_FREGS+(13*8)(r3) - stfd fp14,_UC_FREGS+(14*8)(r3) - stfd fp15,_UC_FREGS+(15*8)(r3) - stfd fp16,_UC_FREGS+(16*8)(r3) - stfd fp17,_UC_FREGS+(17*8)(r3) - stfd fp18,_UC_FREGS+(18*8)(r3) - stfd fp19,_UC_FREGS+(19*8)(r3) - stfd fp20,_UC_FREGS+(20*8)(r3) - stfd fp21,_UC_FREGS+(21*8)(r3) - stfd fp22,_UC_FREGS+(22*8)(r3) - stfd fp23,_UC_FREGS+(23*8)(r3) - stfd fp24,_UC_FREGS+(24*8)(r3) - stfd fp25,_UC_FREGS+(25*8)(r3) - stfd fp26,_UC_FREGS+(26*8)(r3) - stfd fp27,_UC_FREGS+(27*8)(r3) - stfd fp28,_UC_FREGS+(28*8)(r3) - stfd fp29,_UC_FREGS+(29*8)(r3) - mffs fp0 - stfd fp30,_UC_FREGS+(30*8)(r3) - stfd fp31,_UC_FREGS+(31*8)(r3) - stfd fp0,_UC_FREGS+(32*8)(r3) - -# ifdef __CONTEXT_ENABLE_VRS -# ifdef PIC - mflr r8 -# ifdef HAVE_ASM_PPC_REL16 - bcl 20,31,1f -1: mflr r7 - addis r7,r7,_GLOBAL_OFFSET_TABLE_-1b@ha - addi r7,r7,_GLOBAL_OFFSET_TABLE_-1b@l -# else - bl _GLOBAL_OFFSET_TABLE_@local-4 - mflr r7 -# endif -# ifdef SHARED - lwz r7,_rtld_global_ro@got(r7) - mtlr r8 - lwz r7,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r7) -# else - lwz r7,_dl_hwcap@got(r7) - mtlr r8 - lwz r7,0(r7) -# endif -# else - lis r7,_dl_hwcap@ha - lwz r7,_dl_hwcap@l(r7) -# endif - andis. r7,r7,(PPC_FEATURE_HAS_ALTIVEC >> 16) - - la r10,(_UC_VREGS)(r3) - la r9,(_UC_VREGS+16)(r3) - -/* beq L(no_vec)*/ - beq 2f -/* address of the combined VSCR/VSAVE quadword. */ - la r8,(_UC_VREGS+512)(r3) - -/* Save the vector registers */ - stvx v0,0,r10 - stvx v1,0,r9 - addi r10,r10,32 - addi r9,r9,32 -/* We need to get the Vector Status and Control Register early to avoid - store order problems later with the VSAVE register that shares the - same quadword. */ - mfvscr v0 - - stvx v2,0,r10 - stvx v3,0,r9 - addi r10,r10,32 - addi r9,r9,32 - - stvx v0,0,r8 - - stvx v4,0,r10 - stvx v5,0,r9 - addi r10,r10,32 - addi r9,r9,32 - - stvx v6,0,r10 - stvx v7,0,r9 - addi r10,r10,32 - addi r9,r9,32 - - stvx v8,0,r10 - stvx v9,0,r9 - addi r10,r10,32 - addi r9,r9,32 - - stvx v10,0,r10 - stvx v11,0,r9 - addi r10,r10,32 - addi r9,r9,32 - - stvx v12,0,r10 - stvx v13,0,r9 - addi r10,r10,32 - addi r9,r9,32 - - stvx v14,0,r10 - stvx v15,0,r9 - addi r10,r10,32 - addi r9,r9,32 - - stvx v16,0,r10 - stvx v17,0,r9 - addi r10,r10,32 - addi r9,r9,32 - - stvx v18,0,r10 - stvx v19,0,r9 - addi r10,r10,32 - addi r9,r9,32 - - stvx v20,0,r10 - stvx v21,0,r9 - addi r10,r10,32 - addi r9,r9,32 - - stvx v22,0,r10 - stvx v23,0,r9 - addi r10,r10,32 - addi r9,r9,32 - - stvx v24,0,r10 - stvx v25,0,r9 - addi r10,r10,32 - addi r9,r9,32 - - stvx v26,0,r10 - stvx v27,0,r9 - addi r10,r10,32 - addi r9,r9,32 - - stvx v28,0,r10 - stvx v29,0,r9 - addi r10,r10,32 - addi r9,r9,32 - - mfvscr v0 - stvx v30,0,r10 - stvx v31,0,r9 - stw r0,0(r8) - -2: /*L(no_vec):*/ -# endif /* __CONTEXT_ENABLE_VRS */ -#endif /* __CONTEXT_ENABLE_FPRS */ - -/* Restore ucontext (parm1) from stack. */ - lwz r12,_FRAME_PARM_SAVE1(r1) - li r4,0 - stw r3,_UC_REGS_PTR(r12) - addi r5,r12,_UC_SIGMASK - li r3,SIG_SETMASK - bl __sigprocmask@local - cmpwi r3,0 - bne 3f /* L(error_exit) */ - - /* - * If the new ucontext refers to the point where we were interrupted - * by a signal, we have to use the rt_sigreturn system call to - * return to the context so we get both LR and CTR restored. - * - * Otherwise, the context we are restoring is either just after - * a procedure call (getcontext/swapcontext) or at the beginning - * of a procedure call (makecontext), so we don't need to restore - * r0, xer, ctr. We don't restore r2 since it will be used as - * the TLS pointer. - */ - lwz r4,_FRAME_PARM_SAVE2(r1) - lwz r31,_UC_REGS_PTR(r4) - lwz r0,_UC_GREGS+(PT_MSR*4)(r31) - cmpwi r0,0 - bne 4f /* L(do_sigret) */ - -#ifdef __CONTEXT_ENABLE_FPRS -# ifdef __CONTEXT_ENABLE_VRS - -# ifdef PIC - mflr r8 -# ifdef HAVE_ASM_PPC_REL16 - bcl 20,31,5f -5: mflr r7 - addis r7,r7,_GLOBAL_OFFSET_TABLE_-1b@ha - addi r7,r7,_GLOBAL_OFFSET_TABLE_-1b@l -# else - bl _GLOBAL_OFFSET_TABLE_@local-4 - mflr r7 -# endif - mtlr r8 -# ifdef SHARED - lwz r7,_rtld_global_ro@got(r7) - lwz r7,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r7) -# else - lwz r7,_dl_hwcap@got(r7) - lwz r7,0(r7) -# endif -# else - lis r7,_dl_hwcap@ha - lwz r7,_dl_hwcap@l(r7) -# endif - andis. r7,r7,(PPC_FEATURE_HAS_ALTIVEC >> 16) - la r10,(_UC_VREGS)(r31) - beq 6f /* L(has_no_vec) */ - - lwz r0,(32*16)(r10) - li r9,(32*16) - cmpwi r0,0 - mtspr VRSAVE,r0 - beq 6f /* L(has_no_vec) */ - - lvx v19,r9,r10 - la r9,(16)(r10) - - lvx v0,0,r10 - lvx v1,0,r9 - addi r10,r10,32 - addi r9,r9,32 - - mtvscr v19 - lvx v2,0,r10 - lvx v3,0,r9 - addi r10,r10,32 - addi r9,r9,32 - - lvx v4,0,r10 - lvx v5,0,r9 - addi r10,r10,32 - addi r9,r9,32 - - lvx v6,0,r10 - lvx v7,0,r9 - addi r10,r10,32 - addi r9,r9,32 - - lvx v8,0,r10 - lvx v9,0,r9 - addi r10,r10,32 - addi r9,r9,32 - - lvx v10,0,r10 - lvx v11,0,r9 - addi r10,r10,32 - addi r9,r9,32 - - lvx v12,0,r10 - lvx v13,0,r9 - addi r10,r10,32 - addi r9,r9,32 - - lvx v14,0,r10 - lvx v15,0,r9 - addi r10,r10,32 - addi r9,r9,32 - - lvx v16,0,r10 - lvx v17,0,r9 - addi r10,r10,32 - addi r9,r9,32 - - lvx v18,0,r10 - lvx v19,0,r9 - addi r10,r10,32 - addi r9,r9,32 - - lvx v20,0,r10 - lvx v21,0,r9 - addi r10,r10,32 - addi r9,r9,32 - - lvx v22,0,r10 - lvx v23,0,r9 - addi r10,r10,32 - addi r9,r9,32 - - lvx v24,0,r10 - lvx v25,0,r9 - addi r10,r10,32 - addi r9,r9,32 - - lvx v26,0,r10 - lvx v27,0,r9 - addi r10,r10,32 - addi r9,r9,32 - - lvx v28,0,r10 - lvx v29,0,r9 - addi r10,r10,32 - addi r9,r9,32 - - lvx v30,0,r10 - lvx v31,0,r9 - addi r10,r10,32 - addi r9,r9,32 - - lvx v10,0,r10 - lvx v11,0,r9 - -6: /* L(has_no_vec): */ -# endif /* __CONTEXT_ENABLE_VRS */ - /* Restore the floating-point registers */ - lfd fp31,_UC_FREGS+(32*8)(r31) - lfd fp0,_UC_FREGS+(0*8)(r31) - mtfsf 0xff,fp31 - lfd fp1,_UC_FREGS+(1*8)(r31) - lfd fp2,_UC_FREGS+(2*8)(r31) - lfd fp3,_UC_FREGS+(3*8)(r31) - lfd fp4,_UC_FREGS+(4*8)(r31) - lfd fp5,_UC_FREGS+(5*8)(r31) - lfd fp6,_UC_FREGS+(6*8)(r31) - lfd fp7,_UC_FREGS+(7*8)(r31) - lfd fp8,_UC_FREGS+(8*8)(r31) - lfd fp9,_UC_FREGS+(9*8)(r31) - lfd fp10,_UC_FREGS+(10*8)(r31) - lfd fp11,_UC_FREGS+(11*8)(r31) - lfd fp12,_UC_FREGS+(12*8)(r31) - lfd fp13,_UC_FREGS+(13*8)(r31) - lfd fp14,_UC_FREGS+(14*8)(r31) - lfd fp15,_UC_FREGS+(15*8)(r31) - lfd fp16,_UC_FREGS+(16*8)(r31) - lfd fp17,_UC_FREGS+(17*8)(r31) - lfd fp18,_UC_FREGS+(18*8)(r31) - lfd fp19,_UC_FREGS+(19*8)(r31) - lfd fp20,_UC_FREGS+(20*8)(r31) - lfd fp21,_UC_FREGS+(21*8)(r31) - lfd fp22,_UC_FREGS+(22*8)(r31) - lfd fp23,_UC_FREGS+(23*8)(r31) - lfd fp24,_UC_FREGS+(24*8)(r31) - lfd fp25,_UC_FREGS+(25*8)(r31) - lfd fp26,_UC_FREGS+(26*8)(r31) - lfd fp27,_UC_FREGS+(27*8)(r31) - lfd fp28,_UC_FREGS+(28*8)(r31) - lfd fp29,_UC_FREGS+(29*8)(r31) - lfd fp30,_UC_FREGS+(30*8)(r31) - lfd fp31,_UC_FREGS+(31*8)(r31) -#endif /* __CONTEXT_ENABLE_FPRS */ - - /* Restore LR and CCR, and set CTR to the NIP value */ - lwz r3,_UC_GREGS+(PT_LNK*4)(r31) - lwz r4,_UC_GREGS+(PT_NIP*4)(r31) - lwz r5,_UC_GREGS+(PT_CCR*4)(r31) - mtlr r3 - mtctr r4 - mtcr r5 - - /* Restore the general registers */ - lwz r3,_UC_GREGS+(PT_R3*4)(r31) - lwz r4,_UC_GREGS+(PT_R4*4)(r31) - lwz r5,_UC_GREGS+(PT_R5*4)(r31) - lwz r6,_UC_GREGS+(PT_R6*4)(r31) - lwz r7,_UC_GREGS+(PT_R7*4)(r31) - lwz r8,_UC_GREGS+(PT_R8*4)(r31) - lwz r9,_UC_GREGS+(PT_R9*4)(r31) - lwz r10,_UC_GREGS+(PT_R10*4)(r31) - lwz r11,_UC_GREGS+(PT_R11*4)(r31) - lwz r12,_UC_GREGS+(PT_R12*4)(r31) - lwz r13,_UC_GREGS+(PT_R13*4)(r31) - lwz r14,_UC_GREGS+(PT_R14*4)(r31) - lwz r15,_UC_GREGS+(PT_R15*4)(r31) - lwz r16,_UC_GREGS+(PT_R16*4)(r31) - lwz r17,_UC_GREGS+(PT_R17*4)(r31) - lwz r18,_UC_GREGS+(PT_R18*4)(r31) - lwz r19,_UC_GREGS+(PT_R19*4)(r31) - lwz r20,_UC_GREGS+(PT_R20*4)(r31) - lwz r21,_UC_GREGS+(PT_R21*4)(r31) - lwz r22,_UC_GREGS+(PT_R22*4)(r31) - lwz r23,_UC_GREGS+(PT_R23*4)(r31) - lwz r24,_UC_GREGS+(PT_R24*4)(r31) - lwz r25,_UC_GREGS+(PT_R25*4)(r31) - lwz r26,_UC_GREGS+(PT_R26*4)(r31) - lwz r27,_UC_GREGS+(PT_R27*4)(r31) - lwz r28,_UC_GREGS+(PT_R28*4)(r31) - lwz r29,_UC_GREGS+(PT_R29*4)(r31) - lwz r30,_UC_GREGS+(PT_R30*4)(r31) - lwz r1,_UC_GREGS+(PT_R1*4)(r31) - lwz r31,_UC_GREGS+(PT_R31*4)(r31) - - bctr - -3:/*L(error_exit):*/ - lwz r0,_FRAME_LR_SAVE+16(r1) - addi r1,r1,16 - mtlr r0 - blr - -4:/*L(do_sigret):*/ - addi r1,r4,-0xd0 - li r0,SYS_ify(rt_sigreturn) - sc - /* NOTREACHED */ - -END(__CONTEXT_FUNC_NAME) - diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/swapcontext.S b/sysdeps/unix/sysv/linux/powerpc/powerpc32/swapcontext.S index 0605f3d107..c4f0faddc3 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/swapcontext.S +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/swapcontext.S @@ -1,5 +1,5 @@ /* Save current context and jump to a new context. - Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2002, 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 @@ -14,53 +14,684 @@ 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., 51 Franklin Street, Fifth Floor, Boston MA - 02110-1301 USA. */ + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ #include <sysdep.h> #include <rtld-global-offsets.h> #include <shlib-compat.h> -#include <kernel-features.h> #define __ASSEMBLY__ #include <asm/ptrace.h> #include "ucontext_i.h" -#define __CONTEXT_FUNC_NAME __swapcontext -#define __CONTEXT_ENABLE_FPRS 1 -#define __CONTEXT_ENABLE_VRS 1 - -/* Size of ucontext in GLIBC_2.3.4 and later. */ -#define _UC_SIZE_2_3_4 1184 - -#ifdef __ASSUME_SWAPCONTEXT_SYSCALL - .section ".text"; -ENTRY (__swapcontext) - li r5,_UC_SIZE_2_3_4; - DO_CALL (SYS_ify (swapcontext)); - bso- cr0,1f -/* the kernel does not set the return code for the success case */ - li r3,0 - blr -1: - b __syscall_error@local -END(__swapcontext) + .machine "altivec" +ENTRY(__swapcontext) + stwu r1,-16(r1) +/* Insure that the _UC_REGS start on a quadword boundary. */ + stw r3,_FRAME_PARM_SAVE1(r1) + addi r3,r3,_UC_REG_SPACE+12 + stw r4,_FRAME_PARM_SAVE2(r1) /* new context pointer */ + clrrwi r3,r3,4 + +/* Save the general purpose registers */ + stw r0,_UC_GREGS+(PT_R0*4)(r3) + mflr r0 + stw r2,_UC_GREGS+(PT_R2*4)(r3) + stw r4,_UC_GREGS+(PT_R4*4)(r3) +/* Set the callers LR_SAVE, and the ucontext LR and NIP to the callers + return address. */ + stw r0,_UC_GREGS+(PT_LNK*4)(r3) + stw r0,_UC_GREGS+(PT_NIP*4)(r3) + stw r0,_FRAME_LR_SAVE+16(r1) + stw r5,_UC_GREGS+(PT_R5*4)(r3) + stw r6,_UC_GREGS+(PT_R6*4)(r3) + stw r7,_UC_GREGS+(PT_R7*4)(r3) + stw r8,_UC_GREGS+(PT_R8*4)(r3) + stw r9,_UC_GREGS+(PT_R9*4)(r3) + stw r10,_UC_GREGS+(PT_R10*4)(r3) + stw r11,_UC_GREGS+(PT_R11*4)(r3) + stw r12,_UC_GREGS+(PT_R12*4)(r3) + stw r13,_UC_GREGS+(PT_R13*4)(r3) + stw r14,_UC_GREGS+(PT_R14*4)(r3) + stw r15,_UC_GREGS+(PT_R15*4)(r3) + stw r16,_UC_GREGS+(PT_R16*4)(r3) + stw r17,_UC_GREGS+(PT_R17*4)(r3) + stw r18,_UC_GREGS+(PT_R18*4)(r3) + stw r19,_UC_GREGS+(PT_R19*4)(r3) + stw r20,_UC_GREGS+(PT_R20*4)(r3) + stw r21,_UC_GREGS+(PT_R21*4)(r3) + stw r22,_UC_GREGS+(PT_R22*4)(r3) + stw r23,_UC_GREGS+(PT_R23*4)(r3) + stw r24,_UC_GREGS+(PT_R24*4)(r3) + stw r25,_UC_GREGS+(PT_R25*4)(r3) + stw r26,_UC_GREGS+(PT_R26*4)(r3) + stw r27,_UC_GREGS+(PT_R27*4)(r3) + stw r28,_UC_GREGS+(PT_R28*4)(r3) + stw r29,_UC_GREGS+(PT_R29*4)(r3) + stw r30,_UC_GREGS+(PT_R30*4)(r3) + stw r31,_UC_GREGS+(PT_R31*4)(r3) + +/* Save the value of R1. We had to push the stack before we + had the address of uc_reg_space. So compute the address of + the callers stack pointer and save it as R1. */ + addi r8,r1,16 + li r0,0 +/* Save the count, exception and condition registers. */ + mfctr r11 + mfxer r10 + mfcr r9 + stw r8,_UC_GREGS+(PT_R1*4)(r3) + stw r11,_UC_GREGS+(PT_CTR*4)(r3) + stw r10,_UC_GREGS+(PT_XER*4)(r3) + stw r9,_UC_GREGS+(PT_CCR*4)(r3) +/* Set the return value of getcontext to "success". R3 is the only + register whose value is not preserved in the saved context. */ + stw r0,_UC_GREGS+(PT_R3*4)(r3) + + /* Zero fill fields that can't be set in user state. */ + stw r0,_UC_GREGS+(PT_MSR*4)(r3) + stw r0,_UC_GREGS+(PT_MQ*4)(r3) + + /* Save the floating-point registers */ + stfd fp0,_UC_FREGS+(0*8)(r3) + stfd fp1,_UC_FREGS+(1*8)(r3) + stfd fp2,_UC_FREGS+(2*8)(r3) + stfd fp3,_UC_FREGS+(3*8)(r3) + stfd fp4,_UC_FREGS+(4*8)(r3) + stfd fp5,_UC_FREGS+(5*8)(r3) + stfd fp6,_UC_FREGS+(6*8)(r3) + stfd fp7,_UC_FREGS+(7*8)(r3) + stfd fp8,_UC_FREGS+(8*8)(r3) + stfd fp9,_UC_FREGS+(9*8)(r3) + stfd fp10,_UC_FREGS+(10*8)(r3) + stfd fp11,_UC_FREGS+(11*8)(r3) + stfd fp12,_UC_FREGS+(12*8)(r3) + stfd fp13,_UC_FREGS+(13*8)(r3) + stfd fp14,_UC_FREGS+(14*8)(r3) + stfd fp15,_UC_FREGS+(15*8)(r3) + stfd fp16,_UC_FREGS+(16*8)(r3) + stfd fp17,_UC_FREGS+(17*8)(r3) + stfd fp18,_UC_FREGS+(18*8)(r3) + stfd fp19,_UC_FREGS+(19*8)(r3) + stfd fp20,_UC_FREGS+(20*8)(r3) + stfd fp21,_UC_FREGS+(21*8)(r3) + stfd fp22,_UC_FREGS+(22*8)(r3) + stfd fp23,_UC_FREGS+(23*8)(r3) + stfd fp24,_UC_FREGS+(24*8)(r3) + stfd fp25,_UC_FREGS+(25*8)(r3) + stfd fp26,_UC_FREGS+(26*8)(r3) + stfd fp27,_UC_FREGS+(27*8)(r3) + stfd fp28,_UC_FREGS+(28*8)(r3) + stfd fp29,_UC_FREGS+(29*8)(r3) + mffs fp0 + stfd fp30,_UC_FREGS+(30*8)(r3) + stfd fp31,_UC_FREGS+(31*8)(r3) + stfd fp0,_UC_FREGS+(32*8)(r3) +#ifdef PIC + mflr r8 + bl _GLOBAL_OFFSET_TABLE_@local-4 + mflr r7 +# ifdef SHARED + lwz r7,_rtld_global_ro@got(r7) + mtlr r8 + lwz r7,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r7) +# else + lwz r7,_dl_hwcap@got(r7) + mtlr r8 + lwz r7,0(r7) +# endif +#else + lis r7,_dl_hwcap@ha + lwz r7,_dl_hwcap@l(r7) +#endif + andis. r7,r7,(PPC_FEATURE_HAS_ALTIVEC >> 16) + + la r10,(_UC_VREGS)(r3) + la r9,(_UC_VREGS+16)(r3) + + beq L(no_vec) +/* address of the combined VSCR/VSAVE quadword. */ + la r8,(_UC_VREGS+512)(r3) + +/* Save the vector registers */ + stvx v0,0,r10 + stvx v1,0,r9 + addi r10,r10,32 + addi r9,r9,32 +/* We need to get the Vector Status and Control Register early to avoid + store order problems later with the VSAVE register that shares the + same quadword. */ + mfvscr v0 + + stvx v2,0,r10 + stvx v3,0,r9 + addi r10,r10,32 + addi r9,r9,32 + + stvx v0,0,r8 + + stvx v4,0,r10 + stvx v5,0,r9 + addi r10,r10,32 + addi r9,r9,32 + + stvx v6,0,r10 + stvx v7,0,r9 + addi r10,r10,32 + addi r9,r9,32 + + stvx v8,0,r10 + stvx v9,0,r9 + addi r10,r10,32 + addi r9,r9,32 + + stvx v10,0,r10 + stvx v11,0,r9 + addi r10,r10,32 + addi r9,r9,32 + + stvx v12,0,r10 + stvx v13,0,r9 + addi r10,r10,32 + addi r9,r9,32 + + stvx v14,0,r10 + stvx v15,0,r9 + addi r10,r10,32 + addi r9,r9,32 + + stvx v16,0,r10 + stvx v17,0,r9 + addi r10,r10,32 + addi r9,r9,32 + + stvx v18,0,r10 + stvx v19,0,r9 + addi r10,r10,32 + addi r9,r9,32 + + stvx v20,0,r10 + stvx v21,0,r9 + addi r10,r10,32 + addi r9,r9,32 + + stvx v22,0,r10 + stvx v23,0,r9 + addi r10,r10,32 + addi r9,r9,32 + + stvx v24,0,r10 + stvx v25,0,r9 + addi r10,r10,32 + addi r9,r9,32 + + stvx v26,0,r10 + stvx v27,0,r9 + addi r10,r10,32 + addi r9,r9,32 + + stvx v28,0,r10 + stvx v29,0,r9 + addi r10,r10,32 + addi r9,r9,32 + + mfvscr v0 + stvx v30,0,r10 + stvx v31,0,r9 + + stw r0,0(r8) + +L(no_vec): +/* Restore ucontext (parm1) from stack. */ + lwz r12,_FRAME_PARM_SAVE1(r1) + li r4,0 + stw r3,_UC_REGS_PTR(r12) + addi r5,r12,_UC_SIGMASK + li r3,SIG_SETMASK + bl JUMPTARGET(__sigprocmask) + cmpwi r3,0 + bne L(error_exit) + + /* + * If the new ucontext refers to the point where we were interrupted + * by a signal, we have to use the rt_sigreturn system call to + * return to the context so we get both LR and CTR restored. + * + * Otherwise, the context we are restoring is either just after + * a procedure call (getcontext/swapcontext) or at the beginning + * of a procedure call (makecontext), so we don't need to restore + * r0, xer, ctr. We don't restore r2 since it will be used as + * the TLS pointer. + */ + lwz r4,_FRAME_PARM_SAVE2(r1) + lwz r31,_UC_REGS_PTR(r4) + lwz r0,_UC_GREGS+(PT_MSR*4)(r31) + cmpwi r0,0 + bne L(do_sigret) + +#ifdef PIC + mflr r8 + bl _GLOBAL_OFFSET_TABLE_@local-4 + mflr r7 +# ifdef SHARED + lwz r7,_rtld_global_ro@got(r7) + mtlr r8 + lwz r7,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r7) +# else + lwz r7,_dl_hwcap@got(r7) + mtlr r8 + lwz r7,0(r7) +# endif #else -# include "swapcontext-common.S" + lis r7,_dl_hwcap@ha + lwz r7,_dl_hwcap@l(r7) #endif + andis. r7,r7,(PPC_FEATURE_HAS_ALTIVEC >> 16) + la r10,(_UC_VREGS)(r31) + beq L(has_no_vec) + + lwz r0,(32*16)(r10) + li r9,(32*16) + cmpwi r0,0 + mtspr VRSAVE,r0 + beq L(has_no_vec) + + lvx v19,r9,r10 + la r9,(16)(r10) + + lvx v0,0,r10 + lvx v1,0,r9 + addi r10,r10,32 + addi r9,r9,32 + + mtvscr v19 + lvx v2,0,r10 + lvx v3,0,r9 + addi r10,r10,32 + addi r9,r9,32 + + lvx v4,0,r10 + lvx v5,0,r9 + addi r10,r10,32 + addi r9,r9,32 + + lvx v6,0,r10 + lvx v7,0,r9 + addi r10,r10,32 + addi r9,r9,32 + + lvx v8,0,r10 + lvx v9,0,r9 + addi r10,r10,32 + addi r9,r9,32 + + lvx v10,0,r10 + lvx v11,0,r9 + addi r10,r10,32 + addi r9,r9,32 + + lvx v12,0,r10 + lvx v13,0,r9 + addi r10,r10,32 + addi r9,r9,32 + + lvx v14,0,r10 + lvx v15,0,r9 + addi r10,r10,32 + addi r9,r9,32 + + lvx v16,0,r10 + lvx v17,0,r9 + addi r10,r10,32 + addi r9,r9,32 + + lvx v18,0,r10 + lvx v19,0,r9 + addi r10,r10,32 + addi r9,r9,32 + + lvx v20,0,r10 + lvx v21,0,r9 + addi r10,r10,32 + addi r9,r9,32 + + lvx v22,0,r10 + lvx v23,0,r9 + addi r10,r10,32 + addi r9,r9,32 + + lvx v24,0,r10 + lvx v25,0,r9 + addi r10,r10,32 + addi r9,r9,32 + + lvx v26,0,r10 + lvx v27,0,r9 + addi r10,r10,32 + addi r9,r9,32 + + lvx v28,0,r10 + lvx v29,0,r9 + addi r10,r10,32 + addi r9,r9,32 + + lvx v30,0,r10 + lvx v31,0,r9 + addi r10,r10,32 + addi r9,r9,32 + + lvx v10,0,r10 + lvx v11,0,r9 + +L(has_no_vec): + /* Restore the floating-point registers */ + lfd fp31,_UC_FREGS+(32*8)(r31) + lfd fp0,_UC_FREGS+(0*8)(r31) + mtfsf 0xff,fp31 + lfd fp1,_UC_FREGS+(1*8)(r31) + lfd fp2,_UC_FREGS+(2*8)(r31) + lfd fp3,_UC_FREGS+(3*8)(r31) + lfd fp4,_UC_FREGS+(4*8)(r31) + lfd fp5,_UC_FREGS+(5*8)(r31) + lfd fp6,_UC_FREGS+(6*8)(r31) + lfd fp7,_UC_FREGS+(7*8)(r31) + lfd fp8,_UC_FREGS+(8*8)(r31) + lfd fp9,_UC_FREGS+(9*8)(r31) + lfd fp10,_UC_FREGS+(10*8)(r31) + lfd fp11,_UC_FREGS+(11*8)(r31) + lfd fp12,_UC_FREGS+(12*8)(r31) + lfd fp13,_UC_FREGS+(13*8)(r31) + lfd fp14,_UC_FREGS+(14*8)(r31) + lfd fp15,_UC_FREGS+(15*8)(r31) + lfd fp16,_UC_FREGS+(16*8)(r31) + lfd fp17,_UC_FREGS+(17*8)(r31) + lfd fp18,_UC_FREGS+(18*8)(r31) + lfd fp19,_UC_FREGS+(19*8)(r31) + lfd fp20,_UC_FREGS+(20*8)(r31) + lfd fp21,_UC_FREGS+(21*8)(r31) + lfd fp22,_UC_FREGS+(22*8)(r31) + lfd fp23,_UC_FREGS+(23*8)(r31) + lfd fp24,_UC_FREGS+(24*8)(r31) + lfd fp25,_UC_FREGS+(25*8)(r31) + lfd fp26,_UC_FREGS+(26*8)(r31) + lfd fp27,_UC_FREGS+(27*8)(r31) + lfd fp28,_UC_FREGS+(28*8)(r31) + lfd fp29,_UC_FREGS+(29*8)(r31) + lfd fp30,_UC_FREGS+(30*8)(r31) + lfd fp31,_UC_FREGS+(31*8)(r31) + + /* Restore LR and CCR, and set CTR to the NIP value */ + lwz r3,_UC_GREGS+(PT_LNK*4)(r31) + lwz r4,_UC_GREGS+(PT_NIP*4)(r31) + lwz r5,_UC_GREGS+(PT_CCR*4)(r31) + mtlr r3 + mtctr r4 + mtcr r5 + + /* Restore the general registers */ + lwz r1,_UC_GREGS+(PT_R1*4)(r31) + lwz r3,_UC_GREGS+(PT_R3*4)(r31) + lwz r4,_UC_GREGS+(PT_R4*4)(r31) + lwz r5,_UC_GREGS+(PT_R5*4)(r31) + lwz r6,_UC_GREGS+(PT_R6*4)(r31) + lwz r7,_UC_GREGS+(PT_R7*4)(r31) + lwz r8,_UC_GREGS+(PT_R8*4)(r31) + lwz r9,_UC_GREGS+(PT_R9*4)(r31) + lwz r10,_UC_GREGS+(PT_R10*4)(r31) + lwz r11,_UC_GREGS+(PT_R11*4)(r31) + lwz r12,_UC_GREGS+(PT_R12*4)(r31) + lwz r13,_UC_GREGS+(PT_R13*4)(r31) + lwz r14,_UC_GREGS+(PT_R14*4)(r31) + lwz r15,_UC_GREGS+(PT_R15*4)(r31) + lwz r16,_UC_GREGS+(PT_R16*4)(r31) + lwz r17,_UC_GREGS+(PT_R17*4)(r31) + lwz r18,_UC_GREGS+(PT_R18*4)(r31) + lwz r19,_UC_GREGS+(PT_R19*4)(r31) + lwz r20,_UC_GREGS+(PT_R20*4)(r31) + lwz r21,_UC_GREGS+(PT_R21*4)(r31) + lwz r22,_UC_GREGS+(PT_R22*4)(r31) + lwz r23,_UC_GREGS+(PT_R23*4)(r31) + lwz r24,_UC_GREGS+(PT_R24*4)(r31) + lwz r25,_UC_GREGS+(PT_R25*4)(r31) + lwz r26,_UC_GREGS+(PT_R26*4)(r31) + lwz r27,_UC_GREGS+(PT_R27*4)(r31) + lwz r28,_UC_GREGS+(PT_R28*4)(r31) + lwz r29,_UC_GREGS+(PT_R29*4)(r31) + lwz r30,_UC_GREGS+(PT_R30*4)(r31) + lwz r31,_UC_GREGS+(PT_R31*4)(r31) + + bctr + +L(error_exit): + lwz r0,_FRAME_LR_SAVE+16(r1) + addi r1,r1,16 + mtlr r0 + blr + +L(do_sigret): + addi r1,r4,-0xd0 + li r0,SYS_ify(rt_sigreturn) + sc + /* NOTREACHED */ + +END(__swapcontext) versioned_symbol (libc, __swapcontext, swapcontext, GLIBC_2_3_4) #if SHLIB_COMPAT (libc, GLIBC_2_3_3, GLIBC_2_3_4) compat_text_section - -# undef __CONTEXT_FUNC_NAME -# define __CONTEXT_FUNC_NAME __novec_swapcontext -# undef __CONTEXT_ENABLE_VRS +ENTRY(__novec_swapcontext) + /* Save the current context */ + addi r3,r3,_UC_REG_SPACE + stw r3,_UC_REGS_PTR - _UC_REG_SPACE(r3) + stw r0,_UC_GREGS+(PT_R0*4)(r3) + stw r1,_UC_GREGS+(PT_R1*4)(r3) + mflr r0 + stwu r1,-16(r1) + stw r0,20(r1) + stw r31,12(r1) + stw r31,_UC_GREGS+(PT_R31*4)(r3) + mr r31,r4 /* new context pointer */ + stw r0,_UC_GREGS+(PT_LNK*4)(r3) + stw r0,_UC_GREGS+(PT_NIP*4)(r3) + stw r2,_UC_GREGS+(PT_R2*4)(r3) + stw r4,_UC_GREGS+(PT_R4*4)(r3) + stw r5,_UC_GREGS+(PT_R5*4)(r3) + stw r6,_UC_GREGS+(PT_R6*4)(r3) + stw r7,_UC_GREGS+(PT_R7*4)(r3) + stw r8,_UC_GREGS+(PT_R8*4)(r3) + stw r9,_UC_GREGS+(PT_R9*4)(r3) + stw r10,_UC_GREGS+(PT_R10*4)(r3) + stw r11,_UC_GREGS+(PT_R11*4)(r3) + stw r12,_UC_GREGS+(PT_R12*4)(r3) + stw r13,_UC_GREGS+(PT_R13*4)(r3) + stw r14,_UC_GREGS+(PT_R14*4)(r3) + stw r15,_UC_GREGS+(PT_R15*4)(r3) + stw r16,_UC_GREGS+(PT_R16*4)(r3) + stw r17,_UC_GREGS+(PT_R17*4)(r3) + stw r18,_UC_GREGS+(PT_R18*4)(r3) + stw r19,_UC_GREGS+(PT_R19*4)(r3) + stw r20,_UC_GREGS+(PT_R20*4)(r3) + stw r21,_UC_GREGS+(PT_R21*4)(r3) + stw r22,_UC_GREGS+(PT_R22*4)(r3) + stw r23,_UC_GREGS+(PT_R23*4)(r3) + stw r24,_UC_GREGS+(PT_R24*4)(r3) + stw r25,_UC_GREGS+(PT_R25*4)(r3) + stw r26,_UC_GREGS+(PT_R26*4)(r3) + stw r27,_UC_GREGS+(PT_R27*4)(r3) + stw r28,_UC_GREGS+(PT_R28*4)(r3) + stw r29,_UC_GREGS+(PT_R29*4)(r3) + stw r30,_UC_GREGS+(PT_R30*4)(r3) + mfctr r0 + stw r0,_UC_GREGS+(PT_CTR*4)(r3) + mfxer r0 + stw r0,_UC_GREGS+(PT_XER*4)(r3) + mfcr r0 + stw r0,_UC_GREGS+(PT_CCR*4)(r3) + + /* Set the return value of swapcontext to "success". R3 is the only + register whose value is not preserved in the saved context. */ + li r0,0 + stw r0,_UC_GREGS+(PT_R3*4)(r3) + + /* Zero fill fields that can't be set in user state. */ + stw r0,_UC_GREGS+(PT_MSR*4)(r3) + stw r0,_UC_GREGS+(PT_MQ*4)(r3) + + /* Save the floating-point registers */ + stfd fp0,_UC_FREGS+(0*8)(r3) + stfd fp1,_UC_FREGS+(1*8)(r3) + stfd fp2,_UC_FREGS+(2*8)(r3) + stfd fp3,_UC_FREGS+(3*8)(r3) + stfd fp4,_UC_FREGS+(4*8)(r3) + stfd fp5,_UC_FREGS+(5*8)(r3) + stfd fp6,_UC_FREGS+(6*8)(r3) + stfd fp7,_UC_FREGS+(7*8)(r3) + stfd fp8,_UC_FREGS+(8*8)(r3) + stfd fp9,_UC_FREGS+(9*8)(r3) + stfd fp10,_UC_FREGS+(10*8)(r3) + stfd fp11,_UC_FREGS+(11*8)(r3) + stfd fp12,_UC_FREGS+(12*8)(r3) + stfd fp13,_UC_FREGS+(13*8)(r3) + stfd fp14,_UC_FREGS+(14*8)(r3) + stfd fp15,_UC_FREGS+(15*8)(r3) + stfd fp16,_UC_FREGS+(16*8)(r3) + stfd fp17,_UC_FREGS+(17*8)(r3) + stfd fp18,_UC_FREGS+(18*8)(r3) + stfd fp19,_UC_FREGS+(19*8)(r3) + stfd fp20,_UC_FREGS+(20*8)(r3) + stfd fp21,_UC_FREGS+(21*8)(r3) + stfd fp22,_UC_FREGS+(22*8)(r3) + stfd fp23,_UC_FREGS+(23*8)(r3) + stfd fp24,_UC_FREGS+(24*8)(r3) + stfd fp25,_UC_FREGS+(25*8)(r3) + stfd fp26,_UC_FREGS+(26*8)(r3) + stfd fp27,_UC_FREGS+(27*8)(r3) + stfd fp28,_UC_FREGS+(28*8)(r3) + stfd fp29,_UC_FREGS+(29*8)(r3) + mffs fp0 + stfd fp30,_UC_FREGS+(30*8)(r3) + stfd fp31,_UC_FREGS+(31*8)(r3) + stfd fp0,_UC_FREGS+(32*8)(r3) + + addi r5,r3,_UC_SIGMASK - _UC_REG_SPACE + addi r4,r4,_UC_SIGMASK + li r3,SIG_SETMASK + bl JUMPTARGET(__sigprocmask) + cmpwi r3,0 + bne L(novec_error_exit) + + /* + * If the new ucontext refers to the point where we were interrupted + * by a signal, we have to use the rt_sigreturn system call to + * return to the context so we get both LR and CTR restored. + * + * Otherwise, the context we are restoring is either just after + * a procedure call (getcontext/swapcontext) or at the beginning + * of a procedure call (makecontext), so we don't need to restore + * r0, xer, ctr. We don't restore r2 since it will be used as + * the TLS pointer. + */ + mr r4,r31 + lwz r31,_UC_REGS_PTR(r31) + lwz r0,_UC_GREGS+(PT_MSR*4)(r31) + cmpwi r0,0 + bne L(novec_do_sigret) + + /* Restore the floating-point registers */ + lfd fp31,_UC_FREGS+(32*8)(r31) + lfd fp0,_UC_FREGS+(0*8)(r31) + mtfsf 0xff,fp31 + lfd fp1,_UC_FREGS+(1*8)(r31) + lfd fp2,_UC_FREGS+(2*8)(r31) + lfd fp3,_UC_FREGS+(3*8)(r31) + lfd fp4,_UC_FREGS+(4*8)(r31) + lfd fp5,_UC_FREGS+(5*8)(r31) + lfd fp6,_UC_FREGS+(6*8)(r31) + lfd fp7,_UC_FREGS+(7*8)(r31) + lfd fp8,_UC_FREGS+(8*8)(r31) + lfd fp9,_UC_FREGS+(9*8)(r31) + lfd fp10,_UC_FREGS+(10*8)(r31) + lfd fp11,_UC_FREGS+(11*8)(r31) + lfd fp12,_UC_FREGS+(12*8)(r31) + lfd fp13,_UC_FREGS+(13*8)(r31) + lfd fp14,_UC_FREGS+(14*8)(r31) + lfd fp15,_UC_FREGS+(15*8)(r31) + lfd fp16,_UC_FREGS+(16*8)(r31) + lfd fp17,_UC_FREGS+(17*8)(r31) + lfd fp18,_UC_FREGS+(18*8)(r31) + lfd fp19,_UC_FREGS+(19*8)(r31) + lfd fp20,_UC_FREGS+(20*8)(r31) + lfd fp21,_UC_FREGS+(21*8)(r31) + lfd fp22,_UC_FREGS+(22*8)(r31) + lfd fp23,_UC_FREGS+(23*8)(r31) + lfd fp24,_UC_FREGS+(24*8)(r31) + lfd fp25,_UC_FREGS+(25*8)(r31) + lfd fp26,_UC_FREGS+(26*8)(r31) + lfd fp27,_UC_FREGS+(27*8)(r31) + lfd fp28,_UC_FREGS+(28*8)(r31) + lfd fp29,_UC_FREGS+(29*8)(r31) + lfd fp30,_UC_FREGS+(30*8)(r31) + lfd fp31,_UC_FREGS+(31*8)(r31) + + /* Restore LR and CCR, and set CTR to the NIP value */ + lwz r3,_UC_GREGS+(PT_LNK*4)(r31) + lwz r4,_UC_GREGS+(PT_NIP*4)(r31) + lwz r5,_UC_GREGS+(PT_CCR*4)(r31) + mtlr r3 + mtctr r4 + mtcr r5 + + /* Restore the general registers */ + lwz r1,_UC_GREGS+(PT_R1*4)(r31) + lwz r3,_UC_GREGS+(PT_R3*4)(r31) + lwz r4,_UC_GREGS+(PT_R4*4)(r31) + lwz r5,_UC_GREGS+(PT_R5*4)(r31) + lwz r6,_UC_GREGS+(PT_R6*4)(r31) + lwz r7,_UC_GREGS+(PT_R7*4)(r31) + lwz r8,_UC_GREGS+(PT_R8*4)(r31) + lwz r9,_UC_GREGS+(PT_R9*4)(r31) + lwz r10,_UC_GREGS+(PT_R10*4)(r31) + lwz r11,_UC_GREGS+(PT_R11*4)(r31) + lwz r12,_UC_GREGS+(PT_R12*4)(r31) + lwz r13,_UC_GREGS+(PT_R13*4)(r31) + lwz r14,_UC_GREGS+(PT_R14*4)(r31) + lwz r15,_UC_GREGS+(PT_R15*4)(r31) + lwz r16,_UC_GREGS+(PT_R16*4)(r31) + lwz r17,_UC_GREGS+(PT_R17*4)(r31) + lwz r18,_UC_GREGS+(PT_R18*4)(r31) + lwz r19,_UC_GREGS+(PT_R19*4)(r31) + lwz r20,_UC_GREGS+(PT_R20*4)(r31) + lwz r21,_UC_GREGS+(PT_R21*4)(r31) + lwz r22,_UC_GREGS+(PT_R22*4)(r31) + lwz r23,_UC_GREGS+(PT_R23*4)(r31) + lwz r24,_UC_GREGS+(PT_R24*4)(r31) + lwz r25,_UC_GREGS+(PT_R25*4)(r31) + lwz r26,_UC_GREGS+(PT_R26*4)(r31) + lwz r27,_UC_GREGS+(PT_R27*4)(r31) + lwz r28,_UC_GREGS+(PT_R28*4)(r31) + lwz r29,_UC_GREGS+(PT_R29*4)(r31) + lwz r30,_UC_GREGS+(PT_R30*4)(r31) + lwz r31,_UC_GREGS+(PT_R31*4)(r31) + + bctr + +L(novec_error_exit): + lwz r31,12(r1) + lwz r0,20(r1) + addi r1,r1,16 + mtlr r0 + blr -# include "swapcontext-common.S" +L(novec_do_sigret): + addi r1,r4,-0xd0 + li r0,SYS_ify(rt_sigreturn) + sc + /* NOTREACHED */ +END(__novec_swapcontext) .previous compat_symbol (libc, __novec_swapcontext, swapcontext, GLIBC_2_3_3) @@ -69,13 +700,13 @@ compat_symbol (libc, __novec_swapcontext, swapcontext, GLIBC_2_3_3) #if SHLIB_COMPAT (libc, GLIBC_2_1, GLIBC_2_3_3) -# define _ERRNO_H 1 -# include <bits/errno.h> +#define _ERRNO_H 1 +#include <bits/errno.h> compat_text_section ENTRY (__swapcontext_stub) li r3,ENOSYS - b __syscall_error@local + b JUMPTARGET(__syscall_error) END (__swapcontext_stub) .previous diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h b/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h index c42efbabdd..2ee3e60229 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h @@ -1,4 +1,4 @@ -/* Copyright (C) 1992,1997-2003,2004,2005,2006 Free Software Foundation, Inc. +/* Copyright (C) 1992,1997-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 @@ -20,7 +20,6 @@ #define _LINUX_POWERPC_SYSDEP_H 1 #include <sysdeps/unix/powerpc/sysdep.h> -#include <tls.h> /* Some systen calls got renamed over time, but retained the same semantics. Handle them here so they can be catched by both C and assembler stubs in @@ -55,109 +54,6 @@ # include <errno.h> -# ifdef SHARED -# define INLINE_VSYSCALL(name, nr, args...) \ - ({ \ - __label__ out; \ - __label__ iserr; \ - INTERNAL_SYSCALL_DECL (sc_err); \ - long int sc_ret; \ - \ - if (__vdso_##name != NULL) \ - { \ - sc_ret = INTERNAL_VSYSCALL_NCS (__vdso_##name, sc_err, nr, ##args); \ - if (!INTERNAL_SYSCALL_ERROR_P (sc_ret, sc_err)) \ - goto out; \ - if (INTERNAL_SYSCALL_ERRNO (sc_ret, sc_err) != ENOSYS) \ - goto iserr; \ - } \ - \ - sc_ret = INTERNAL_SYSCALL (name, sc_err, nr, ##args); \ - if (INTERNAL_SYSCALL_ERROR_P (sc_ret, sc_err)) \ - { \ - iserr: \ - __set_errno (INTERNAL_SYSCALL_ERRNO (sc_ret, sc_err)); \ - sc_ret = -1L; \ - } \ - out: \ - sc_ret; \ - }) -# else -# define INLINE_VSYSCALL(name, nr, args...) \ - INLINE_SYSCALL (name, nr, ##args) -# endif - -# ifdef SHARED -# define INTERNAL_VSYSCALL(name, err, nr, args...) \ - ({ \ - __label__ out; \ - long int v_ret; \ - \ - if (__vdso_##name != NULL) \ - { \ - v_ret = INTERNAL_VSYSCALL_NCS (__vdso_##name, err, nr, ##args); \ - if (!INTERNAL_SYSCALL_ERROR_P (v_ret, err) \ - || INTERNAL_SYSCALL_ERRNO (v_ret, err) != ENOSYS) \ - goto out; \ - } \ - v_ret = INTERNAL_SYSCALL (name, err, nr, ##args); \ - out: \ - v_ret; \ - }) -# else -# define INTERNAL_VSYSCALL(name, err, nr, args...) \ - INTERNAL_SYSCALL (name, err, nr, ##args) -# endif - -# define INTERNAL_VSYSCALL_NO_SYSCALL_FALLBACK(name, err, nr, args...) \ - ({ \ - long int sc_ret = ENOSYS; \ - \ - if (__vdso_##name != NULL) \ - sc_ret = INTERNAL_VSYSCALL_NCS (__vdso_##name, err, nr, ##args); \ - else \ - err = 1 << 28; \ - sc_ret; \ - }) - -/* List of system calls which are supported as vsyscalls. */ -# define HAVE_CLOCK_GETRES_VSYSCALL 1 -# define HAVE_CLOCK_GETTIME_VSYSCALL 1 - -/* Define a macro which expands inline into the wrapper code for a VDSO - call. This use is for internal calls that do not need to handle errors - normally. It will never touch errno. - On powerpc a system call basically clobbers the same registers like a - function call, with the exception of LR (which is needed for the - "sc; bnslr+" sequence) and CR (where only CR0.SO is clobbered to signal - an error return status). */ -# define INTERNAL_VSYSCALL_NCS(funcptr, err, nr, args...) \ - ({ \ - register void *r0 __asm__ ("r0"); \ - register long int r3 __asm__ ("r3"); \ - register long int r4 __asm__ ("r4"); \ - register long int r5 __asm__ ("r5"); \ - register long int r6 __asm__ ("r6"); \ - register long int r7 __asm__ ("r7"); \ - register long int r8 __asm__ ("r8"); \ - register long int r9 __asm__ ("r9"); \ - register long int r10 __asm__ ("r10"); \ - register long int r11 __asm__ ("r11"); \ - register long int r12 __asm__ ("r12"); \ - LOADARGS_##nr (funcptr, args); \ - __asm__ __volatile__ \ - ("mtctr %0\n\t" \ - "bctrl\n\t" \ - "mfcr %0" \ - : "=&r" (r0), \ - "=&r" (r3), "=&r" (r4), "=&r" (r5), "=&r" (r6), "=&r" (r7), \ - "=&r" (r8), "=&r" (r9), "=&r" (r10), "=&r" (r11), "=&r" (r12) \ - : ASM_INPUT_##nr \ - : "cr0", "ctr", "lr", "memory"); \ - err = (long int) r0; \ - (int) r3; \ - }) - # undef INLINE_SYSCALL # define INLINE_SYSCALL(name, nr, args...) \ ({ \ @@ -196,7 +92,7 @@ register long int r10 __asm__ ("r10"); \ register long int r11 __asm__ ("r11"); \ register long int r12 __asm__ ("r12"); \ - LOADARGS_##nr(name, args); \ + LOADARGS_##nr(name, args); \ __asm__ __volatile__ \ ("sc \n\t" \ "mfcr %0" \ @@ -213,16 +109,16 @@ # undef INTERNAL_SYSCALL_ERROR_P # define INTERNAL_SYSCALL_ERROR_P(val, err) \ - ((void) (val), __builtin_expect ((err) & (1 << 28), 0)) + (__builtin_expect (err & (1 << 28), 0)) # undef INTERNAL_SYSCALL_ERRNO # define INTERNAL_SYSCALL_ERRNO(val, err) (val) -# define LOADARGS_0(name, dummy) \ +# define LOADARGS_0(name, dummy) \ r0 = name # define LOADARGS_1(name, __arg1) \ long int arg1 = (long int) (__arg1); \ - LOADARGS_0(name, 0); \ + LOADARGS_0(name, 0); \ extern void __illegally_sized_syscall_arg1 (void); \ if (__builtin_classify_type (__arg1) != 5 && sizeof (__arg1) > 4) \ __illegally_sized_syscall_arg1 (); \ @@ -274,28 +170,4 @@ #endif /* __ASSEMBLER__ */ -/* Pointer mangling support. */ -#if defined NOT_IN_libc && defined IS_IN_rtld -/* We cannot use the thread descriptor because in ld.so we use setjmp - earlier than the descriptor is initialized. */ -#else -# ifdef __ASSEMBLER__ -# define PTR_MANGLE(reg, tmpreg) \ - lwz tmpreg,POINTER_GUARD(r2); \ - xor reg,tmpreg,reg -# define PTR_MANGLE2(reg, tmpreg) \ - xor reg,tmpreg,reg -# define PTR_MANGLE3(destreg, reg, tmpreg) \ - lwz tmpreg,POINTER_GUARD(r2); \ - xor destreg,tmpreg,reg -# define PTR_DEMANGLE(reg, tmpreg) PTR_MANGLE (reg, tmpreg) -# define PTR_DEMANGLE2(reg, tmpreg) PTR_MANGLE2 (reg, tmpreg) -# define PTR_DEMANGLE3(destreg, reg, tmpreg) PTR_MANGLE3 (destreg, reg, tmpreg) -# else -# define PTR_MANGLE(var) \ - (var) = (__typeof (var)) ((uintptr_t) (var) ^ THREAD_GET_POINTER_GUARD ()) -# define PTR_DEMANGLE(var) PTR_MANGLE (var) -# endif -#endif - #endif /* linux/powerpc/powerpc32/sysdep.h */ diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/truncate64.c b/sysdeps/unix/sysv/linux/powerpc/powerpc32/truncate64.c index f107e84373..ce8ebc2a97 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/truncate64.c +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/truncate64.c @@ -1,5 +1,4 @@ -/* Copyright (C) 1997,1998,1999,2000,2002,2005,2006 - Free Software Foundation, Inc. +/* Copyright (C) 1997, 1998, 1999, 2000, 2002 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 @@ -25,12 +24,12 @@ #include <sys/syscall.h> #include <bp-checks.h> -#include <kernel-features.h> +#include "kernel-features.h" #ifdef __NR_truncate64 #ifndef __ASSUME_TRUNCATE64_SYSCALL /* The variable is shared between all wrappers around *truncate64 calls. */ -int __have_no_truncate64; +int have_no_truncate64; #endif @@ -41,7 +40,7 @@ truncate64 (path, length) off64_t length; { #ifndef __ASSUME_TRUNCATE64_SYSCALL - if (! __have_no_truncate64) + if (! have_no_truncate64) #endif { #ifndef __ASSUME_TRUNCATE64_SYSCALL @@ -59,7 +58,7 @@ truncate64 (path, length) #ifndef __ASSUME_TRUNCATE64_SYSCALL __set_errno (saved_errno); - __have_no_truncate64 = 1; + have_no_truncate64 = 1; #endif } @@ -69,11 +68,11 @@ truncate64 (path, length) __set_errno (EINVAL); return -1; } - return __truncate (path, (off_t) length); + return truncate (path, (off_t) length); #endif } #else /* Use the generic implementation. */ -# include <misc/truncate64.c> +# include <sysdeps/generic/truncate64.c> #endif diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/ucontext_i.h b/sysdeps/unix/sysv/linux/powerpc/powerpc32/ucontext_i.h new file mode 100644 index 0000000000..e47b24a09e --- /dev/null +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/ucontext_i.h @@ -0,0 +1,43 @@ +/* Offsets and other constants needed in the *context() function + implementation. + Copyright (C) 2002 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. */ + +#define SIG_BLOCK 0 +#define SIG_SETMASK 2 + +#define _FRAME_BACKCHAIN 0 +#define _FRAME_LR_SAVE 4 +#define _FRAME_PARM_SAVE1 8 +#define _FRAME_PARM_SAVE2 12 +#define _FRAME_PARM_SAVE3 16 +#define _FRAME_PARM_SAVE4 20 + +#define _UC_LINK 4 +#define _UC_STACK_SP 8 +#define _UC_STACK_SIZE 16 +#define _UC_REGS_PTR 48 +#define _UC_SIGMASK 52 +#define _UC_REG_SPACE 180 + +/* offsets within mcontext_t */ +#define _UC_GREGS 0 +#define _UC_FREGS 192 +#define _UC_VREGS 464 +#define _UC_VSCR 976 +#define _UC_VRSAVE 980 diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/ucontext_i.sym b/sysdeps/unix/sysv/linux/powerpc/powerpc32/ucontext_i.sym deleted file mode 100644 index 293761f260..0000000000 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/ucontext_i.sym +++ /dev/null @@ -1,26 +0,0 @@ -#include <stddef.h> -#include <signal.h> -#include <sys/ucontext.h> - --- - -SIG_BLOCK -SIG_SETMASK - --- Offsets in ucontext_t. -#define ucontext(member) offsetof (ucontext_t, member) -_UC_LINK ucontext (uc_link) -_UC_STACK_SP ucontext (uc_stack.ss_sp) -_UC_STACK_SIZE ucontext (uc_stack.ss_size) -_UC_REGS_PTR ucontext (uc_mcontext.uc_regs) -_UC_SIGMASK ucontext (uc_sigmask) -_UC_REG_SPACE ucontext (uc_reg_space) - --- Offsets in mcontext_t. -#define mcontext(member) offsetof (mcontext_t, member) -_UC_GREGS mcontext (gregs) -_UC_FREGS mcontext (fpregs) -_UC_VREGS mcontext (vrregs) -_UC_VREGS mcontext (vrregs) -_UC_VSCR mcontext (vrregs.vscr) -_UC_VRSAVE mcontext (vrregs.vrsave) diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/vfork.S b/sysdeps/unix/sysv/linux/powerpc/powerpc32/vfork.S index 66a149f10b..5fb7868c31 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/vfork.S +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/vfork.S @@ -50,7 +50,7 @@ ENTRY (__vfork) bnslr+ .Lsyscall_error: - b __syscall_error@local + b JUMPTARGET(__syscall_error) #endif PSEUDO_END (__vfork) |