aboutsummaryrefslogtreecommitdiff
path: root/sysdeps/unix
diff options
context:
space:
mode:
authorRoland McGrath <roland@gnu.org>1995-10-19 02:20:22 +0000
committerRoland McGrath <roland@gnu.org>1995-10-19 02:20:22 +0000
commit1d234146c04ec6a6bad50e6d1bf74cf6ff189e7a (patch)
tree2312fa6c66d401746ee00f956dc5f5534252461b /sysdeps/unix
parent580c1888bec85d6ec20b8c9d3b893b5397a71325 (diff)
downloadglibc-1d234146c04ec6a6bad50e6d1bf74cf6ff189e7a.tar
glibc-1d234146c04ec6a6bad50e6d1bf74cf6ff189e7a.tar.gz
glibc-1d234146c04ec6a6bad50e6d1bf74cf6ff189e7a.tar.bz2
glibc-1d234146c04ec6a6bad50e6d1bf74cf6ff189e7a.zip
* sysdeps/unix/sysv/linux/i386/sysdep.h (PSEUDO): Use
SYSCALL_PIC_SETUP before jumping to syscall_error. * sysdeps/unix/i386/sysdep.h (SYSCALL_PIC_SETUP): New macro. (PSEUDO): Use it before jumping to syscall_error. * sysdeps/unix/i386/sysdep.S [! PIC]: Don't find GOT address; expect it in %ebx on entry. Pop old %ebx value off stack after using it.
Diffstat (limited to 'sysdeps/unix')
-rw-r--r--sysdeps/unix/i386/sysdep.S10
-rw-r--r--sysdeps/unix/i386/sysdep.h14
-rw-r--r--sysdeps/unix/sysv/linux/i386/sysdep.h4
3 files changed, 19 insertions, 9 deletions
diff --git a/sysdeps/unix/i386/sysdep.S b/sysdeps/unix/i386/sysdep.S
index efe4f56e95..95e2fd5c7a 100644
--- a/sysdeps/unix/i386/sysdep.S
+++ b/sysdeps/unix/i386/sysdep.S
@@ -41,11 +41,11 @@ notb:
#ifndef PIC
movl %eax, C_SYMBOL_NAME(errno)
#else
- /* Standard PIC nonsense to store into `errno' through the GOT. */
- call here
-here: popl %ecx
- addl $_GLOBAL_OFFSET_TABLE_+[.-here], %ecx
- movl C_SYMBOL_NAME(errno@GOT)(%ecx), %ecx
+ /* The caller has pushed %ebx and then set it up to
+ point to the GOT before calling us through the PLT. */
+ movl C_SYMBOL_NAME(errno@GOT)(%ebx), %ecx
+ /* Pop %ebx value saved before jumping here. */
+ popl %ebx
movl %eax, (%ecx)
#endif
movl $-1, %eax
diff --git a/sysdeps/unix/i386/sysdep.h b/sysdeps/unix/i386/sysdep.h
index 7fd77dd936..fb1781b156 100644
--- a/sysdeps/unix/i386/sysdep.h
+++ b/sysdeps/unix/i386/sysdep.h
@@ -42,15 +42,23 @@ Cambridge, MA 02139, USA. */
#endif
#define PSEUDO(name, syscall_name, args) \
+lose: SYSCALL_PIC_SETUP \
+ jmp JUMPTARGET(syscall_error) \
.globl syscall_error; \
ENTRY (name) \
DO_CALL (syscall_name, args); \
- jb JUMPTARGET(syscall_error)
+ jb lose
#ifdef PIC
-#define JUMPTARGET(name) name##@PLT
+#define JUMPTARGET(name) name##@PLT
+#define SYSCALL_PIC_SETUP \
+ pushl %ebx; \
+ call 0f; \
+0: popl %ebx; \
+ addl $_GLOBAL_OFFSET_TABLE+[.-0b], %ebx;
#else
-#define JUMPTARGET(name) name
+#define JUMPTARGET(name) name
+#define SYSCALL_PIC_SETUP /* Nothing. */
#endif
/* This is defined as a separate macro so that other sysdep.h files
diff --git a/sysdeps/unix/sysv/linux/i386/sysdep.h b/sysdeps/unix/sysv/linux/i386/sysdep.h
index a40ca86e40..ccb484664f 100644
--- a/sysdeps/unix/sysv/linux/i386/sysdep.h
+++ b/sysdeps/unix/sysv/linux/i386/sysdep.h
@@ -42,12 +42,14 @@ Cambridge, MA 02139, USA. */
#undef PSEUDO
#define PSEUDO(name, syscall_name, args) \
.text; \
+ lose: SYSCALL_PIC_SETUP \
+ jmp JUMPTARGET (syscall_error) \
.globl syscall_error; \
ENTRY (name) \
movl $SYS_ify (syscall_name), %eax; \
DO_CALL (args); \
testl %eax, %eax; \
- jl JUMPTARGET (syscall_error)
+ jl lose
/* We define our own ENTRY macro because the alignment should be 16 for ELF. */
#undef ENTRY