|
@@ -1,88 +1,59 @@
|
|
|
-
|
|
|
- * clone syscall for OpenRISC
|
|
|
- *
|
|
|
- * Copyright (c) 2010 Jonas Bonn <jonas@southpole.se>
|
|
|
- * Copyright (C) 2003 John Williams <jwilliams@itee.uq.edu.au>
|
|
|
- * Copyright (C) 2002,03 NEC Electronics Corporation
|
|
|
- * Copyright (C) 2002,03 Miles Bader <miles@gnu.org>
|
|
|
- *
|
|
|
- * This file is subject to the terms and conditions of the GNU Lesser
|
|
|
- * General Public License. See the file COPYING.LIB in the main
|
|
|
- * directory of this archive for more details.
|
|
|
- *
|
|
|
- * OpenRISC port by Jonas Bonn <jonas@southpole.se>
|
|
|
- */
|
|
|
+
|
|
|
+ This file is part of the GNU C Library.
|
|
|
|
|
|
-#include <errno.h>
|
|
|
-#include <sys/syscall.h>
|
|
|
-#include <sched.h>
|
|
|
-#include <unistd.h>
|
|
|
-
|
|
|
-
|
|
|
- int clone (int (*fn)(void *arg), void *child_stack, int flags, void *arg, ...)
|
|
|
- the kernel entry is:
|
|
|
- int clone (long flags, void *child_stack)
|
|
|
-*/
|
|
|
-
|
|
|
-int
|
|
|
-clone (int (*fn)(void *arg), void *child_stack, int flags, void *arg, ...)
|
|
|
-{
|
|
|
- int err;
|
|
|
-
|
|
|
-
|
|
|
- * OR1K GCC does weird things with varargs functions... the last
|
|
|
- * parameter is NEVER passed on the stack -- i.e. arg, in this case.
|
|
|
- * So we need to push at least 'arg' onto the child stack so that
|
|
|
- * the new thread can find it. Just to be totally safe, we'll
|
|
|
- * push both 'fn' and 'arg'; that way we don't need to care what
|
|
|
- * GCC does with parameters, whether they are passed in registers
|
|
|
- * or on stack.
|
|
|
- */
|
|
|
+ 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.
|
|
|
|
|
|
-
|
|
|
- __asm__ __volatile__ (
|
|
|
- "l.sw -4(%0),%1;"
|
|
|
- "l.sw -8(%0),%2;"
|
|
|
- :
|
|
|
- : "r" (child_stack), "r" (fn), "r" (arg)
|
|
|
- );
|
|
|
+ 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.
|
|
|
|
|
|
-
|
|
|
- err = -EINVAL;
|
|
|
- if (!fn)
|
|
|
- goto syscall_error;
|
|
|
- if (!child_stack)
|
|
|
- goto syscall_error;
|
|
|
+ You should have received a copy of the GNU Lesser General Public
|
|
|
+ License along with the GNU C Library; if not, see
|
|
|
+ <http:
|
|
|
|
|
|
- err = INLINE_SYSCALL(clone, 2, flags, child_stack);
|
|
|
-
|
|
|
-
|
|
|
- *
|
|
|
- * Do not use any functions here that may write data _up_
|
|
|
- * onto the stack because they will overwrite the child's
|
|
|
- * thread descriptor... i.e. don't use printf
|
|
|
- */
|
|
|
-
|
|
|
- if (err < 0)
|
|
|
- goto syscall_error;
|
|
|
- else if (err != 0) {
|
|
|
- return err;
|
|
|
- }
|
|
|
+#include <stdarg.h>
|
|
|
+#include <sysdep.h>
|
|
|
+#include <unistd.h>
|
|
|
|
|
|
-
|
|
|
+extern int __or1k_clone (int (*fn)(void *), void *child_stack,
|
|
|
+ int flags, void *arg, pid_t *ptid,
|
|
|
+ void *tls, pid_t *ctid);
|
|
|
|
|
|
-
|
|
|
- __asm__ __volatile__ (
|
|
|
- "l.lwz %0,-4(%2);"
|
|
|
- "l.lwz %1,-8(%2);"
|
|
|
- : "=&r" (fn), "=r" (arg)
|
|
|
- : "r" (child_stack)
|
|
|
- : "0", "1"
|
|
|
- );
|
|
|
|
|
|
- _exit(fn(arg));
|
|
|
+
|
|
|
+ * This function moves from varargs to regs. */
|
|
|
+int
|
|
|
+__clone (int (*fn)(void *), void *child_stack,
|
|
|
+ int flags, void *arg, ...
|
|
|
+ )
|
|
|
+{
|
|
|
+ void *ptid;
|
|
|
+ void *tls;
|
|
|
+ void *ctid;
|
|
|
+ va_list ap;
|
|
|
+ int err;
|
|
|
+
|
|
|
+ va_start (ap, arg);
|
|
|
+ ptid = va_arg (ap, void *);
|
|
|
+ tls = va_arg (ap, void *);
|
|
|
+ ctid = va_arg (ap, void *);
|
|
|
+ va_end (ap);
|
|
|
+
|
|
|
+
|
|
|
+ err = -EINVAL;
|
|
|
+ if (!fn)
|
|
|
+ goto syscall_error;
|
|
|
+ if (!child_stack)
|
|
|
+ goto syscall_error;
|
|
|
+
|
|
|
+ return __or1k_clone (fn, child_stack, flags, arg, ptid, tls, ctid);
|
|
|
|
|
|
syscall_error:
|
|
|
- __set_errno (-err);
|
|
|
- return -1;
|
|
|
+ __set_errno (-err);
|
|
|
+ return -1;
|
|
|
}
|
|
|
+weak_alias (__clone, clone)
|