summaryrefslogtreecommitdiff
path: root/libc/sysdeps/linux/xtensa/vfork.S
diff options
context:
space:
mode:
Diffstat (limited to 'libc/sysdeps/linux/xtensa/vfork.S')
-rw-r--r--libc/sysdeps/linux/xtensa/vfork.S104
1 files changed, 52 insertions, 52 deletions
diff --git a/libc/sysdeps/linux/xtensa/vfork.S b/libc/sysdeps/linux/xtensa/vfork.S
index f094ae38f..6aced0a50 100644
--- a/libc/sysdeps/linux/xtensa/vfork.S
+++ b/libc/sysdeps/linux/xtensa/vfork.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005, 2007 Free Software Foundation, Inc.
+/* Copyright (C) 2005-2013 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
@@ -19,72 +19,67 @@
#include <sys/syscall.h>
#define _SIGNAL_H
#include <bits/signum.h>
+#define __ASSEMBLY__
+#include <linux/sched.h>
-/* Clone the calling process, but without copying the whole address space.
+/*
+ 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.
Note that it is important that we don't create a new stack frame for the
- caller. */
+ caller.
-
-/* The following are defined in linux/sched.h, which unfortunately
- is not safe for inclusion in an assembly file. */
-#define CLONE_VM 0x00000100 /* set if VM shared between processes */
-#define CLONE_VFORK 0x00004000 /* set if the parent wants the child to
- wake it up on mm_release */
+*/
#ifndef SAVE_PID
-#define SAVE_PID
+#define SAVE_PID(a,b,c,d)
#endif
-
#ifndef RESTORE_PID
-#define RESTORE_PID
+#define RESTORE_PID(a,b,c)
+#endif
+#ifndef RESTORE_PID12
+#define RESTORE_PID12(a,b,c)
#endif
+/*
+ pid_t vfork(void);
+ Implemented as __clone_syscall(CLONE_VFORK | CLONE_VM | SIGCHLD, 0)
+ */
-/* pid_t vfork(void);
- Implemented as __clone_syscall(CLONE_VFORK | CLONE_VM | SIGCHLD, 0) */
HIDDEN_ENTRY (__vfork)
+ .literal .Ljumptable, 0, .L4, .L8, .L12
- movi a6, .Ljumptable
- extui a2, a0, 30, 2 /* call-size: call4/8/12 = 1/2/3 */
- addx4 a4, a2, a6 /* find return address in jumptable */
- l32i a4, a4, 0
- add a4, a4, a6
-
+ mov a3, a0 # move return address out of the way
+ movi a0, .Ljumptable
+ extui a2, a3, 30, 2 # call-size: call4/8/12 = 1/2/3
+ addx4 a0, a2, a0 # find return address in jumptable
slli a2, a2, 30
- xor a3, a0, a2 /* remove call-size from return addr */
- extui a5, a4, 30, 2 /* get high bits of jump target */
- slli a5, a5, 30
- or a3, a3, a5 /* stuff them into the return address */
- xor a4, a4, a5 /* clear high bits of jump target */
- or a0, a4, a2 /* create temporary return address */
- retw /* "return" to .L4, .L8, or .L12 */
-
- .align 4
-.Ljumptable:
- .word 0
- .word .L4 - .Ljumptable
- .word .L8 - .Ljumptable
- .word .L12 - .Ljumptable
+ l32i a0, a0, 0
+
+ xor a3, a3, a2 # remove call-size from return address
+ or a0, a0, a2 # create temporary return address
+ retw
/* a7: return address */
+
.L4: mov a12, a2
mov a13, a3
- SAVE_PID
+ SAVE_PID(a5,a15,a2,a3)
+
+ /* use syscall 'clone' and set new stack pointer to the same address */
- /* Use syscall 'clone'. Set new stack pointer to the same address. */
- movi a2, SYS_ify (clone)
+ movi a2, SYS_ify(clone)
movi a3, 0
movi a6, CLONE_VM | CLONE_VFORK | SIGCHLD
+
syscall
- RESTORE_PID
+ RESTORE_PID(a5,a15,a2)
movi a5, -4096
@@ -94,22 +89,24 @@ HIDDEN_ENTRY (__vfork)
bgeu a6, a5, 1f
jx a7
-1: call4 .Lerr /* returns to original caller */
+1: call4 .Lerr
/* a11: return address */
+
.L8: mov a12, a2
mov a13, a3
mov a14, a6
- SAVE_PID
+ SAVE_PID(a9,a15,a2,a3)
- movi a2, SYS_ify (clone)
+ movi a2, SYS_ify(clone)
movi a3, 0
movi a6, CLONE_VM | CLONE_VFORK | SIGCHLD
+
syscall
- RESTORE_PID
+ RESTORE_PID(a9,a15,a2)
movi a9, -4096
@@ -120,22 +117,25 @@ HIDDEN_ENTRY (__vfork)
bgeu a10, a9, 1f
jx a11
-1: call8 .Lerr /* returns to original caller */
+
+1: call8 .Lerr
/* a15: return address */
+
.L12: mov a12, a2
mov a13, a3
mov a14, a6
- SAVE_PID
+ SAVE_PID (a2,a3,a2,a6)
- movi a2, SYS_ify (clone)
+ movi a2, SYS_ify(clone)
movi a3, 0
movi a6, CLONE_VM | CLONE_VFORK | SIGCHLD
+
syscall
- RESTORE_PID
+ RESTORE_PID12(a3,a6,a15)
mov a3, a13
movi a13, -4096
@@ -147,18 +147,18 @@ HIDDEN_ENTRY (__vfork)
bgeu a14, a13, 1f
jx a15
-1: call12 .Lerr /* returns to original caller */
+1: call12 .Lerr
.align 4
+
.Lerr: entry a1, 16
- /* Restore the return address. */
- extui a4, a0, 30, 2 /* get the call-size bits */
+ /* Restore return address */
+
+ extui a4, a0, 30, 2
slli a4, a4, 30
- slli a3, a3, 2 /* clear high bits of target address */
- srli a3, a3, 2
- or a0, a3, a4 /* combine them */
+ or a0, a3, a4
PSEUDO_END (__vfork)
.Lpseudo_end: