From 69ec4a5d65cdd4a2fdf2c94e1861464fa2caf7ce Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Wed, 29 Jun 2005 00:56:09 +0000 Subject: add syscall error handling with jockes simple errno setting solution --- libc/sysdeps/linux/x86_64/__syscall_error.c | 28 ++++++++++++++++++++++++++++ libc/sysdeps/linux/x86_64/clone.S | 18 +++++++++--------- libc/sysdeps/linux/x86_64/syscall.S | 15 ++++++++------- libc/sysdeps/linux/x86_64/vfork.S | 29 +++++++++++++++++++++-------- 4 files changed, 66 insertions(+), 24 deletions(-) create mode 100644 libc/sysdeps/linux/x86_64/__syscall_error.c (limited to 'libc/sysdeps/linux') diff --git a/libc/sysdeps/linux/x86_64/__syscall_error.c b/libc/sysdeps/linux/x86_64/__syscall_error.c new file mode 100644 index 000000000..f0a699575 --- /dev/null +++ b/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 + +/* 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; +} diff --git a/libc/sysdeps/linux/x86_64/clone.S b/libc/sysdeps/linux/x86_64/clone.S index 9d244d018..65d0c53fd 100644 --- a/libc/sysdeps/linux/x86_64/clone.S +++ b/libc/sysdeps/linux/x86_64/clone.S @@ -48,17 +48,17 @@ r8: thread pointer */ - .text +.text .globl __clone; .type __clone,@function -.align 4; +.align 4 __clone: /* Sanity check arguments. */ movq $-EINVAL,%rax testq %rdi,%rdi /* no NULL function pointers */ - jz __syscall_error + jz __error testq %rsi,%rsi /* no NULL stack pointers */ - jz __syscall_error + jz __error /* Insert the argument onto the new stack. */ subq $16,%rsi @@ -73,12 +73,12 @@ __clone: movq %r8, %rdx movq %r9, %r8 movq 8(%rsp), %r10 - movq $__NR_clone,%rax + movq __NR_clone,%rax syscall testq %rax,%rax - jl __syscall_error + jl __error jz L(thread_start) L(pseudo_end): @@ -110,7 +110,7 @@ L(thread_start): movq %rax, %rdi 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 diff --git a/libc/sysdeps/linux/x86_64/syscall.S b/libc/sysdeps/linux/x86_64/syscall.S index 0ec272566..23ff07ac1 100644 --- a/libc/sysdeps/linux/x86_64/syscall.S +++ b/libc/sysdeps/linux/x86_64/syscall.S @@ -23,9 +23,10 @@ We need to do some arg shifting, the syscall_number will be in rax. */ -.globl syscall; -.type syscall,@function; -.align 16; +.text +.globl syscall +.type syscall,@function +.align 16 syscall: movq %rdi, %rax /* Syscall number -> rax. */ movq %rsi, %rdi /* shift arg1 - arg5. */ @@ -36,10 +37,10 @@ syscall: movq 8(%rsp),%r9 /* arg6 is on the stack. */ syscall /* Do the system call. */ 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. */ -__syscall_error: - /* TODO: implement this ! :D */ +__error: + jmp __syscall_error -.size syscall,.-syscall; +.size syscall,.-syscall diff --git a/libc/sysdeps/linux/x86_64/vfork.S b/libc/sysdeps/linux/x86_64/vfork.S index 072a3a0a8..e3bd7d23d 100644 --- a/libc/sysdeps/linux/x86_64/vfork.S +++ b/libc/sysdeps/linux/x86_64/vfork.S @@ -18,15 +18,24 @@ #define _ERRNO_H 1 #include +#include /* Clone the calling process, but without copying the whole address space. 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, 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: /* Pop the return PC value into RDI. We need a register that @@ -41,13 +50,17 @@ __vfork: pushq %rdi cmpl $-4095, %eax - jae __syscall_error /* Branch forward if it failed. */ + jae __error /* Branch forward if it failed. */ /* Normal return. */ 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 */ -- cgit v1.2.3