summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libc/sysdeps/linux/mips/Makefile2
-rw-r--r--libc/sysdeps/linux/mips/clone.S148
-rw-r--r--libc/sysdeps/linux/mips/sysdep-nptl.h2
-rw-r--r--libc/sysdeps/linux/mips/sysdep.h7
-rw-r--r--libc/sysdeps/linux/mips/vfork.S39
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/mips/Makefile2
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/mips/clone.S2
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/mips/pt-vfork.S6
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/mips/vfork.S42
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>