From 4d3c7f75e644c67e3110fa7ded9eb6af696f8ef2 Mon Sep 17 00:00:00 2001 From: Eric Andersen Date: Fri, 15 Nov 2002 13:46:14 +0000 Subject: 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 --- libc/sysdeps/linux/sh/clone.S | 88 +++++++++++----------------- libc/sysdeps/linux/sh/syscall_error.S | 37 ++++++++++++ libc/sysdeps/linux/sh/vfork.S | 106 +++++++++++++++------------------- 3 files changed, 116 insertions(+), 115 deletions(-) create mode 100644 libc/sysdeps/linux/sh/syscall_error.S 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 +#define _SYSCALL_H +#include #define _ERRNO_H 1 #include @@ -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 -- cgit v1.2.3