aboutsummaryrefslogtreecommitdiff
path: root/sysdeps/unix/sysv
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/unix/sysv')
-rw-r--r--sysdeps/unix/sysv/linux/i386/sysdep.S29
-rw-r--r--sysdeps/unix/sysv/linux/i386/sysdep.h27
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