diff options
Diffstat (limited to 'sysdeps/unix/sysv')
-rw-r--r-- | sysdeps/unix/sysv/linux/i386/sysdep.S | 29 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/i386/sysdep.h | 27 |
2 files changed, 39 insertions, 17 deletions
diff --git a/sysdeps/unix/sysv/linux/i386/sysdep.S b/sysdeps/unix/sysv/linux/i386/sysdep.S index 5bbe3b745d..f5ac8aa017 100644 --- a/sysdeps/unix/sysv/linux/i386/sysdep.S +++ b/sysdeps/unix/sysv/linux/i386/sysdep.S @@ -16,17 +16,6 @@ License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* 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. */ - -.globl __syscall_error -__syscall_error: - negl %eax - -#define __syscall_error __syscall_error_1 -#include <sysdeps/unix/i386/sysdep.S> - /* Because the Linux version is in fact i386/ELF and the start.? file for this system (sysdeps/i386/elf/start.S) is also used by The Hurd and therefore this files must not contain the definition of the @@ -38,3 +27,21 @@ __syscall_error: .globl errno errno: .long 0 + +/* The following code is not used at all in the shared library. + The PIC system call stubs set errno themselves. */ + +#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. */ + +.globl __syscall_error +__syscall_error: + negl %eax + +#define __syscall_error __syscall_error_1 +#include <sysdeps/unix/i386/sysdep.S> + +#endif diff --git a/sysdeps/unix/sysv/linux/i386/sysdep.h b/sysdeps/unix/sysv/linux/i386/sysdep.h index ccb484664f..7bd910e534 100644 --- a/sysdeps/unix/sysv/linux/i386/sysdep.h +++ b/sysdeps/unix/sysv/linux/i386/sysdep.h @@ -42,16 +42,31 @@ Cambridge, MA 02139, USA. */ #undef PSEUDO #define PSEUDO(name, syscall_name, args) \ .text; \ - lose: SYSCALL_PIC_SETUP \ - jmp JUMPTARGET (syscall_error) \ - .globl syscall_error; \ + SYSCALL_ERROR_HANDLER \ ENTRY (name) \ movl $SYS_ify (syscall_name), %eax; \ DO_CALL (args); \ testl %eax, %eax; \ - jl lose + jl syscall_error; -/* We define our own ENTRY macro because the alignment should be 16 for ELF. */ +#ifndef PIC +#define SYSCALL_ERROR_HANDLER /* Nothing here; code in sysdep.S is used. */ +#else +/* Store (- %eax) into errno through the GOT. */ +#define SYSCALL_ERROR_HANDLER \ +syscall_error: \ + call 0f; \ +0:popl %ecx; \ + negl %eax; \ + addl $_GLOBAL_OFFSET_TABLE_+[.-0b], %ecx; \ + movl errno@GOT(%ecx), %ecx; \ + movl %eax, (%ecx); \ + movl $-1, %eax; \ + ret +#endif + +/* We define our own ENTRY macro because the alignment should be 16 for + ELF. */ #undef ENTRY #define ENTRY(name) \ ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME (name); \ @@ -81,7 +96,7 @@ Cambridge, MA 02139, USA. */ arguments 4 and 5.) The following code tries hard to be optimal. A general assuption - (which is true accoriding to the data books I have) is that + (which is true according to the data books I have) is that 2 * xchg is more expensive than pushl + movl + popl |