diff options
Diffstat (limited to 'libc/sysdeps/linux/sh/clone.S')
-rw-r--r-- | libc/sysdeps/linux/sh/clone.S | 135 |
1 files changed, 72 insertions, 63 deletions
diff --git a/libc/sysdeps/linux/sh/clone.S b/libc/sysdeps/linux/sh/clone.S index 3d18b6dd0..423a6c2f1 100644 --- a/libc/sysdeps/linux/sh/clone.S +++ b/libc/sysdeps/linux/sh/clone.S @@ -1,4 +1,4 @@ -/* Copyright (C) 1999, 2000 Free Software Foundation, Inc. +/* Copyright (C) 1999, 2000, 2003, 2004, 2007 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 @@ -20,93 +20,94 @@ and invokes a function in the right context after its all over. */ #include <features.h> -#include <sys/syscall.h> -#define _ERRNO_H +#include <asm/unistd.h> +#include <sysdep.h> +#define _ERRNO_H 1 #include <bits/errno.h> -#include <bits/sysnum.h> - - -#ifdef __PIC__ -#define PLTJMP(_x) _x@PLT -#else -#define PLTJMP(_x) _x +#ifdef RESET_PID +#include <tcb-offsets.h> #endif +/* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg, + pid_t *ptid, void *tls, pid_t *ctid); */ - -/* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg); */ - - .text - -.text -.align 4 -.type clone,@function -.globl clone; -clone: + .text +ENTRY(__clone) /* sanity check arguments. */ tst r4, r4 - bt 0f - tst r5, r5 - bf/s 1f - mov #+__NR_clone, r3 -0: - bra __syscall_error - mov #-EINVAL, r4 - + bt/s 0f + tst r5, r5 + bf 1f +0: + bra .Lsyscall_error + mov #-EINVAL,r0 1: /* insert the args onto the new stack */ mov.l r7, @-r5 /* save the function pointer as the 0th element */ mov.l r4, @-r5 - + /* do the system call */ mov r6, r4 - trapa #(__SH_SYSCALL_TRAP_BASE + 2) + mov.l @r15, r6 + mov.l @(8,r15), r7 + mov.l @(4,r15), r0 + mov #+SYS_ify(clone), r3 + trapa #0x15 mov r0, r1 -#ifdef __sh2__ -/* 12 arithmetic shifts for the crappy sh2, because shad doesn't exist! */ - shar r1 - shar r1 - shar r1 - shar r1 - shar r1 - shar r1 - shar r1 - shar r1 - shar r1 - shar r1 - shar r1 - shar r1 -#else mov #-12, r2 shad r2, r1 -#endif - not r1, r1 /* r1=0 means r0 = -1 to -4095 */ - tst r1, r1 /* i.e. error in linux */ - bf/s 2f - tst r0, r0 - bra __syscall_error - mov r0, r4 - -2: - bt 3f + not r1, r1 // r1=0 means r0 = -1 to -4095 + tst r1, r1 // i.e. error in linux + bf .Lclone_end +.Lsyscall_error: + SYSCALL_ERROR_HANDLER +.Lclone_end: + tst r0, r0 + bt 2f +.Lpseudo_end: rts nop +2: + /* terminate the stack frame */ + mov #0, r14 +#ifdef RESET_PID + mov r4, r0 + shlr16 r0 + tst #1, r0 // CLONE_THREAD = (1 << 16) + bf/s 4f + mov r4, r0 + /* new pid */ + shlr8 r0 + tst #1, r0 // CLONE_VM = (1 << 8) + bf/s 3f + mov #-1, r0 + mov #+SYS_ify(getpid), r3 + trapa #0x15 3: + stc gbr, r1 + mov.w .Lpidoff, r2 + add r1, r2 + mov.l r0, @r2 + mov.w .Ltidoff, r2 + add r1, r2 + mov.l r0, @r2 +4: +#endif /* thread starts */ mov.l @r15, r1 jsr @r1 mov.l @(4,r15), r4 /* we are done, passing the return value through r0 */ - mov.l .L1, r1 -#ifdef __PIC__ + mov.l .L3, r1 +#ifdef SHARED mov.l r12, @-r15 sts.l pr, @-r15 mov r0, r4 - mova .LG, r0 /* .LG from syscall_error.S */ + mova .LG, r0 mov.l .LG, r12 add r0, r12 - mova .L1, r0 + mova .L3, r0 add r0, r1 jsr @r1 nop @@ -118,8 +119,16 @@ clone: mov r0, r4 #endif .align 2 -.L1: - .long PLTJMP( HIDDEN_JUMPTARGET(_exit)) -.size clone,.-clone; +.LG: + .long _GLOBAL_OFFSET_TABLE_ +.L3: + .long PLTJMP(C_SYMBOL_NAME(_exit)) +#ifdef RESET_PID +.Lpidoff: + .word PID - TLS_PRE_TCB_SIZE +.Ltidoff: + .word TID - TLS_PRE_TCB_SIZE +#endif +PSEUDO_END (__clone) -#include "syscall_error.S" +weak_alias (__clone, clone) |