summaryrefslogtreecommitdiff
path: root/libc
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
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')
-rw-r--r--libc/sysdeps/linux/sh/clone.S88
-rw-r--r--libc/sysdeps/linux/sh/syscall_error.S37
-rw-r--r--libc/sysdeps/linux/sh/vfork.S106
3 files changed, 116 insertions, 115 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"
diff --git a/libc/sysdeps/linux/sh/syscall_error.S b/libc/sysdeps/linux/sh/syscall_error.S
new file mode 100644
index 000000000..7115120db
--- /dev/null
+++ b/libc/sysdeps/linux/sh/syscall_error.S
@@ -0,0 +1,37 @@
+ .align 4
+__syscall_error:
+ /* Call errno_location, store '-r4' in errno and return -1 */
+ mov.l r12, @-r15
+ sts.l pr, @-r15
+#if defined __HAVE_ELF__ && defined __HAVE_SHARED__
+ mova .LG, r0
+ mov.l .LG, r12
+ add r0, r12
+ mov.l 1f, r0
+ mov.l @(r0,r12),r0
+ jsr @r0
+ neg r4, r12
+#else
+ mov.l 1f, r0
+ bsrf r0
+ neg r4, r12
+.jmp_loc:
+#endif
+ mov.l r12, @r0
+ lds.l @r15+, pr
+ mov.l @r15+,r12
+
+ /* And just kick back a -1. */
+ rts
+ mov #-1, r0
+
+ .align 4
+
+#if defined __HAVE_ELF__ && defined __HAVE_SHARED__
+1: .long __errno_location@GOT
+.LG: .long _GLOBAL_OFFSET_TABLE_
+#else
+1: .long __errno_location - .jmp_loc
+#endif
+
+
diff --git a/libc/sysdeps/linux/sh/vfork.S b/libc/sysdeps/linux/sh/vfork.S
index b98c74f35..981928e08 100644
--- a/libc/sysdeps/linux/sh/vfork.S
+++ b/libc/sysdeps/linux/sh/vfork.S
@@ -20,6 +20,9 @@
respective copyright holders.
*/
+#include <features.h>
+#define _SYSCALL_H
+#include <bits/sysnum.h>
#define _ERRNO_H 1
#include <bits/errno.h>
@@ -28,26 +31,15 @@
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. */
-.global errno
-
.text
.align 4
.type __vfork,@function
.globl __vfork;
__vfork:
- mov.l @r15+,r3 // pop value from the stack
- mov.l .L5,r1
- mov.l r3,@r1 // save it in .sav_stack
-
- mov.w .L3, r3
-
-#ifdef HIOS
- trapa #0x28
-#else
+ mov.w .L2, r3
trapa #0x10
-#endif
-
mov r0, r1
+#ifdef __sh2__
// 12 arithmetic shifts for the crappy sh2, because shad doesn't exist!
shar r1
shar r1
@@ -61,66 +53,60 @@ __vfork:
shar r1
shar r1
shar r1
+#else
+ mov #-12, r2
+ shad r2, r1
+#endif
-// mov #-12, r2
-// shad r2, r1
not r1, r1 // r1=0 means r0 = -1 to -4095
tst r1, r1 // i.e. error in linux
- bf 1f
+ bf 2f
mov.w .L1, r1
cmp/eq r1, r0
- bt 2f
- mov.l .L2, r1
- jmp @r1
+ bf/s __syscall_error
mov r0, r4
- .align 4
-
-1:
- mov.l .L5,r1
- mov.l @r1,r3 // get it from .sav_stack
- mov.l r3,@-r15 // restore value to the stack
-
- rts
- nop
-
- .align 4
+ /* If we don't have vfork, use fork. */
+ mov.w .L3, r3
+ trapa #0x10
+ 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
+ bt/s __syscall_error
+ mov r0, r4
2:
-.global __syscall_error
-__syscall_error:
- /* Store it in errno... */
- mov.l .L4, r1
- mov.l r0, @r1
-
- mov.l .L5,r1
- mov.l @r1,r3 // get it from .sav_stack
- mov.l r3,@-r15 // restore value to the stack
-
- /* And just kick back a -1. */
rts
- mov #-1, r0
+ nop
- .align 4
+ .align 2
.L1:
.word -ENOSYS
-.L3:
- .word 190 //__NR_vfork
-
- .align 4 // Shouldn't be necessary as previously with have two words
.L2:
- .long __syscall_error
-
-.L4: .long errno
-
-.L5: .long .sav_stack
-
- .data
-
- .align 4
+ .word __NR_vfork
+.L3:
+ .word __NR_fork
+ .size __vfork, .-__vfork
+.weak vfork
+ vfork = __vfork
-.sav_stack: //area to temporary save the stach
- .long 0
+#include "syscall_error.S"
-.weak vfork
-vfork = __vfork