aboutsummaryrefslogtreecommitdiff
path: root/sysdeps/unix/sysv/linux/i386/sysdep.h
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/unix/sysv/linux/i386/sysdep.h')
-rw-r--r--sysdeps/unix/sysv/linux/i386/sysdep.h42
1 files changed, 34 insertions, 8 deletions
diff --git a/sysdeps/unix/sysv/linux/i386/sysdep.h b/sysdeps/unix/sysv/linux/i386/sysdep.h
index ed0bdf6b7d..87dfe9042c 100644
--- a/sysdeps/unix/sysv/linux/i386/sysdep.h
+++ b/sysdeps/unix/sysv/linux/i386/sysdep.h
@@ -26,6 +26,12 @@
#include <bp-asm.h>
#include <tls.h>
+
+#ifdef IS_IN_rtld
+# include <dl-sysdep.h> /* Defines RTLD_PRIVATE_ERRNO. */
+#endif
+
+
/* For Linux we can use the system call table in the header file
/usr/include/asm/unistd.h
of the kernel. But these symbols do not follow the SYS_* syntax
@@ -92,10 +98,19 @@ __i686.get_pc_thunk.reg: \
call __i686.get_pc_thunk.reg
# endif
-/* Store (- %eax) into errno through the GOT. */
-# ifdef _LIBC_REENTRANT
+# if RTLD_PRIVATE_ERRNO
+# define SYSCALL_ERROR_HANDLER \
+0:SETUP_PIC_REG(cx); \
+ addl $_GLOBAL_OFFSET_TABLE_, %ecx; \
+ xorl %edx, %edx; \
+ subl %eax, %edx; \
+ movl %edx, errno@GOTOFF(%ecx); \
+ orl $-1, %eax; \
+ jmp L(pseudo_end);
-# if USE_TLS && HAVE___THREAD
+# elif defined _LIBC_REENTRANT
+
+# if USE___THREAD
# define SYSCALL_ERROR_HANDLER \
0:SETUP_PIC_REG (cx); \
addl $_GLOBAL_OFFSET_TABLE_, %ecx; \
@@ -125,6 +140,7 @@ __i686.get_pc_thunk.reg: \
not modify the stack! */
# endif
# else
+/* Store (- %eax) into errno through the GOT. */
# define SYSCALL_ERROR_HANDLER \
0:SETUP_PIC_REG(cx); \
addl $_GLOBAL_OFFSET_TABLE_, %ecx; \
@@ -274,6 +290,21 @@ asm (".L__X'%ebx = 1\n\t"
#undef INLINE_SYSCALL
#define INLINE_SYSCALL(name, nr, args...) \
({ \
+ unsigned int resultvar = INTERNAL_SYSCALL(name, nr, args); \
+ if (resultvar >= 0xfffff001) \
+ { \
+ __set_errno (-resultvar); \
+ resultvar = 0xffffffff; \
+ } \
+ (int) resultvar; })
+
+/* Define a macro which expands inline into the wrapper code for a system
+ call. This use is for internal calls that do not need to handle errors
+ normally. It will never touch errno. This returns just what the kernel
+ gave back. */
+#undef INTERNAL_SYSCALL
+#define INTERNAL_SYSCALL(name, nr, args...) \
+ ({ \
unsigned int resultvar; \
asm volatile ( \
LOADARGS_##nr \
@@ -282,11 +313,6 @@ asm (".L__X'%ebx = 1\n\t"
RESTOREARGS_##nr \
: "=a" (resultvar) \
: "i" (__NR_##name) ASMFMT_##nr(args) : "memory", "cc"); \
- if (resultvar >= 0xfffff001) \
- { \
- __set_errno (-resultvar); \
- resultvar = 0xffffffff; \
- } \
(int) resultvar; })
#define LOADARGS_0