ソースを参照

add syscall error handling with jockes simple errno setting solution

Mike Frysinger 20 年 前
コミット
69ec4a5d65

+ 28 - 0
libc/sysdeps/linux/x86_64/__syscall_error.c

@@ -0,0 +1,28 @@
+/* Wrapper for setting errno.
+   Copyright (C) 1997, 1998, 1999, 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 <errno.h>
+
+/* This routine is jumped to by all the syscall handlers, to stash
+ * an error number into errno.  */
+int attribute_hidden __syscall_error(int err_no)
+{
+	__set_errno(err_no);
+	return -1;
+}

+ 9 - 9
libc/sysdeps/linux/x86_64/clone.S

@@ -48,17 +48,17 @@
    r8:	thread pointer  */
    r8:	thread pointer  */
 
 
 
 
-        .text
+.text
 .globl __clone;
 .globl __clone;
 .type	__clone,@function
 .type	__clone,@function
-.align 4;
+.align 4
 __clone:
 __clone:
 	/* Sanity check arguments.  */
 	/* Sanity check arguments.  */
 	movq	$-EINVAL,%rax
 	movq	$-EINVAL,%rax
 	testq	%rdi,%rdi		/* no NULL function pointers */
 	testq	%rdi,%rdi		/* no NULL function pointers */
-	jz	__syscall_error
+	jz	__error
 	testq	%rsi,%rsi		/* no NULL stack pointers */
 	testq	%rsi,%rsi		/* no NULL stack pointers */
-	jz	__syscall_error
+	jz	__error
 
 
 	/* Insert the argument onto the new stack.  */
 	/* Insert the argument onto the new stack.  */
 	subq	$16,%rsi
 	subq	$16,%rsi
@@ -73,12 +73,12 @@ __clone:
 	movq	%r8, %rdx
 	movq	%r8, %rdx
 	movq	%r9, %r8
 	movq	%r9, %r8
 	movq	8(%rsp), %r10
 	movq	8(%rsp), %r10
-	movq	$__NR_clone,%rax
+	movq	__NR_clone,%rax
 
 
 	syscall
 	syscall
 
 
 	testq	%rax,%rax
 	testq	%rax,%rax
-	jl	__syscall_error
+	jl	__error
 	jz	L(thread_start)
 	jz	L(thread_start)
 
 
 L(pseudo_end):
 L(pseudo_end):
@@ -110,7 +110,7 @@ L(thread_start):
 	movq	%rax, %rdi
 	movq	%rax, %rdi
 	call	HIDDEN_JUMPTARGET (_exit)
 	call	HIDDEN_JUMPTARGET (_exit)
 
 
-	cfi_startproc;
-PSEUDO_END (BP_SYM (__clone))
+.size __clone,.-__clone
 
 
-weak_alias (BP_SYM (__clone), BP_SYM (clone))
+.weak clone
+	clone = __clone

+ 8 - 7
libc/sysdeps/linux/x86_64/syscall.S

@@ -23,9 +23,10 @@
    We need to do some arg shifting, the syscall_number will be in
    We need to do some arg shifting, the syscall_number will be in
    rax.  */
    rax.  */
 
 
-.globl syscall;
-.type	syscall,@function;
-.align 16;
+.text
+.globl syscall
+.type	syscall,@function
+.align 16
 syscall:
 syscall:
 	movq %rdi, %rax		/* Syscall number -> rax.  */
 	movq %rdi, %rax		/* Syscall number -> rax.  */
 	movq %rsi, %rdi		/* shift arg1 - arg5.  */
 	movq %rsi, %rdi		/* shift arg1 - arg5.  */
@@ -36,10 +37,10 @@ syscall:
 	movq 8(%rsp),%r9	/* arg6 is on the stack.  */
 	movq 8(%rsp),%r9	/* arg6 is on the stack.  */
 	syscall			/* Do the system call.  */
 	syscall			/* Do the system call.  */
 	cmpq $-4095, %rax	/* Check %rax for error.  */
 	cmpq $-4095, %rax	/* Check %rax for error.  */
-	jae __syscall_error		/* Branch forward if it failed.  */
+	jae __error		/* Branch forward if it failed.  */
 	ret			/* Return to caller.  */
 	ret			/* Return to caller.  */
 
 
-__syscall_error:
-	/* TODO: implement this ! :D */
+__error:
+	jmp __syscall_error
 
 
-.size syscall,.-syscall;
+.size syscall,.-syscall

+ 21 - 8
libc/sysdeps/linux/x86_64/vfork.S

@@ -18,15 +18,24 @@
 
 
 #define _ERRNO_H	1
 #define _ERRNO_H	1
 #include <bits/errno.h>
 #include <bits/errno.h>
+#include <sys/syscall.h>
 
 
 /* Clone the calling process, but without copying the whole address space.
 /* Clone the calling process, but without copying the whole address space.
    The calling process is suspended until the new process exits or is
    The calling process is suspended until the new process exits or is
    replaced by a call to `execve'.  Return -1 for errors, 0 to the new process,
    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.  */
    and the process ID of the new process to the old process.  */
 
 
-.globl __vfork;
-.type	__vfork,@function;
-.align 16;
+#ifndef __NR_vfork
+#error wtf
+/* No vfork so use fork instead */
+.weak vfork ; vfork = __libc_fork
+
+#else
+
+.text
+.globl __vfork
+.type	__vfork,@function
+.align 16
 __vfork:
 __vfork:
 
 
 	/* Pop the return PC value into RDI.  We need a register that
 	/* Pop the return PC value into RDI.  We need a register that
@@ -41,13 +50,17 @@ __vfork:
 	pushq	%rdi
 	pushq	%rdi
 
 
 	cmpl	$-4095, %eax
 	cmpl	$-4095, %eax
-	jae __syscall_error		/* Branch forward if it failed.  */
+	jae __error		/* Branch forward if it failed.  */
 
 
 	/* Normal return.  */
 	/* Normal return.  */
 	ret
 	ret
 
 
-__syscall_error:
-	/* TODO: implement this ! :D */
+__error:
+	jmp __syscall_error
+
+.size __vfork,.-__vfork
+
+.weak vfork
+	vfork = __vfork
 
 
-.size	 __vfork,.Lsize-__vfork
-.weak vfork ; vfork = __vfork
+#endif /* __NR_vfork */