OSDN Git Service

Fixup setjmp and longjmp so they behave themselves properly now
authorEric Andersen <andersen@codepoet.org>
Thu, 31 Jan 2002 15:49:34 +0000 (15:49 -0000)
committerEric Andersen <andersen@codepoet.org>
Thu, 31 Jan 2002 15:49:34 +0000 (15:49 -0000)
on both x86 and arm...
 -Erik

13 files changed:
libc/sysdeps/linux/arm/Makefile
libc/sysdeps/linux/arm/__longjmp.S [new file with mode: 0644]
libc/sysdeps/linux/arm/bsd-_setjmp.S [new file with mode: 0644]
libc/sysdeps/linux/arm/bsd-setjmp.S [new file with mode: 0644]
libc/sysdeps/linux/arm/clone.S
libc/sysdeps/linux/arm/longjmp.S [deleted file]
libc/sysdeps/linux/arm/setjmp.S
libc/sysdeps/linux/arm/vfork.S
libc/sysdeps/linux/common/Makefile
libc/sysdeps/linux/common/longjmp.c [new file with mode: 0644]
libc/sysdeps/linux/i386/Makefile
libc/sysdeps/linux/i386/jmp-unwind.c [deleted file]
libc/sysdeps/linux/i386/longjmp.c [deleted file]

index 9e826aa..5651d6d 100644 (file)
@@ -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 (file)
index 0000000..4c12a74
--- /dev/null
@@ -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 (file)
index 0000000..7f092c1
--- /dev/null
@@ -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 (file)
index 0000000..16f077a
--- /dev/null
@@ -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;
index c9a1ec2..f417be0 100644 (file)
 /* 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 (file)
index c217585..0000000
+++ /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;
-
index a993f8c..166e4ef 100644 (file)
    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;
index ccf815f..3611532 100644 (file)
@@ -21,7 +21,7 @@
  */
 
 #include <asm/errno.h>
-#include <asm/unistd.h>
+#include <sys/syscall.h>
 
 
 .global errno;
index d846487..e4820e3 100644 (file)
@@ -27,7 +27,7 @@ include $(TOPDIR)Rules.mak
 CSRC=  waitpid.c kernel_version.c statfix.c getdnnm.c gethstnm.c \
        mkfifo.c setegid.c wait.c errno.c getpagesize.c seteuid.c \
        wait3.c setpgrp.c getdtablesize.c create_module.c ptrace.c \
-       cmsg_nxthdr.c open64.c statfix64.c statfs64.c
+       cmsg_nxthdr.c open64.c statfix64.c statfs64.c longjmp.c
 ifneq ($(strip $(EXCLUDE_BRK)),true)
 CSRC+=sbrk.c
 endif
diff --git a/libc/sysdeps/linux/common/longjmp.c b/libc/sysdeps/linux/common/longjmp.c
new file mode 100644 (file)
index 0000000..95c7fef
--- /dev/null
@@ -0,0 +1,46 @@
+/* Copyright (C) 1991, 92, 94, 95, 97, 98, 2000 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 <stddef.h>
+#include <setjmp.h>
+#include <signal.h>
+
+
+/* Set the signal mask to the one specified in ENV, and jump
+   to the position specified in ENV, causing the setjmp
+   call there to return VAL, or 1 if VAL is 0.  */
+void __libc_siglongjmp (sigjmp_buf env, int val)
+{
+#if 0
+  /* Perform any cleanups needed by the frames being unwound.  */
+  _longjmp_unwind (env, val);
+#endif
+
+  if (env[0].__mask_was_saved)
+    /* Restore the saved signal mask.  */
+    (void) sigprocmask (SIG_SETMASK, &env[0].__saved_mask,
+                         (sigset_t *) NULL);
+
+  /* Call the machine-dependent function to restore machine state.  */
+  __longjmp (env[0].__jmpbuf, val ?: 1);
+}
+
+strong_alias (__libc_siglongjmp, __libc_longjmp)
+weak_alias (__libc_siglongjmp, _longjmp)
+weak_alias (__libc_siglongjmp, longjmp)
+weak_alias (__libc_siglongjmp, siglongjmp)
index 67dd89e..143162c 100644 (file)
@@ -42,7 +42,7 @@ ifeq ($(UNIFIED_SYSCALL),true)
 endif
 SOBJS=$(patsubst %.S,%.o, $(SSRC))
 
-CSRC=brk.c longjmp.c #jmp-unwind.c
+CSRC=brk.c
 COBJS=$(patsubst %.c,%.o, $(CSRC))
 
 OBJS=$(SOBJS) $(COBJS)
diff --git a/libc/sysdeps/linux/i386/jmp-unwind.c b/libc/sysdeps/linux/i386/jmp-unwind.c
deleted file mode 100644 (file)
index 083dc74..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/* _longjmp_unwind -- Clean up stack frames unwound by longjmp.  Stub version.
-   Copyright (C) 1995, 1997 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.  */
-
-#include <setjmp.h>
-
-void
-_longjmp_unwind (jmp_buf env, int val)
-{
-
-  /* This function can perform any cleanups necessary to safely unwind the
-     stack frames around the current context which ENV unwinds past.  */
-
-}
diff --git a/libc/sysdeps/linux/i386/longjmp.c b/libc/sysdeps/linux/i386/longjmp.c
deleted file mode 100644 (file)
index 46e48f5..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/* Copyright (C) 1991, 92, 94, 95, 97, 98 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.  */
-
-#include <stddef.h>
-#include <setjmp.h>
-#define __USE_GNU
-#include <signal.h>
-
-
-#if 0
-extern void _longjmp_unwind (jmp_buf env, int val);
-#endif
-extern void __longjmp(__jmp_buf __env, int __val) 
-        __attribute__ ((__noreturn__));
-
-/* Set the signal mask to the one specified in ENV, and jump
-   to the position specified in ENV, causing the setjmp
-   call there to return VAL, or 1 if VAL is 0.  */
-void
-__uClibc_siglongjmp (sigjmp_buf env, int val)
-{
-#if 0
-  /* Perform any cleanups needed by the frames being unwound.  */
-  _longjmp_unwind (env, val);
-#endif
-
-  if (env[0].__mask_was_saved)
-    /* Restore the saved signal mask.  */
-    (void) sigprocmask (SIG_SETMASK, &env[0].__saved_mask,
-                         (sigset_t *) NULL);
-
-  /* Call the machine-dependent function to restore machine state.  */
-  __longjmp (env[0].__jmpbuf, val ?: 1);
-}
-
-__asm__(".weak longjmp; longjmp = __uClibc_siglongjmp");
-__asm__(".weak _longjmp; _longjmp = __uClibc_siglongjmp");
-__asm__(".weak siglongjmp; siglongjmp = __uClibc_siglongjmp");
-__asm__(".weak __sigprocmask; __sigprocmask = sigprocmask");