summaryrefslogtreecommitdiff
path: root/libc/sysdeps/linux/arm
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2002-01-31 15:49:34 +0000
committerEric Andersen <andersen@codepoet.org>2002-01-31 15:49:34 +0000
commit8dd9c51eb2f6c5dc659b426dc3bd114751adb405 (patch)
tree5eeeb11b1f38660340b91c83128cdb88cad6d65b /libc/sysdeps/linux/arm
parent290b06002e9d168438c418c508e6ab5431b05b62 (diff)
Fixup setjmp and longjmp so they behave themselves properly now
on both x86 and arm... -Erik
Diffstat (limited to 'libc/sysdeps/linux/arm')
-rw-r--r--libc/sysdeps/linux/arm/Makefile2
-rw-r--r--libc/sysdeps/linux/arm/__longjmp.S40
-rw-r--r--libc/sysdeps/linux/arm/bsd-_setjmp.S34
-rw-r--r--libc/sysdeps/linux/arm/bsd-setjmp.S34
-rw-r--r--libc/sysdeps/linux/arm/clone.S43
-rw-r--r--libc/sysdeps/linux/arm/longjmp.S45
-rw-r--r--libc/sysdeps/linux/arm/setjmp.S21
-rw-r--r--libc/sysdeps/linux/arm/vfork.S2
8 files changed, 151 insertions, 70 deletions
diff --git a/libc/sysdeps/linux/arm/Makefile b/libc/sysdeps/linux/arm/Makefile
index 9e826aa48..5651d6d7b 100644
--- a/libc/sysdeps/linux/arm/Makefile
+++ b/libc/sysdeps/linux/arm/Makefile
@@ -30,7 +30,7 @@ TARGET_MACHINE_TYPE=$(shell $(CC) -dumpmachine)
CRT0=crt0.S
CRT0_OBJ=crt0.o
-SSRC=longjmp.S setjmp.S vfork.S
+SSRC=__longjmp.S vfork.S clone.S setjmp.S bsd-setjmp.S bsd-_setjmp.S
SOBJS=$(patsubst %.S,%.o, $(SSRC))
CSRC=inout_bwl.c brk.c
diff --git a/libc/sysdeps/linux/arm/__longjmp.S b/libc/sysdeps/linux/arm/__longjmp.S
new file mode 100644
index 000000000..4c12a748c
--- /dev/null
+++ b/libc/sysdeps/linux/arm/__longjmp.S
@@ -0,0 +1,40 @@
+/* longjmp for ARM.
+ Copyright (C) 1997, 1998 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
+ 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, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <features.h>
+#define _SETJMP_H
+#define _ASM
+#include <bits/setjmp.h>
+
+
+.globl __longjmp;
+.type __longjmp,%function
+.align 4;
+__longjmp:
+ mov ip, r0 /* save jmp_buf pointer */
+
+ movs r0, r1 /* get the return value in place */
+ moveq r0, #1 /* can't let setjmp() return zero! */
+
+#ifdef __UCLIBC_HAS_FLOATS__
+ lfmfd f4, 4, [ip] ! /* load the floating point regs */
+#endif
+
+ ldmia ip , {v1-v6, sl, fp, sp, pc}
+.size __longjmp,.-__longjmp;
diff --git a/libc/sysdeps/linux/arm/bsd-_setjmp.S b/libc/sysdeps/linux/arm/bsd-_setjmp.S
new file mode 100644
index 000000000..7f092c18b
--- /dev/null
+++ b/libc/sysdeps/linux/arm/bsd-_setjmp.S
@@ -0,0 +1,34 @@
+/* BSD `_setjmp' entry point to `sigsetjmp (..., 0)'. ARM version.
+ Copyright (C) 1997, 1998 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
+ 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, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This just does a tail-call to `__sigsetjmp (ARG, 1)'.
+ We cannot do it in C because it must be a tail-call, so frame-unwinding
+ in setjmp doesn't clobber the state restored by longjmp. */
+
+#define _SETJMP_H
+#define _ASM
+#include <bits/setjmp.h>
+
+.globl _setjmp;
+.type _setjmp,%function
+.align 4;
+_setjmp:
+ mov r1, #0
+ b __sigsetjmp (PLT)
+.size _setjmp,.-_setjmp;
diff --git a/libc/sysdeps/linux/arm/bsd-setjmp.S b/libc/sysdeps/linux/arm/bsd-setjmp.S
new file mode 100644
index 000000000..16f077a79
--- /dev/null
+++ b/libc/sysdeps/linux/arm/bsd-setjmp.S
@@ -0,0 +1,34 @@
+/* BSD `setjmp' entry point to `sigsetjmp (..., 1)'. ARM version.
+ Copyright (C) 1997, 1998 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
+ 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, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This just does a tail-call to `__sigsetjmp (ARG, 1)'.
+ We cannot do it in C because it must be a tail-call, so frame-unwinding
+ in setjmp doesn't clobber the state restored by longjmp. */
+
+#define _SETJMP_H
+#define _ASM
+#include <bits/setjmp.h>
+
+.globl setjmp;
+.type setjmp,%function
+.align 4;
+setjmp:
+ mov r1, #1
+ b __sigsetjmp (PLT)
+.size setjmp,.-setjmp;
diff --git a/libc/sysdeps/linux/arm/clone.S b/libc/sysdeps/linux/arm/clone.S
index c9a1ec23a..f417be07f 100644
--- a/libc/sysdeps/linux/arm/clone.S
+++ b/libc/sysdeps/linux/arm/clone.S
@@ -20,19 +20,21 @@
/* clone() is even more special than fork() as it mucks with stacks
and invokes a function in the right context after its all over. */
-#include <sysdep.h>
-#define _ERRNO_H 1
-#include <bits/errno.h>
+#include <asm/errno.h>
+#include <sys/syscall.h>
/* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg); */
- .text
-ENTRY(__clone)
+.text
+.globl __clone;
+.type __clone,%function
+.align 4;
+__clone:
@ sanity check args
cmp r0, #0
cmpne r1, #0
moveq r0, #-EINVAL
- beq PLTJMP(syscall_error)
+ beq __syscall_error (PLT)
@ insert the args onto the new stack
sub r1, r1, #8
@@ -44,10 +46,10 @@ ENTRY(__clone)
@ get flags
mov r0, r2
@ new sp is already in r1
- swi SYS_ify(clone)
+ swi __NR_clone
movs a1, a1
- blt PLTJMP(C_SYMBOL_NAME(__syscall_error))
- RETINSTR(movne, pc, lr)
+ blt __syscall_error (PLT)
+ movne pc, lr
@ pick the function arg and call address off the stack and execute
ldr r0, [sp, #4]
@@ -55,8 +57,25 @@ ENTRY(__clone)
ldr pc, [sp]
@ and we are done, passing the return value through r0
- b PLTJMP(_exit)
+ b _exit (PLT)
-PSEUDO_END (__clone)
+__syscall_error:
+ /* Looks like the syscall choked -- set errno */
+ ldr r3, .L4
+ /* Calculate the - of the syscall result, in case we need it */
+ rsb r2, r0, $0
+
+ /* errno = -result */
+ str r2, [r9,r3]
+
+ /* return -1 */
+ mvn r0, $0
+ mov pc, lr
+.size __clone,.-__clone;
+
+.L4: .word errno
+
+
+.globl clone;
+ clone = __clone
-weak_alias (__clone, clone)
diff --git a/libc/sysdeps/linux/arm/longjmp.S b/libc/sysdeps/linux/arm/longjmp.S
deleted file mode 100644
index c21758524..000000000
--- a/libc/sysdeps/linux/arm/longjmp.S
+++ /dev/null
@@ -1,45 +0,0 @@
-/* longjmp for ARM.
- Copyright (C) 1997, 1998 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
- modify it under the terms of the GNU Library General Public License as
- published by the Free Software Foundation; either version 2 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with the GNU C Library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
-
-#define _SETJMP_H
-#define _ASM
-#include <bits/setjmp.h>
-
-/* __longjmp(jmpbuf, val) */
-
-.globl longjmp;
-.type longjmp,#function
-.align 4; \
-longjmp:
- mov ip, r0
- movs r0, r1 /* get the return value in place */
- moveq r0, #1 /* can't let setjmp() return zero! */
-
- ldmia ip,{v1-v6, sl, fp, sp, pc}
-.size longjmp,.-longjmp;
-
-.weak _longjmp;
- _longjmp = longjmp;
-
-.weak siglongjmp;
- siglongjmp = longjmp;
-
-.weak __sigprocmask;
- __sigprocmask = sigprocmask;
-
diff --git a/libc/sysdeps/linux/arm/setjmp.S b/libc/sysdeps/linux/arm/setjmp.S
index a993f8c59..166e4efab 100644
--- a/libc/sysdeps/linux/arm/setjmp.S
+++ b/libc/sysdeps/linux/arm/setjmp.S
@@ -17,25 +17,24 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
+#include <features.h>
#define _SETJMP_H
#define _ASM
#include <bits/setjmp.h>
- /* Binary compatibility entry point. */
-.globl _setjmp;
-.type _setjmp,#function
-.align 4;
-_setjmp:
- mov r1, #0
-
-
.globl __sigsetjmp;
-.type __sigsetjmp,#function
+.type __sigsetjmp,%function
.align 4;
__sigsetjmp:
/* Save registers */
- stmia r0, {v1-v6, sl, fp, sp, lr}
+#ifdef __UCLIBC_HAS_FLOATS__
+ sfmea f4, 4, [r0]!
+#endif
+ stmia r0, {v1-v6, sl, fp, sp, lr}
+
+ /* Restore pointer to jmp_buf */
+ sub r0, r0, #48
/* Make a tail call to __sigjmp_save; it takes the same args. */
- B __sigjmp_save
+ B __sigjmp_save (PLT)
.size __sigsetjmp,.-__sigsetjmp;
diff --git a/libc/sysdeps/linux/arm/vfork.S b/libc/sysdeps/linux/arm/vfork.S
index ccf815f12..361153214 100644
--- a/libc/sysdeps/linux/arm/vfork.S
+++ b/libc/sysdeps/linux/arm/vfork.S
@@ -21,7 +21,7 @@
*/
#include <asm/errno.h>
-#include <asm/unistd.h>
+#include <sys/syscall.h>
.global errno;