diff options
Diffstat (limited to 'sysdeps/unix/sysv')
22 files changed, 91 insertions, 85 deletions
diff --git a/sysdeps/unix/sysv/linux/alpha/sysdep.h b/sysdeps/unix/sysv/linux/alpha/sysdep.h index a95b1139d2..aea77b472b 100644 --- a/sysdeps/unix/sysv/linux/alpha/sysdep.h +++ b/sysdeps/unix/sysv/linux/alpha/sysdep.h @@ -25,6 +25,7 @@ #endif /* There is some commonality. */ +#include <sysdeps/unix/sysv/linux/sysdep.h> #include <sysdeps/unix/alpha/sysdep.h> #include <tls.h> diff --git a/sysdeps/unix/sysv/linux/arm/sysdep.h b/sysdeps/unix/sysv/linux/arm/sysdep.h index 200f77a62e..c8715f7f4b 100644 --- a/sysdeps/unix/sysv/linux/arm/sysdep.h +++ b/sysdeps/unix/sysv/linux/arm/sysdep.h @@ -21,6 +21,7 @@ #define _LINUX_ARM_SYSDEP_H 1 /* There is some commonality. */ +#include <sysdeps/unix/sysv/linux/sysdep.h> #include <sysdeps/unix/arm/sysdep.h> /* Defines RTLD_PRIVATE_ERRNO and USE_DL_SYSINFO. */ diff --git a/sysdeps/unix/sysv/linux/generic/sysdep.h b/sysdeps/unix/sysv/linux/generic/sysdep.h index 11da9d21df..70e7158508 100644 --- a/sysdeps/unix/sysv/linux/generic/sysdep.h +++ b/sysdeps/unix/sysv/linux/generic/sysdep.h @@ -19,6 +19,7 @@ #include <bits/wordsize.h> #include <kernel-features.h> #include <sysdeps/unix/sysdep.h> +#include <sysdeps/unix/sysv/linux/sysdep.h> /* Provide the common name to allow more code reuse. */ #define __NR__llseek __NR_llseek diff --git a/sysdeps/unix/sysv/linux/hppa/sysdep.h b/sysdeps/unix/sysv/linux/hppa/sysdep.h index cb1f163b4b..2cae70fd3c 100644 --- a/sysdeps/unix/sysv/linux/hppa/sysdep.h +++ b/sysdeps/unix/sysv/linux/hppa/sysdep.h @@ -22,6 +22,7 @@ #define _LINUX_HPPA_SYSDEP_H 1 #include <sysdeps/unix/sysdep.h> +#include <sysdeps/unix/sysv/linux/sysdep.h> #include <sysdeps/hppa/sysdep.h> /* Defines RTLD_PRIVATE_ERRNO. */ diff --git a/sysdeps/unix/sysv/linux/i386/Makefile b/sysdeps/unix/sysv/linux/i386/Makefile index 80da5935cf..e10d133db4 100644 --- a/sysdeps/unix/sysv/linux/i386/Makefile +++ b/sysdeps/unix/sysv/linux/i386/Makefile @@ -27,3 +27,17 @@ endif ifeq ($(subdir),stdlib) gen-as-const-headers += ucontext_i.sym endif + +ifeq ($(subdir),csu) +sysdep-dl-routines += sysdep +endif + +ifeq ($(subdir),nptl) +# pull in __syscall_error routine +libpthread-routines += sysdep +endif + +ifeq ($(subdir),rt) +# pull in __syscall_error routine +librt-routines += sysdep +endif diff --git a/sysdeps/unix/sysv/linux/i386/clone.S b/sysdeps/unix/sysv/linux/i386/clone.S index 243dbfecc9..2aafb3a4a6 100644 --- a/sysdeps/unix/sysv/linux/i386/clone.S +++ b/sysdeps/unix/sysv/linux/i386/clone.S @@ -47,19 +47,11 @@ ENTRY (__clone) /* Sanity check arguments. */ movl $-EINVAL,%eax movl FUNC(%esp),%ecx /* no NULL function pointers */ -#ifdef PIC - jecxz SYSCALL_ERROR_LABEL -#else testl %ecx,%ecx jz SYSCALL_ERROR_LABEL -#endif movl STACK(%esp),%ecx /* no NULL stack pointers */ -#ifdef PIC - jecxz SYSCALL_ERROR_LABEL -#else testl %ecx,%ecx jz SYSCALL_ERROR_LABEL -#endif /* Insert the argument onto the new stack. Make sure the new thread is started with an alignment of (mod 16). */ diff --git a/sysdeps/unix/sysv/linux/i386/sysdep.S b/sysdeps/unix/sysv/linux/i386/sysdep.c index 4e6c262f8e..141105eeff 100644 --- a/sysdeps/unix/sysv/linux/i386/sysdep.S +++ b/sysdeps/unix/sysv/linux/i386/sysdep.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1995-2015 Free Software Foundation, Inc. +/* Copyright (C) 2015 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 @@ -15,26 +15,16 @@ License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ +#include <errno.h> #include <sysdep.h> -/* The following code is only used in the shared library when we - compile the reentrant version. Otherwise each system call defines - each own version. */ - -#ifndef PIC - -/* The syscall stubs jump here when they detect an error. - The code for Linux is almost identical to the canonical Unix/i386 - code, except that the error number in %eax is negated. */ - -#undef CALL_MCOUNT -#define CALL_MCOUNT /* Don't insert the profiling call, it clobbers %eax. */ - - .text -ENTRY (__syscall_error) - negl %eax - -#define __syscall_error __syscall_error_1 -#include <sysdeps/unix/i386/sysdep.S> - -#endif /* !PIC */ +/* This routine is jumped to by all the syscall handlers, to stash + an error number into errno. ERROR is the negative error number + returned from the x86 kernel. */ +int +__attribute__ ((__regparm__ (1))) +__syscall_error (int error) +{ + __set_errno (-error); + return -1; +} diff --git a/sysdeps/unix/sysv/linux/i386/sysdep.h b/sysdeps/unix/sysv/linux/i386/sysdep.h index d76aca50d6..3cf927a24b 100644 --- a/sysdeps/unix/sysv/linux/i386/sysdep.h +++ b/sysdeps/unix/sysv/linux/i386/sysdep.h @@ -20,6 +20,7 @@ #define _LINUX_I386_SYSDEP_H 1 /* There is some commonality. */ +#include <sysdeps/unix/sysv/linux/sysdep.h> #include <sysdeps/unix/i386/sysdep.h> /* Defines RTLD_PRIVATE_ERRNO and USE_DL_SYSINFO. */ #include <dl-sysdep.h> @@ -55,11 +56,7 @@ /* We don't want the label for the error handle to be global when we define it here. */ -#ifdef PIC -# define SYSCALL_ERROR_LABEL 0f -#else -# define SYSCALL_ERROR_LABEL syscall_error -#endif +#define SYSCALL_ERROR_LABEL __syscall_error #undef PSEUDO #define PSEUDO(name, syscall_name, args) \ @@ -100,55 +97,7 @@ #define ret_ERRVAL ret -#ifndef PIC -# define SYSCALL_ERROR_HANDLER /* Nothing here; code in sysdep.S is used. */ -#else - -# if RTLD_PRIVATE_ERRNO -# define SYSCALL_ERROR_HANDLER \ -0:SETUP_PIC_REG(cx); \ - addl $_GLOBAL_OFFSET_TABLE_, %ecx; \ - negl %eax; \ - movl %eax, rtld_errno@GOTOFF(%ecx); \ - orl $-1, %eax; \ - ret; - -# elif defined _LIBC_REENTRANT - -# if IS_IN (libc) -# define SYSCALL_ERROR_ERRNO __libc_errno -# else -# define SYSCALL_ERROR_ERRNO errno -# endif -# define SYSCALL_ERROR_HANDLER \ -0:SETUP_PIC_REG (cx); \ - addl $_GLOBAL_OFFSET_TABLE_, %ecx; \ - movl SYSCALL_ERROR_ERRNO@GOTNTPOFF(%ecx), %ecx; \ - negl %eax; \ - SYSCALL_ERROR_HANDLER_TLS_STORE (%eax, %ecx); \ - orl $-1, %eax; \ - ret; -# ifndef NO_TLS_DIRECT_SEG_REFS -# define SYSCALL_ERROR_HANDLER_TLS_STORE(src, destoff) \ - movl src, %gs:(destoff) -# else -# define SYSCALL_ERROR_HANDLER_TLS_STORE(src, destoff) \ - addl %gs:0, destoff; \ - movl src, (destoff) -# endif -# else -/* Store (- %eax) into errno through the GOT. */ -# define SYSCALL_ERROR_HANDLER \ -0:SETUP_PIC_REG(cx); \ - addl $_GLOBAL_OFFSET_TABLE_, %ecx; \ - negl %eax; \ - movl errno@GOT(%ecx), %ecx; \ - movl %eax, (%ecx); \ - orl $-1, %eax; \ - ret; -# endif /* _LIBC_REENTRANT */ -#endif /* PIC */ - +#define SYSCALL_ERROR_HANDLER /* Nothing here; code in sysdep.c is used. */ /* The original calling convention for system calls on Linux/i386 is to use int $0x80. */ @@ -275,6 +224,9 @@ #else /* !__ASSEMBLER__ */ +extern int __syscall_error (int) + attribute_hidden __attribute__ ((__regparm__ (1))); + /* We need some help from the assembler to generate optimal code. We define some macros here which later will be used. */ asm (".L__X'%ebx = 1\n\t" @@ -318,7 +270,15 @@ struct libc_do_syscall_args /* Define a macro which expands inline into the wrapper code for a system call. */ #undef INLINE_SYSCALL -#define INLINE_SYSCALL(name, nr, args...) \ +#if IS_IN (libc) +# define INLINE_SYSCALL(name, nr, args...) \ + ({ \ + unsigned int resultvar = INTERNAL_SYSCALL (name, , nr, args); \ + __glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (resultvar, )) \ + ? __syscall_error (-INTERNAL_SYSCALL_ERRNO (resultvar, )) \ + : (int) resultvar; }) +#else +# define INLINE_SYSCALL(name, nr, args...) \ ({ \ unsigned int resultvar = INTERNAL_SYSCALL (name, , nr, args); \ if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (resultvar, ))) \ @@ -327,6 +287,14 @@ struct libc_do_syscall_args resultvar = 0xffffffff; \ } \ (int) resultvar; }) +#endif + +/* Set error number and return -1. Return the internal function, + __syscall_error, which sets errno from the negative error number + and returns -1, to avoid PIC. */ +#undef INLINE_SYSCALL_ERROR_RETURN_VALUE +#define INLINE_SYSCALL_ERROR_RETURN_VALUE(resultvar) \ + __syscall_error (-(resultvar)) /* List of system calls which are supported as vsyscalls. */ # define HAVE_CLOCK_GETTIME_VSYSCALL 1 diff --git a/sysdeps/unix/sysv/linux/ia64/sysdep.h b/sysdeps/unix/sysv/linux/ia64/sysdep.h index 03efae9024..eafcc7acfb 100644 --- a/sysdeps/unix/sysv/linux/ia64/sysdep.h +++ b/sysdeps/unix/sysv/linux/ia64/sysdep.h @@ -21,6 +21,7 @@ #define _LINUX_IA64_SYSDEP_H 1 #include <sysdeps/unix/sysdep.h> +#include <sysdeps/unix/sysv/linux/sysdep.h> #include <sysdeps/ia64/sysdep.h> #include <dl-sysdep.h> #include <tls.h> diff --git a/sysdeps/unix/sysv/linux/m68k/sysdep.h b/sysdeps/unix/sysv/linux/m68k/sysdep.h index 2b88add4c8..e55446cb44 100644 --- a/sysdeps/unix/sysv/linux/m68k/sysdep.h +++ b/sysdeps/unix/sysv/linux/m68k/sysdep.h @@ -17,6 +17,7 @@ License along with the GNU C Library. If not, see <http://www.gnu.org/licenses/>. */ +#include <sysdeps/unix/sysv/linux/sysdep.h> #include <tls.h> /* Defines RTLD_PRIVATE_ERRNO. */ diff --git a/sysdeps/unix/sysv/linux/microblaze/sysdep.h b/sysdeps/unix/sysv/linux/microblaze/sysdep.h index 9d5c542633..75dd11f741 100644 --- a/sysdeps/unix/sysv/linux/microblaze/sysdep.h +++ b/sysdeps/unix/sysv/linux/microblaze/sysdep.h @@ -20,6 +20,7 @@ #define _LINUX_MICROBLAZE_SYSDEP_H 1 #include <sysdeps/unix/sysdep.h> +#include <sysdeps/unix/sysv/linux/sysdep.h> #include <sysdeps/microblaze/sysdep.h> /* Defines RTLD_PRIVATE_ERRNO. */ diff --git a/sysdeps/unix/sysv/linux/mips/mips32/sysdep.h b/sysdeps/unix/sysv/linux/mips/mips32/sysdep.h index a2aa38ddd7..cb8f4a8d94 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/sysdep.h +++ b/sysdeps/unix/sysv/linux/mips/mips32/sysdep.h @@ -19,6 +19,7 @@ #define _LINUX_MIPS_MIPS32_SYSDEP_H 1 /* There is some commonality. */ +#include <sysdeps/unix/sysv/linux/sysdep.h> #include <sysdeps/unix/mips/mips32/sysdep.h> #include <tls.h> diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/sysdep.h b/sysdeps/unix/sysv/linux/mips/mips64/n32/sysdep.h index 4c28af6c3e..b97bf0b63b 100644 --- a/sysdeps/unix/sysv/linux/mips/mips64/n32/sysdep.h +++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/sysdep.h @@ -19,6 +19,7 @@ #define _LINUX_MIPS_SYSDEP_H 1 /* There is some commonality. */ +#include <sysdeps/unix/sysv/linux/sysdep.h> #include <sysdeps/unix/mips/mips64/n32/sysdep.h> #include <tls.h> diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/sysdep.h b/sysdeps/unix/sysv/linux/mips/mips64/n64/sysdep.h index 1fc038c27f..6bbeeb0ee3 100644 --- a/sysdeps/unix/sysv/linux/mips/mips64/n64/sysdep.h +++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/sysdep.h @@ -19,6 +19,7 @@ #define _LINUX_MIPS_SYSDEP_H 1 /* There is some commonality. */ +#include <sysdeps/unix/sysv/linux/sysdep.h> #include <sysdeps/unix/mips/mips64/n64/sysdep.h> #include <tls.h> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h b/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h index dc56bea49a..7f389e478b 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h @@ -18,6 +18,7 @@ #ifndef _LINUX_POWERPC_SYSDEP_H #define _LINUX_POWERPC_SYSDEP_H 1 +#include <sysdeps/unix/sysv/linux/sysdep.h> #include <sysdeps/unix/powerpc/sysdep.h> #include <tls.h> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h b/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h index e2014cca39..6803cce70f 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h @@ -20,6 +20,7 @@ #ifndef _LINUX_POWERPC_SYSDEP_H #define _LINUX_POWERPC_SYSDEP_H 1 +#include <sysdeps/unix/sysv/linux/sysdep.h> #include <sysdeps/unix/powerpc/sysdep.h> #include <tls.h> diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/sysdep.h b/sysdeps/unix/sysv/linux/s390/s390-32/sysdep.h index c768df1743..d29b68593d 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-32/sysdep.h +++ b/sysdeps/unix/sysv/linux/s390/s390-32/sysdep.h @@ -21,6 +21,7 @@ #include <sysdeps/s390/s390-32/sysdep.h> #include <sysdeps/unix/sysdep.h> +#include <sysdeps/unix/sysv/linux/sysdep.h> #include <dl-sysdep.h> /* For RTLD_PRIVATE_ERRNO. */ #include <tls.h> diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h b/sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h index c041153b3a..a373207dff 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h +++ b/sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h @@ -22,6 +22,7 @@ #include <sysdeps/s390/s390-64/sysdep.h> #include <sysdeps/unix/sysdep.h> +#include <sysdeps/unix/sysv/linux/sysdep.h> #include <dl-sysdep.h> /* For RTLD_PRIVATE_ERRNO. */ #include <tls.h> diff --git a/sysdeps/unix/sysv/linux/sh/sysdep.h b/sysdeps/unix/sysv/linux/sh/sysdep.h index 5226ff611c..ab5b2c3d70 100644 --- a/sysdeps/unix/sysv/linux/sh/sysdep.h +++ b/sysdeps/unix/sysv/linux/sh/sysdep.h @@ -21,6 +21,7 @@ #define _LINUX_SH_SYSDEP_H 1 /* There is some commonality. */ +#include <sysdeps/unix/sysv/linux/sysdep.h> #include <sysdeps/unix/sh/sysdep.h> #include <tls.h> diff --git a/sysdeps/unix/sysv/linux/sparc/sysdep.h b/sysdeps/unix/sysv/linux/sparc/sysdep.h index e215dbb3be..c9843de5b3 100644 --- a/sysdeps/unix/sysv/linux/sparc/sysdep.h +++ b/sysdeps/unix/sysv/linux/sparc/sysdep.h @@ -20,6 +20,7 @@ #define _LINUX_SPARC_SYSDEP_H 1 #include <sysdeps/unix/sysdep.h> +#include <sysdeps/unix/sysv/linux/sysdep.h> #include <sysdeps/sparc/sysdep.h> #ifdef __ASSEMBLER__ diff --git a/sysdeps/unix/sysv/linux/sysdep.h b/sysdeps/unix/sysv/linux/sysdep.h new file mode 100644 index 0000000000..a7dd887394 --- /dev/null +++ b/sysdeps/unix/sysv/linux/sysdep.h @@ -0,0 +1,25 @@ +/* Copyright (C) 2015 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, see + <http://www.gnu.org/licenses/>. */ + +/* Set error number and return -1. A target may choose to return the + internal function, __syscall_error, which sets errno and returns -1. + We use -1l, instead of -1, so that it can be casted to (void *). */ +#define INLINE_SYSCALL_ERROR_RETURN_VALUE(err) \ + ({ \ + __set_errno (err); \ + -1l; \ + }) diff --git a/sysdeps/unix/sysv/linux/x86_64/sysdep.h b/sysdeps/unix/sysv/linux/x86_64/sysdep.h index 5a62cce467..fc132f6791 100644 --- a/sysdeps/unix/sysv/linux/x86_64/sysdep.h +++ b/sysdeps/unix/sysv/linux/x86_64/sysdep.h @@ -19,6 +19,7 @@ #define _LINUX_X86_64_SYSDEP_H 1 /* There is some commonality. */ +#include <sysdeps/unix/sysv/linux/sysdep.h> #include <sysdeps/unix/x86_64/sysdep.h> #include <tls.h> |