diff options
author | Ulrich Drepper <drepper@redhat.com> | 2003-01-17 01:02:24 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2003-01-17 01:02:24 +0000 |
commit | 609b4783564008cafdeb947bfd613a1bcb5946f6 (patch) | |
tree | ec4d830d2bf9d55decdf5bc941ececfe91e71d7d /sysdeps/unix/sysv/linux/powerpc/powerpc64/makecontext.S | |
parent | 7b7b9e70ea0d820c863c78fbf84fe52626a408d6 (diff) | |
download | glibc-609b4783564008cafdeb947bfd613a1bcb5946f6.tar.gz glibc-609b4783564008cafdeb947bfd613a1bcb5946f6.tar.xz glibc-609b4783564008cafdeb947bfd613a1bcb5946f6.zip |
Update.
2003-01-16 Steven Munroe <sjmunroe@us.ibm.com> * sysdeps/unix/sysv/linux/powerpc/powerpc64/getcontext.S: New file. * sysdeps/unix/sysv/linux/powerpc/powerpc64/makecontext.S: New file. * sysdeps/unix/sysv/linux/powerpc/powerpc64/setcontext.S: New file. * sysdeps/unix/sysv/linux/powerpc/powerpc64/swapcontext.S: New file. * sysdeps/unix/sysv/linux/powerpc/powerpc64/ucontext_i.h: New file. * sysdeps/unix/sysv/linux/powerpc/sys/ucontext.h: New file. * sysdeps/unix/sysv/linux/configure.in: Minimum kernel for PPC64 is 2.4.21. 2003-01-16 Ulrich Drepper <drepper@redhat.com> * sysdeps/generic/glob.c (glob): Assume sysconf() always returns values != -1 for _LIBC. Use extend_alloca to reallocate alloca'ed buffers. * sysdeps/generic/sysconf.c: Unconditionally implement _SC_GETPW_R_SIZE_MAX and _SC_GETGR_R_SIZE_MAX. * sysdeps/posix/sysconf.c: Likewise.
Diffstat (limited to 'sysdeps/unix/sysv/linux/powerpc/powerpc64/makecontext.S')
-rw-r--r-- | sysdeps/unix/sysv/linux/powerpc/powerpc64/makecontext.S | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/makecontext.S b/sysdeps/unix/sysv/linux/powerpc/powerpc64/makecontext.S new file mode 100644 index 0000000000..29dd17ffe4 --- /dev/null +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/makecontext.S @@ -0,0 +1,161 @@ +/* Create new context. + 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. */ + +#include <sysdep.h> + +#define __ASSEMBLY__ +#include <asm/ptrace.h> +#include "ucontext_i.h" + +ENTRY(__makecontext) + /* Save parameters into the parameter save area of callers frame. */ + std r3,FRAME_PARM1_SAVE(r1) /* ucontext_t *ucp */ + std r4,FRAME_PARM2_SAVE(r1) /* void (*func)(void) */ + std r5,FRAME_PARM3_SAVE(r1) /* int argc */ + std r6,FRAME_PARM4_SAVE(r1) /* ... */ + std r7,FRAME_PARM5_SAVE(r1) + std r8,FRAME_PARM6_SAVE(r1) + std r9,FRAME_PARM7_SAVE(r1) + std r10,FRAME_PARM8_SAVE(r1) + mflr r0 + /* Get the address of the target functions first parameter. */ + addi r6,r1,FRAME_PARM4_SAVE + std r0,FRAME_LR_SAVE(r1) + stdu r1,-128(r1) + + /* Get the ucontexts stack pointer and size. Compute the top of stack + and round down to a quadword boundary. Then stack a dummy frame + with a null back chain. We store the context pointer in the frames + "compiler double word" field so we can recover if is the function + returns. Finally save the callers link register and TOC pointer + into this frame so the debugger can display a backtrace. + */ + ld r7,UCONTEXT_STACK_SP(r3) + ld r0,UCONTEXT_STACK_SIZE(r3) + add r7,r7,r0 + clrrdi r7,r7,4 + li r0,0 + stdu r0,-48(r7) + std r3,24(r7) + mflr r0 + std r2,FRAME_TOC_SAVE(r7) /* Store the TOC pointer for later. */ + std r0,FRAME_LR_SAVE(r7) + + /* Now we need to stack another frame to hold the parameter save area + for the function. We need to allocate a frame with the minimum 48 + byte header and 8 parameter register. However if there are more + than 8 parameters addition space is need to hold all the parameters. + The total size it rounded up to a quadword multiple then a frame is + stacked. This address is stored in the ucontext as GPR 1. */ + + cmpdi cr1,r5,8 + sldi r8,r5,3 + bgt cr1,L(gt8) + li r8,64 +L(gt8): + addi r8,r8,FRAME_PARM_SAVE+8 /* Add header plus rounding factor. */ + clrrdi r8,r8,4 /* Round down to quadword. */ + + subf r8,r8,r7 + std r7,0(r8) /* Stack the frame. */ + std r8,(SIGCONTEXT_GP_REGS+(PT_R1*8))(r3) + + /* Now we need to copy the target functions parameters. The functions + parameters are saved in the parameter save area. We skip over the + first three parameters and copy up to 8 double word into the + SIGCONTEXT_GP_REGS starting with R3. If there are more than 8 + parameters then doublewords 8-N are copied into the parameter + save area of the context frame. */ + cmpdi r5,0 + beq L(noparms) + mr r0,r5 + ble cr1,L(le8) + li r0,8 +L(le8): + mtctr r0 + addi r7,r6,-8 + addi r9,r3,(SIGCONTEXT_GP_REGS+(PT_R3*8)-8) +L(parmloop2): + ldu r0,8(r7) + stdu r0,8(r9) + bdnz L(parmloop2) + + addi r0,r5,-8 + ble cr1,L(noparms) + mtctr r0 + addi r9,r8,FRAME_PARM9_SAVE-8 +L(parmloop): + ldu r0,8(r7) + stdu r0,8(r9) + bdnz L(parmloop) + +L(noparms): + + /* Load the function address and TOC from the function descriptor + and store them in the ucontext as NIP and r2. Store the 3rd + field of the function descriptor into the ucontext as r11 in case + the calling language needs the "environment pointer". */ + ld r0,0(r4) + ld r10,8(r4); + ld r9,16(r4); + std r0,(SIGCONTEXT_GP_REGS+(PT_NIP*8))(r3) + std r10,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r3) + std r9,(SIGCONTEXT_GP_REGS+(PT_R11*8))(r3) + + /* If the target function returns we need to do some cleanup. We use a + code trick to get the address of our cleanup function into the link + register. Do not add any code between here and L(exitcode). */ + bl L(gotexitcodeaddr); + + /* This is the helper code which gets called if a function which + is registered with 'makecontext' returns. In this case we + have to install the context listed in the uc_link element of + the context 'makecontext' manipulated at the time of the + 'makecontext' call. If the pointer is NULL the process must + terminate. */ +L(exitcode): + /* Recover the ucontext and TOC from the dummy frame. */ + ld r1,FRAME_BACKCHAIN(r1) /* Unstack the parameter save area frame. */ + ld r3,FRAME_COMPILER_DW(r1) + ld r2,FRAME_TOC_SAVE(r1) + ld r3,UCONTEXT_LINK(r3) /* Load the resume context. */ + cmpdi r3,0 + beq L(BADSTATUS) + bl JUMPTARGET(__setcontext) + nop + +L(BADSTATUS): +/* If setcontext returns (which can happen if the syscall fails) we will + exit the program with error status (-1). */ + li r3,-1 + b JUMPTARGET(exit); + + /* The address of the exit code is in the link register. Store the lr + in the ucontext as LNK so the target function will return to our + exit code. */ +L(gotexitcodeaddr): + mflr r0 + std r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r3) + ld r0,128+FRAME_LR_SAVE(r1) + addi r1,r1,128 + mtlr r0 + blr +END(__makecontext) + +weak_alias(__makecontext, makecontext) |