summaryrefslogtreecommitdiff
path: root/linuxthreads/sysdeps/unix/sysv/linux
diff options
context:
space:
mode:
Diffstat (limited to 'linuxthreads/sysdeps/unix/sysv/linux')
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/arm/sysdep-cancel.h19
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/arm/vfork.S57
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/powerpc/Makefile (renamed from linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc32/Makefile)0
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h102
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/sh/vfork.S57
5 files changed, 229 insertions, 6 deletions
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/arm/sysdep-cancel.h b/linuxthreads/sysdeps/unix/sysv/linux/arm/sysdep-cancel.h
index 5f3709f742..38e472d2ba 100644
--- a/linuxthreads/sysdeps/unix/sysv/linux/arm/sysdep-cancel.h
+++ b/linuxthreads/sysdeps/unix/sysv/linux/arm/sysdep-cancel.h
@@ -27,6 +27,7 @@
# undef PSEUDO_RET
# define PSEUDO_RET \
ldrcc pc, [sp], $4; \
+ ldr lr, [sp], $4; \
b PLTJMP(SYSCALL_ERROR)
# undef PSEUDO
@@ -34,7 +35,7 @@
.section ".text"; \
PSEUDO_PROLOGUE; \
ENTRY (name) \
- SINGLE_THREAD_P; \
+ SINGLE_THREAD_P_INT; \
bne .Lpseudo_cancel; \
DO_CALL (syscall_name, args); \
cmn r0, $4096; \
@@ -74,7 +75,7 @@
# define UNDOC2ARGS_4
# define DOCARGS_5 stmfd sp!, {r0-r3}
-# define UNDOCARGS_5 str r4, [sp, #-4]!; ldmfd sp, {r0-r4}
+# define UNDOCARGS_5 ldmfd sp, {r0-r3}; str r4, [sp, #-4]!; ldr r4, [sp, #24]
# define UNDOC2ARGS_5 ldr r4, [sp], #20
# ifdef IS_IN_libpthread
@@ -92,10 +93,11 @@ extern int __local_multiple_threads attribute_hidden;
# define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1)
# else
# if !defined PIC
-# define SINGLE_THREAD_P \
+# define SINGLE_THREAD_P_INT \
ldr ip, =__local_multiple_threads; \
ldr ip, [ip]; \
teq ip, #0;
+# define SINGLE_THREAD_P SINGLE_THREAD_P_INT
# define MAYBE_SAVE_LR \
str lr, [sp, $-4]!;
# define PSEUDO_RET_MOV \
@@ -103,14 +105,19 @@ extern int __local_multiple_threads attribute_hidden;
b PLTJMP(SYSCALL_ERROR)
# define PSEUDO_PROLOGUE
# else
-# define SINGLE_THREAD_P \
- str lr, [sp, $-4]!; \
+# define SINGLE_THREAD_P_PIC(reg) \
ldr ip, 1b; \
- ldr lr, 2b; \
+ ldr reg, 2b; \
3: \
add ip, pc, ip; \
ldr ip, [ip, lr]; \
teq ip, #0;
+# define SINGLE_THREAD_P_INT \
+ str lr, [sp, $-4]!; \
+ SINGLE_THREAD_P_PIC(lr)
+# define SINGLE_THREAD_P \
+ SINGLE_THREAD_P_INT; \
+ ldr lr, [sp], $4
# define PSEUDO_PROLOGUE \
1: .word _GLOBAL_OFFSET_TABLE_ - 3f - 8; \
2: .word __local_multiple_threads(GOTOFF);
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/arm/vfork.S b/linuxthreads/sysdeps/unix/sysv/linux/arm/vfork.S
new file mode 100644
index 0000000000..6092bd9fd4
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/arm/vfork.S
@@ -0,0 +1,57 @@
+/* Copyright (C) 1999, 2002, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Philip Blundell <philb@gnu.org>.
+
+ 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-cancel.h>
+#define _ERRNO_H 1
+#include <bits/errno.h>
+
+/* Clone the calling process, but without copying the whole address
+pace.
+ The calling process is suspended until the new process exits or is
+ replaced by a call to `execve'. Return -1 for errors, 0 to the new
+rocess,
+ and the process ID of the new process to the old process. */
+
+ PSEUDO_PROLOGUE
+
+ENTRY (__vfork)
+
+#ifdef __NR_vfork
+ SINGLE_THREAD_P
+ bne HIDDEN_JUMPTARGET (__fork)
+ swi __NR_vfork
+ cmn a1, #4096
+ RETINSTR(movcc, pc, lr)
+
+ /* Check if vfork syscall is known at all. */
+ ldr a2, =-ENOSYS
+ teq a1, a2
+ bne PLTJMP(C_SYMBOL_NAME(__syscall_error))
+#endif
+
+ /* If we don't have vfork, fork is close enough. */
+ swi __NR_fork
+ cmn a1, #4096
+ RETINSTR(movcc, pc, lr)
+ b PLTJMP(C_SYMBOL_NAME(__syscall_error))
+
+PSEUDO_END (__vfork)
+libc_hidden_def (__vfork)
+
+weak_alias (__vfork, vfork)
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc32/Makefile b/linuxthreads/sysdeps/unix/sysv/linux/powerpc/Makefile
index e98c9bd866..e98c9bd866 100644
--- a/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc32/Makefile
+++ b/linuxthreads/sysdeps/unix/sysv/linux/powerpc/Makefile
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h b/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h
new file mode 100644
index 0000000000..58257a17b2
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h
@@ -0,0 +1,102 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Franz Sirl <Franz.Sirl-kernel@lauterbach.com>, 2003.
+
+ 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>
+#ifndef __ASSEMBLER__
+# include <linuxthreads/internals.h>
+#endif
+
+#if !defined NOT_IN_libc || defined IS_IN_libpthread
+
+# undef PSEUDO
+# define PSEUDO(name, syscall_name, args) \
+ .section ".text"; \
+ ENTRY (name) \
+ SINGLE_THREAD_P; \
+ bne- .Lpseudo_cancel; \
+ DO_CALL (SYS_ify (syscall_name)); \
+ PSEUDO_RET; \
+ .Lpseudo_cancel: \
+ stdu 1,-128(1); \
+ mflr 9; \
+ std 9,128+16(1); \
+ DOCARGS_##args; /* save syscall args around CENABLE. */ \
+ CENABLE; \
+ std 3,72(1); /* store CENABLE return value (MASK). */ \
+ UNDOCARGS_##args; /* restore syscall args. */ \
+ DO_CALL (SYS_ify (syscall_name)); \
+ mfcr 0; /* save CR/R3 around CDISABLE. */ \
+ std 3,64(1); \
+ std 0,8(1); \
+ ld 3,72(1); /* pass MASK to CDISABLE. */ \
+ CDISABLE; \
+ ld 9,128+16(1); \
+ ld 0,8(1); /* restore CR/R3. */ \
+ ld 3,64(1); \
+ mtlr 9; \
+ mtcr 0; \
+ addi 1,1,128;
+
+# define DOCARGS_0
+# define UNDOCARGS_0
+
+# define DOCARGS_1 std 3,80(1); DOCARGS_0
+# define UNDOCARGS_1 ld 3,80(1); UNDOCARGS_0
+
+# define DOCARGS_2 std 4,88(1); DOCARGS_1
+# define UNDOCARGS_2 ld 4,88(1); UNDOCARGS_1
+
+# define DOCARGS_3 std 5,96(1); DOCARGS_2
+# define UNDOCARGS_3 ld 5,96(1); UNDOCARGS_2
+
+# define DOCARGS_4 std 6,104(1); DOCARGS_3
+# define UNDOCARGS_4 ld 6,104(1); UNDOCARGS_3
+
+# define DOCARGS_5 std 7,112(1); DOCARGS_4
+# define UNDOCARGS_5 ld 7,112(1); UNDOCARGS_4
+
+# define DOCARGS_6 std 8,120(1); DOCARGS_5
+# define UNDOCARGS_6 ld 8,120(1); UNDOCARGS_5
+
+# ifdef IS_IN_libpthread
+# define CENABLE bl JUMPTARGET(__pthread_enable_asynccancel)
+# define CDISABLE bl JUMPTARGET(__pthread_disable_asynccancel)
+# define __local_multiple_threads __pthread_multiple_threads
+# else
+# define CENABLE bl JUMPTARGET(__libc_enable_asynccancel)
+# define CDISABLE bl JUMPTARGET(__libc_disable_asynccancel)
+# define __local_multiple_threads __libc_multiple_threads
+# endif
+
+# ifndef __ASSEMBLER__
+extern int __local_multiple_threads attribute_hidden;
+# define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1)
+# else
+# define SINGLE_THREAD_P \
+ ld 10,__local_multiple_threads@got(2); \
+ ld 10,0(10); \
+ cmpdi 10,0
+# endif
+
+#elif !defined __ASSEMBLER__
+
+/* This code should never be used but we define it anyhow. */
+# define SINGLE_THREAD_P (1)
+
+#endif
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/sh/vfork.S b/linuxthreads/sysdeps/unix/sysv/linux/sh/vfork.S
new file mode 100644
index 0000000000..f796e31088
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/sh/vfork.S
@@ -0,0 +1,57 @@
+/* Copyright (C) 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
+ 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-cancel.h>
+#define _ERRNO_H 1
+#include <bits/errno.h>
+
+/* Clone the calling process, but without copying the whole address space.
+ The calling process is suspended until the new process exits or is
+ replaced by a call to `execve'. Return -1 for errors, 0 to the new process,
+ and the process ID of the new process to the old process. */
+
+ENTRY (__vfork)
+ SINGLE_THREAD_P
+ bf .Lhidden_fork
+
+ mov.w .L1, r3
+ trapa #0x10
+ mov r0, r1
+ mov #-12, r2
+ shad r2, r1
+ not r1, r1 // r1=0 means r0 = -1 to -4095
+ tst r1, r1 // i.e. error in linux
+ bf .Lpseudo_end
+ SYSCALL_ERROR_HANDLER
+.Lpseudo_end:
+ rts
+ nop
+.L1: .word __NR_vfork
+
+.Lhidden_fork:
+ mov.l .L2, r1
+ braf r1
+ nop
+1:
+ .align 2
+.L2: .long HIDDEN_JUMPTARGET(__fork)-1b
+
+PSEUDO_END (__vfork)
+libc_hidden_def (__vfork)
+
+weak_alias (__vfork, vfork)