summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid McCullough <davidm@snapgear.com>2001-06-25 04:11:28 +0000
committerDavid McCullough <davidm@snapgear.com>2001-06-25 04:11:28 +0000
commit5d2472cf83a9ceb2b002dee59100ca3fbe7b9311 (patch)
tree1471b5a8b8e4eca189c06585c8e83d15ab6835aa
parentc5207a5547426030930716fbd0de0de064c2f27b (diff)
downloaduClibc-alpine-5d2472cf83a9ceb2b002dee59100ca3fbe7b9311.tar.bz2
uClibc-alpine-5d2472cf83a9ceb2b002dee59100ca3fbe7b9311.tar.xz
Fixed vfork so the child doesn't trash the parents return address.
-rw-r--r--libc/sysdeps/linux/m68k/Makefile4
-rw-r--r--libc/sysdeps/linux/m68k/vfork.S33
-rw-r--r--libc/sysdeps/linux/m68k/vfork.c25
3 files changed, 35 insertions, 27 deletions
diff --git a/libc/sysdeps/linux/m68k/Makefile b/libc/sysdeps/linux/m68k/Makefile
index 3ca165344..9c929ec11 100644
--- a/libc/sysdeps/linux/m68k/Makefile
+++ b/libc/sysdeps/linux/m68k/Makefile
@@ -29,10 +29,10 @@ ASFLAGS=$(CFLAGS)
CRT0=crt0.S
CRT0_OBJ=$(patsubst %.S,%.o, $(CRT0))
-SSRC=setjmp.S # longjmp.S _start.S clone.S
+SSRC=setjmp.S vfork.S # longjmp.S _start.S clone.S
SOBJS=$(patsubst %.S,%.o, $(SSRC))
-CSRC=ptrace.c vfork.c
+CSRC=ptrace.c
COBJS=$(patsubst %.c,%.o, $(CSRC))
OBJS=$(SOBJS) $(MOBJ) $(COBJS)
diff --git a/libc/sysdeps/linux/m68k/vfork.S b/libc/sysdeps/linux/m68k/vfork.S
new file mode 100644
index 000000000..ba3a67203
--- /dev/null
+++ b/libc/sysdeps/linux/m68k/vfork.S
@@ -0,0 +1,33 @@
+
+#include <asm/unistd.h>
+
+#ifndef __NR_vfork
+#define __NR_vfork __NR_fork /* uClinux-2.0 only has fork which is vfork */
+#endif
+
+#define IMM #
+
+ .text
+ .align 2
+ .globl errno
+ .globl vfork
+ .type vfork,@function
+vfork:
+ movl %sp@+, %a1 /* save the return address for later */
+ movl IMM __NR_vfork,%d0
+ trap #0
+ movl IMM -4097, %d1
+ cmpl %d0, %d1
+ bcs fix_errno
+ jmp %a1@ /* don't return, just jmp directly */
+fix_errno:
+ negl %d0
+#ifndef __PIC__
+ movl errno, %a0
+#else
+ movl errno@GOT(%a5), %a0
+#endif
+ movl %d0, %a0@
+ movl IMM -1, %d0
+ jmp %a1@ /* don't return, just jmp directly */
+
diff --git a/libc/sysdeps/linux/m68k/vfork.c b/libc/sysdeps/linux/m68k/vfork.c
deleted file mode 100644
index 9edcb650d..000000000
--- a/libc/sysdeps/linux/m68k/vfork.c
+++ /dev/null
@@ -1,25 +0,0 @@
-/* orginally from include/unistd.h, written by ndf@linux.mit.edu> */
-#include <unistd.h>
-#include <sys/types.h>
-#include <asm/unistd.h>
-
-#ifndef __NR_vfork
-#define __NR_vfork __NR_fork /* uClinux-2.0 only has fork which is vfork */
-#endif
-
-pid_t vfork(void)
-{
- pid_t __res;
- __asm__ __volatile__ ("movel %1,%%d0;"
- "trap #0;"
- "movel %%d0,%0"
- : "=d" (__res)
- : "0" (__NR_vfork)
- : "%d0");
- if (__res >= (unsigned long)-4096) {
- errno = -__res;
- __res = (pid_t)-1;
- }
- return(__res);
-}
-