summaryrefslogtreecommitdiff
path: root/libc/sysdeps/linux/m68k/clone.S
diff options
context:
space:
mode:
authorWaldemar Brodkorb <wbx@uclibc-ng.org>2017-12-16 21:01:39 +0100
committerWaldemar Brodkorb <wbx@uclibc-ng.org>2017-12-31 11:12:07 +0100
commit23bb649090ff588e8642f0c581cfe7ce2d29c757 (patch)
tree4a68d696415fce9f2dd50edf27a79bacbde3fc50 /libc/sysdeps/linux/m68k/clone.S
parent604781391549faafc59516700d9439ab1a7ec19b (diff)
m68k: add NPTL/TLS support
Port over NPTL/TLS support from GNU C Library. In the first step only the slower syscall is used for TLS access. The uClibc-ng testsuite shows 79 errors, so their is room for bugfixes and improvements.
Diffstat (limited to 'libc/sysdeps/linux/m68k/clone.S')
-rw-r--r--libc/sysdeps/linux/m68k/clone.S108
1 files changed, 78 insertions, 30 deletions
diff --git a/libc/sysdeps/linux/m68k/clone.S b/libc/sysdeps/linux/m68k/clone.S
index 7eddff10c..24071235b 100644
--- a/libc/sysdeps/linux/m68k/clone.S
+++ b/libc/sysdeps/linux/m68k/clone.S
@@ -1,54 +1,94 @@
-/* Adapted from glibc */
-/* Copyright (C) 1996, 1997 Free Software Foundation, Inc. */
+/* Copyright (C) 1996-2017 Free Software Foundation, Inc.
+ Contributed by Andreas Schwab (schwab@issan.informatik.uni-dortmund.de)
+
+ 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, see
+ <http://www.gnu.org/licenses/>. */
/* clone is even more special than fork as it mucks with stacks
and invokes a function in the right context after its all over. */
#define _ERRNO_H
+#include <sysdep.h>
#include <features.h>
#include <bits/errno.h>
#include <sys/syscall.h>
#include "m68k_pic.S"
-/* 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
-.align 4
-.type clone,@function
-.globl clone;
-clone:
+ .text
+ .align 4
+ .globl __clone
+ .type __clone,@function
+
+__clone:
/* Sanity check arguments. */
- movel #-EINVAL, %d0
- movel 4(%sp), %d1 /* no NULL function pointers */
- movel %d1, %a0
- tstl %d1
+ movel #-EINVAL, %d0
+ movel 4(%sp), %a0 /* no NULL function pointers */
+ tstl %a0
beq.w __syscall_error_trampoline
- movel 8(%sp), %d1 /* no NULL stack pointers */
- movel %d1, %a1
- tstl %d1
+ movel 8(%sp), %a1 /* no NULL stack pointers */
+ tstl %a1
beq.w __syscall_error_trampoline
/* Allocate space and copy the argument onto the new stack. */
movel 16(%sp), -(%a1)
/* Do the system call */
-#if 1 /* defined (CONFIG_COLDFIRE) */
- movel %d2, %d1 /* save %d2 and get stack pointer */
- movel %a1, %d2
- movel %d1, %a1
+ movel 12(%sp), %d1 /* get flags */
+ movel %d3, -(%a1) /* save %d3 and get parent_tidptr */
+ movel %d3, -(%sp)
+ cfi_adjust_cfa_offset (4)
+ cfi_rel_offset (%d3, 0)
+ movel 20+4(%sp), %d3
+ movel %d4, -(%a1) /* save %d4 and get child_tidptr */
+ movel %d4, -(%sp)
+ cfi_adjust_cfa_offset (4)
+ cfi_rel_offset (%d4, 0)
+ movel 28+8(%sp), %d4
+ movel %d5, -(%a1) /* save %d5 and get tls */
+ movel %d5, -(%sp)
+ cfi_adjust_cfa_offset (4)
+ cfi_rel_offset (%d5, 0)
+ movel 24+12(%sp), %d5
+ /* save %d2 and get stack pointer */
+#ifdef __mcoldfire__
+ movel %d2, -(%a1)
+ movel %d2, -(%sp)
+ cfi_adjust_cfa_offset (4)
+ cfi_rel_offset (%d2, 0)
+ movel %a1, %d2
#else
- exg %d2, %a1 /* save %d2 and get stack pointer */
+ exg %d2, %a1 /* save %d2 and get stack pointer */
+ cfi_register (%d2, %a1)
#endif
- movel 12(%sp), %d1 /* get flags */
movel #__NR_clone, %d0
+
+ /* End FDE now, because in the child the unwind info will be
+ wrong. */
+ cfi_endproc
+
trap #0
-#if 1 /* defined (CONFIG_COLDFIRE) */
- movel %d2, %d1 /* restore %d2 */
- movel %a1, %d2
- movel %d1, %a1
+#ifdef __mcoldfire__
+ movel (%sp)+, %d2
#else
- exg %d2, %a1 /* restore %d2 */
+ exg %d2, %a1 /* restore %d2 */
#endif
+ movel (%sp)+, %d5 /* restore %d5, %d4 and %d3 */
+ movel (%sp)+, %d4
+ movel (%sp)+, %d3
tstl %d0
bmi.w __syscall_error_trampoline
@@ -57,13 +97,21 @@ clone:
rts
thread_start:
- /*subl %fp, %fp*/ /* terminate the stack frame */
- jsr (%a0)
- movel %d0, -(%sp)
+ cfi_startproc
+ cfi_undefined (pc) /* Mark end of stack */
+ subl %fp, %fp /* terminate the stack frame */
+ jsr (%a0)
+ movel %d0, %d1
movel #__NR_exit, %d0
trap #0
- /*jsr exit*/
+ cfi_endproc
+
+ cfi_startproc
__syscall_error_trampoline:
JUMP __syscall_error,%a0
+.size __clone,.-__clone
+
+weak_alias(__clone,clone)
+libc_hidden_def(clone)