diff options
-rw-r--r-- | libc/sysdeps/linux/mips/Makefile | 2 | ||||
-rw-r--r-- | libc/sysdeps/linux/mips/clone.S | 148 | ||||
-rw-r--r-- | libc/sysdeps/linux/mips/sysdep-nptl.h | 2 | ||||
-rw-r--r-- | libc/sysdeps/linux/mips/sysdep.h | 7 | ||||
-rw-r--r-- | libc/sysdeps/linux/mips/vfork.S | 39 | ||||
-rw-r--r-- | libpthread/nptl/sysdeps/unix/sysv/linux/mips/Makefile | 2 | ||||
-rw-r--r-- | libpthread/nptl/sysdeps/unix/sysv/linux/mips/clone.S | 2 | ||||
-rw-r--r-- | libpthread/nptl/sysdeps/unix/sysv/linux/mips/pt-vfork.S | 6 | ||||
-rw-r--r-- | libpthread/nptl/sysdeps/unix/sysv/linux/mips/vfork.S | 42 |
9 files changed, 143 insertions, 107 deletions
diff --git a/libc/sysdeps/linux/mips/Makefile b/libc/sysdeps/linux/mips/Makefile index bcfcb0b59..cec19a378 100644 --- a/libc/sysdeps/linux/mips/Makefile +++ b/libc/sysdeps/linux/mips/Makefile @@ -24,7 +24,7 @@ CRT_OBJ = crt1.o SCRT_OBJ = $(patsubst %,S%, $(CRT_OBJ)) CTOR_TARGETS=$(TOPDIR)lib/crti.o $(TOPDIR)lib/crtn.o -SSRC=bsd-_setjmp.S bsd-setjmp.S setjmp.S clone.S syscall.S pipe.S +SSRC=bsd-_setjmp.S bsd-setjmp.S setjmp.S clone.S syscall.S pipe.S vfork.S SOBJS=$(patsubst %.S,%.o, $(SSRC)) CSRC=__longjmp.c brk.c setjmp_aux.c mmap.c __syscall_error.c \ diff --git a/libc/sysdeps/linux/mips/clone.S b/libc/sysdeps/linux/mips/clone.S index 21cb8ec61..8486da783 100644 --- a/libc/sysdeps/linux/mips/clone.S +++ b/libc/sysdeps/linux/mips/clone.S @@ -1,6 +1,6 @@ -/* Copyright (C) 1996, 1997, 2000 Free Software Foundation, Inc. +/* Copyright (C) 1996, 1997, 2000, 2003, 2005 Free Software Foundation, Inc. This file is part of the GNU C Library. - Contributed by Ralf Baechle <ralf@gnu.ai.mit.edu>, 1996. + Contributed by Ralf Baechle <ralf@linux-mips.org>, 1996. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -20,86 +20,121 @@ /* clone() is even more special than fork() as it mucks with stacks and invokes a function in the right context after its all over. */ -#include <asm/unistd.h> -#include <sys/regdef.h> +#include <sys/asm.h> +#include <sysdep.h> #define _ERRNO_H 1 #include <bits/errno.h> -#include <asm/asm.h> +#ifdef RESET_PID +#include <tls.h> +#endif + +#define CLONE_VM 0x00000100 +#define CLONE_THREAD 0x00010000 -/* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg) */ +/* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg, + void *parent_tidptr, void *tls, void *child_tidptr) */ .text -.globl __clone ; - .align 2; - .type __clone,@function; - .ent __clone, 0; - -__clone: - .frame sp, 4*SZREG, sp -#ifdef __PIC__ - .set noreorder - .cpload $25 - .set reorder - subu sp,32 - .cprestore 16 +#if _MIPS_SIM == _ABIO32 +# define EXTRA_LOCALS 1 #else - subu sp,32 +# define EXTRA_LOCALS 0 +#endif +LOCALSZ= 4 +FRAMESZ= (((NARGSAVE+LOCALSZ)*SZREG)+ALSZ)&ALMASK +GPOFF= FRAMESZ-(1*SZREG) +NESTED(__clone,4*SZREG,sp) +#ifdef __PIC__ + SETUP_GP +#endif + PTR_SUBU sp, FRAMESZ + SETUP_GP64 (GPOFF, __clone) +#ifdef __PIC__ + SAVE_GP (GPOFF) +#endif +#ifdef PROF + .set noat + move $1,ra + jal _mcount + .set at #endif /* Sanity check arguments. */ li v0,EINVAL - beqz a0,error /* No NULL function pointers. */ - beqz a1,error /* No NULL stack pointers. */ + beqz a0,L(error) /* No NULL function pointers. */ + beqz a1,L(error) /* No NULL stack pointers. */ + + PTR_SUBU a1,32 /* Reserve argument save space. */ + PTR_S a0,0(a1) /* Save function pointer. */ + PTR_S a3,PTRSIZE(a1) /* Save argument pointer. */ +#ifdef RESET_PID + LONG_S a2,(PTRSIZE*2)(a1) /* Save clone flags. */ +#endif - subu a1,32 /* Reserve argument save space. */ - sw a0,0(a1) /* Save function pointer. */ - sw a3,4(a1) /* Save argument pointer. */ + move a0,a2 + /* Shuffle in the last three arguments - arguments 5, 6, and 7 to + this function, but arguments 3, 4, and 5 to the syscall. */ +#if _MIPS_SIM == _ABIO32 + PTR_L a2,(FRAMESZ+PTRSIZE+PTRSIZE+16)(sp) + PTR_S a2,16(sp) + PTR_L a2,(FRAMESZ+16)(sp) + PTR_L a3,(FRAMESZ+PTRSIZE+16)(sp) +#else + move a2,a4 + move a3,a5 + move a4,a6 +#endif /* Do the system call */ - move a0,a2 li v0,__NR_clone syscall - bnez a3,error - beqz v0,__thread_start + bnez a3,L(error) + beqz v0,L(thread_start) /* Successful return from the parent */ - addiu sp,32 - j $31 ; nop + RESTORE_GP64 + PTR_ADDU sp, FRAMESZ + j ra + nop /* Something bad happened -- no child created */ -error: - addiu sp,32 - - /* uClibc change -- start */ - move a0,v0 /* Pass return val to C function. */ - /* uClibc change -- stop */ - +L(error): #ifdef __PIC__ - la t9,__syscall_error + PTR_LA t9,__syscall_error + RESTORE_GP64 + PTR_ADDU sp, FRAMESZ jr t9 #else + RESTORE_GP64 + PTR_ADDU sp, FRAMESZ j __syscall_error #endif - .end __clone + END(__clone) /* Load up the arguments to the function. Put this block of code in its own function so that we can terminate the stack trace with our debug info. */ -.globl __thread_start; - .align 2; - .ent __thread_start, 0; - -__thread_start: +LEAF(__thread_start) +L(thread_start): /* cp is already loaded. */ - .cprestore 16 + SAVE_GP (GPOFF) /* The stackframe has been created on entry of clone(). */ + +#ifdef RESET_PID + /* Check and see if we need to reset the PID. */ + LONG_L a0,(PTRSIZE*2)(sp) + and a1,a0,CLONE_THREAD + beqz a1,L(restore_pid) +L(donepid): +#endif + /* Restore the arg for user's function. */ - lw t9,0(sp) /* Function pointer. */ - lw a0,4(sp) /* Argument pointer. */ + PTR_L t9,0(sp) /* Function pointer. */ + PTR_L a0,PTRSIZE(sp) /* Argument pointer. */ /* Call the user's function. */ jal t9 @@ -107,12 +142,27 @@ __thread_start: /* Call _exit rather than doing it inline for breakpoint purposes. */ move a0,v0 #ifdef __PIC__ - la t9,_exit + PTR_LA t9,_exit jalr t9 #else jal _exit #endif - .end __thread_start + +#ifdef RESET_PID +L(restore_pid): + and a1,a0,CLONE_VM + li v0,-1 + bnez a1,L(gotpid) + li v0,__NR_getpid + syscall +L(gotpid): + READ_THREAD_POINTER(v1) + INT_S v0,PID_OFFSET(v1) + INT_S v0,TID_OFFSET(v1) + b L(donepid) +#endif + + END(__thread_start) .weak clone; clone = __clone diff --git a/libc/sysdeps/linux/mips/sysdep-nptl.h b/libc/sysdeps/linux/mips/sysdep-nptl.h index 2cc897cdb..e364d774a 100644 --- a/libc/sysdeps/linux/mips/sysdep-nptl.h +++ b/libc/sysdeps/linux/mips/sysdep-nptl.h @@ -193,7 +193,7 @@ #ifdef __ASSEMBLER__ -#include <regdef.h> +#include <sys/regdef.h> #define ENTRY(name) \ .globl name; \ diff --git a/libc/sysdeps/linux/mips/sysdep.h b/libc/sysdeps/linux/mips/sysdep.h index da8eacded..f9778b2d1 100644 --- a/libc/sysdeps/linux/mips/sysdep.h +++ b/libc/sysdeps/linux/mips/sysdep.h @@ -17,6 +17,7 @@ not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include <sys/syscall.h> +#include <sys/regdef.h> #include <features.h> /* Not that using a `PASTE' macro loses. */ @@ -130,3 +131,9 @@ Cambridge, MA 02139, USA. */ #ifdef __PTHREADS_NATIVE__ #include <sysdep-nptl.h> #endif + +#if _MIPS_SIM == _ABIO32 +# define L(label) $L ## label +#else +# define L(label) .L ## label +#endif diff --git a/libc/sysdeps/linux/mips/vfork.S b/libc/sysdeps/linux/mips/vfork.S index bdac50b02..0dbf62e31 100644 --- a/libc/sysdeps/linux/mips/vfork.S +++ b/libc/sysdeps/linux/mips/vfork.S @@ -20,11 +20,37 @@ #include <sys/asm.h> #include <sysdep.h> -#ifndef __UCLIBC__ -#include <asm/unistd.h> -#endif #include <sgidefs.h> +#ifdef __PTHREADS_NATIVE__ +#include <tls.h> + +/* Save the PID value. */ +#ifndef SAVE_PID +#define SAVE_PID \ + READ_THREAD_POINTER(v1); /* Get the thread pointer. */ \ + lw a2, PID_OFFSET(v1); /* Load the saved PID. */ \ + subu a2, $0, a2; /* Negate it. */ \ + bnez a2, 1f; /* If it was zero... */ \ + lui a2, 0x8000; /* use 0x80000000 instead. */ \ +1: sw a2, PID_OFFSET(v1); /* Store the temporary PID. */ +#endif + +/* Restore the old PID value in the parent. */ +#ifndef RESTORE_PID +#define RESTORE_PID \ + beqz v0, 1f; /* If we are the parent... */ \ + READ_THREAD_POINTER(v1); /* Get the thread pointer. */ \ + lw a2, PID_OFFSET(v1); /* Load the saved PID. */ \ + subu a2, $0, a2; /* Re-negate it. */ \ + lui a0, 0x8000; /* Load 0x80000000... */ \ + bne a2, a0, 2f; /* ... compare against it... */ \ + li a2, 0; /* ... use 0 instead. */ \ +2: sw a2, PID_OFFSET(v1); /* Restore the PID. */ \ +1: +#endif +#endif + #ifndef SAVE_PID #define SAVE_PID #endif @@ -82,7 +108,8 @@ NESTED(__vfork,FRAMESZ,sp) /* Successful return from the parent or child. */ RESTORE_GP64 - ret + j ra + nop /* Something bad happened -- no child created. */ L(error): @@ -96,5 +123,5 @@ L(error): #endif END(__vfork) -libc_hidden_def(__vfork) -weak_alias (__vfork, vfork) +.weak vfork; + vfork = __vfork diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/mips/Makefile b/libpthread/nptl/sysdeps/unix/sysv/linux/mips/Makefile index 1978413ea..dd2bda972 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/mips/Makefile +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/mips/Makefile @@ -21,7 +21,7 @@ TOPDIR=../../../../../../../ include $(TOPDIR)Rules.mak include ../../../../../Rules.mak -ASRC-LIBP-ST = pt-vfork.S +ASRC-LIBP-ST = pt-vfork.S clone.S ASRC-LIBP-SH = $(ASRC-LIBP-ST) CSRC-LIBP-ST = pthread_once.c diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/mips/clone.S b/libpthread/nptl/sysdeps/unix/sysv/linux/mips/clone.S index 80c265bf6..add405523 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/mips/clone.S +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/mips/clone.S @@ -1,2 +1,2 @@ #define RESET_PID -#include <sysdeps/unix/sysv/linux/mips/clone.S> +#include <../../../../../../../libc/sysdeps/linux/mips/clone.S> diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/mips/pt-vfork.S b/libpthread/nptl/sysdeps/unix/sysv/linux/mips/pt-vfork.S index f82504329..c02ffca93 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/mips/pt-vfork.S +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/mips/pt-vfork.S @@ -35,10 +35,4 @@ sw a2, PID_OFFSET(v1); /* Restore the PID. */ \ 1: -#ifdef __UCLIBC__ -#undef weak_alias -#define weak_alias(name, aliasname) #include <../../../../../../../libc/sysdeps/linux/mips/vfork.S> -#else -#include <../sysdeps/unix/sysv/linux/mips/vfork.S> -#endif diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/mips/vfork.S b/libpthread/nptl/sysdeps/unix/sysv/linux/mips/vfork.S deleted file mode 100644 index 874a2e2bf..000000000 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/mips/vfork.S +++ /dev/null @@ -1,42 +0,0 @@ -/* Copyright (C) 2005 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 <tls.h> - -/* Save the PID value. */ -#define SAVE_PID \ - READ_THREAD_POINTER(v1); /* Get the thread pointer. */ \ - lw a2, PID_OFFSET(v1); /* Load the saved PID. */ \ - subu a2, $0, a2; /* Negate it. */ \ - bnez a2, 1f; /* If it was zero... */ \ - lui a2, 0x8000; /* use 0x80000000 instead. */ \ -1: sw a2, PID_OFFSET(v1); /* Store the temporary PID. */ - -/* Restore the old PID value in the parent. */ -#define RESTORE_PID \ - beqz v0, 1f; /* If we are the parent... */ \ - READ_THREAD_POINTER(v1); /* Get the thread pointer. */ \ - lw a2, PID_OFFSET(v1); /* Load the saved PID. */ \ - subu a2, $0, a2; /* Re-negate it. */ \ - lui a0, 0x8000; /* Load 0x80000000... */ \ - bne a2, a0, 2f; /* ... compare against it... */ \ - li a2, 0; /* ... use 0 instead. */ \ -2: sw a2, PID_OFFSET(v1); /* Restore the PID. */ \ -1: - -#include <../sysdeps/unix/sysv/linux/mips/vfork.S> |