summaryrefslogtreecommitdiff
path: root/libc/sysdeps/linux/sh/clone.S
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2002-11-15 13:46:14 +0000
committerEric Andersen <andersen@codepoet.org>2002-11-15 13:46:14 +0000
commit4d3c7f75e644c67e3110fa7ded9eb6af696f8ef2 (patch)
tree11357382c5da640a8dcd1b90c09b8b19cfdae6a7 /libc/sysdeps/linux/sh/clone.S
parent30c30b2c9990d4f620fed8292c0fbf28f8cbd16f (diff)
Stefan Allius writes:
I attached a patch, which revise the clone.S and vfork.S: - Use PIC code. - include new file syscall.S, so we can simply make a branch to __syscall_error instead of a PLT/GOT call - call errno_location to store the syscall error (for pthreads) - avoid to use the 'shad' statement on SH2 targets - call fork if vfork isn't available - some cleanups and optimization
Diffstat (limited to 'libc/sysdeps/linux/sh/clone.S')
-rw-r--r--libc/sysdeps/linux/sh/clone.S88
1 files changed, 33 insertions, 55 deletions
diff --git a/libc/sysdeps/linux/sh/clone.S b/libc/sysdeps/linux/sh/clone.S
index f2ce8321b..98086ef09 100644
--- a/libc/sysdeps/linux/sh/clone.S
+++ b/libc/sysdeps/linux/sh/clone.S
@@ -35,7 +35,6 @@
/* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg); */
.text
-.extern __syscall_error
.text
.align 4
@@ -44,71 +43,50 @@
__clone:
/* sanity check arguments. */
tst r4, r4
+ bt 0f
+ tst r5, r5
bf/s 1f
- tst r5, r5
- bf/s 1f
- mov.l .L1, r1
-#ifdef __HAVE_SHARED__
- mov.l r12, @-r15
- sts.l pr, @-r15
- mov.l .LG, r12
- mova .LG, r0
- add r0, r12
- mova .L1, r0
- add r0, r1
- jsr @r1
+ mov #+__NR_clone, r3
+0:
+ bra __syscall_error
mov #-EINVAL, r4
- lds.l @r15+, pr
- rts
- mov.l @r15+, r12
-#else
- jmp @r1
- mov #-EINVAL, r4
-#endif
- .align 2
-.L1:
- .long PLTJMP(__syscall_error)
+
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
- mov #+__NR_clone, r3
trapa #0x12
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 2f
- mov.l .L2, r1
-#ifdef __HAVE_SHARED__
- mov r0, r4
- mov.l r12, @-r15
- sts.l pr, @-r15
- mov.l .LG, r12
- mova .LG, r0
- add r0, r12
- mova .L2, r0
- add r0, r1
- jsr @r1
- nop
- lds.l @r15+, pr
- rts
- mov.l @r15+, r12
-#else
- jmp @r1
+ bf/s 2f
+ tst r0, r0
+ bra __syscall_error
mov r0, r4
-#endif
- .align 2
-.L2:
- .long PLTJMP(__syscall_error)
2:
- tst r0, r0
bt 3f
rts
nop
@@ -119,15 +97,15 @@ __clone:
mov.l @(4,r15), r4
/* we are done, passing the return value through r0 */
- mov.l .L3, r1
-#ifdef __HAVE_SHARED__
+ mov.l .L1, r1
+#if defined __HAVE_ELF__ && defined __HAVE_SHARED__
mov.l r12, @-r15
sts.l pr, @-r15
mov r0, r4
- mova .LG, r0
+ mova .LG, r0 /* .LG from syscall_error.S */
mov.l .LG, r12
add r0, r12
- mova .L3, r0
+ mova .L1, r0
add r0, r1
jsr @r1
nop
@@ -139,11 +117,11 @@ __clone:
mov r0, r4
#endif
.align 2
-.LG:
- .long _GLOBAL_OFFSET_TABLE_
-.L3:
+.L1:
.long PLTJMP(_exit)
.size __clone,.-__clone;
.globl clone;
clone = __clone
+
+#include "syscall_error.S"