aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2005-12-18 06:58:22 +0000
committerUlrich Drepper <drepper@redhat.com>2005-12-18 06:58:22 +0000
commit827b70873b41363c864fb65e99829204595d0f85 (patch)
tree5d2e3811b6b0da44f18a7c8920dffdc524e3cd66
parent8292f6fc71a60e92a23be053c500f504c6802c54 (diff)
downloadglibc-827b70873b41363c864fb65e99829204595d0f85.zip
glibc-827b70873b41363c864fb65e99829204595d0f85.tar.gz
glibc-827b70873b41363c864fb65e99829204595d0f85.tar.bz2
* elf/Versions [GLIBC_PRIVATE]: Export __pointer_chk_guard if defined.
* elf/rtld.c: Define __pointer_chk_guard_local and if necessary __pointer_chk_guard. (_rtld_global_ro): Initialize _dl_pointer_guard. (dl_main): Initialize __pointer_chk_guard_local and either __pointer_chk_guard or TLS value if necessary. (process_envvars): Recognize and handle LD_POINTER_GUARD. * sysdeps/generic/ldsodefs.h (rtld_global_ro): Add _dl_pointer_guard. * sysdeps/i386/__longjmp.S: Use PTR_DEMANGLE for PC if defined. * sysdeps/x86_64/__longjmp.S: Likewise. * sysdeps/i386/bsd-_setjmp.S: Use PTR_MANGLE for PC if defined. * sysdeps/i386/bsd-_setjmp.S: Likewise. * sysdeps/i386/setjmp.S: Likewise. [IS_IN_rtld]: Avoid call to __sigjmp_save. * sysdeps/i386/setjmp.S: Likewise. * sysdeps/unix/sysv/linux/i386/sysdep.h: Define PTR_MANGLE and PTR_DEMANGLE. * sysdeps/unix/sysv/linux/x86_64/sysdep.h: Likewise. * sysdeps/i386/elf/setjmp.S: Removed. * sysdeps/i386/elf/bsd-setjmp.S: Removed.
-rw-r--r--ChangeLog22
-rw-r--r--elf/Versions2
-rw-r--r--elf/rtld.c32
-rw-r--r--nptl/ChangeLog10
-rw-r--r--nptl/pthread_create.c5
-rw-r--r--nptl/sysdeps/i386/tcb-offsets.sym1
-rw-r--r--nptl/sysdeps/i386/tls.h9
-rw-r--r--nptl/sysdeps/x86_64/tcb-offsets.sym1
-rw-r--r--nptl/sysdeps/x86_64/tls.h10
-rw-r--r--sysdeps/generic/ldsodefs.h3
-rw-r--r--sysdeps/i386/__longjmp.S5
-rw-r--r--sysdeps/i386/bsd-_setjmp.S5
-rw-r--r--sysdeps/i386/bsd-setjmp.S7
-rw-r--r--sysdeps/i386/elf/bsd-setjmp.S82
-rw-r--r--sysdeps/i386/elf/setjmp.S70
-rw-r--r--sysdeps/i386/setjmp.S13
-rw-r--r--sysdeps/unix/sysv/linux/i386/sysdep.h11
-rw-r--r--sysdeps/unix/sysv/linux/x86_64/sysdep.h12
-rw-r--r--sysdeps/x86_64/__longjmp.S5
-rw-r--r--sysdeps/x86_64/setjmp.S15
20 files changed, 159 insertions, 161 deletions
diff --git a/ChangeLog b/ChangeLog
index b2af78c..e992f38 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,27 @@
2005-12-17 Ulrich Drepper <drepper@redhat.com>
+ * elf/Versions [GLIBC_PRIVATE]: Export __pointer_chk_guard if defined.
+ * elf/rtld.c: Define __pointer_chk_guard_local and if necessary
+ __pointer_chk_guard.
+ (_rtld_global_ro): Initialize _dl_pointer_guard.
+ (dl_main): Initialize __pointer_chk_guard_local and either
+ __pointer_chk_guard or TLS value if necessary.
+ (process_envvars): Recognize and handle LD_POINTER_GUARD.
+ * sysdeps/generic/ldsodefs.h (rtld_global_ro): Add _dl_pointer_guard.
+ * sysdeps/i386/__longjmp.S: Use PTR_DEMANGLE for PC if defined.
+ * sysdeps/x86_64/__longjmp.S: Likewise.
+ * sysdeps/i386/bsd-_setjmp.S: Use PTR_MANGLE for PC if defined.
+ * sysdeps/i386/bsd-_setjmp.S: Likewise.
+ * sysdeps/i386/setjmp.S: Likewise.
+ [IS_IN_rtld]: Avoid call to __sigjmp_save.
+ * sysdeps/i386/setjmp.S: Likewise.
+ * sysdeps/unix/sysv/linux/i386/sysdep.h: Define PTR_MANGLE and
+ PTR_DEMANGLE.
+ * sysdeps/unix/sysv/linux/x86_64/sysdep.h: Likewise.
+
+ * sysdeps/i386/elf/setjmp.S: Removed.
+ * sysdeps/i386/elf/bsd-setjmp.S: Removed.
+
* elf/dl-error.c (_dl_catch_error): Use __sigsetgjmp instead of
setjmp.
* elf/dl-error.c (_dl_signal_error): Use __longjmp instead of longjmp.
diff --git a/elf/Versions b/elf/Versions
index 9c53f16..87e27c5 100644
--- a/elf/Versions
+++ b/elf/Versions
@@ -60,5 +60,7 @@ ld {
_dl_make_stack_executable;
# Only here for gdb while a better method is developed.
_dl_debug_state;
+ # Pointer protection.
+ __pointer_chk_guard;
}
}
diff --git a/elf/rtld.c b/elf/rtld.c
index a89f89b..9ef58bb 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -90,6 +90,15 @@ INTDEF(_dl_argv)
uintptr_t __stack_chk_guard attribute_relro;
#endif
+/* Only exported for architectures that don't store the pointer guard
+ value in thread local area. */
+uintptr_t __pointer_chk_guard_local
+ attribute_relro attribute_hidden __attribute__ ((nocommon));
+#ifndef THREAD_SET_POINTER_GUARD
+strong_alias (__pointer_chk_guard_local, __pointer_chk_guard)
+#endif
+
+
/* List of auditing DSOs. */
static struct audit_list
{
@@ -142,6 +151,7 @@ struct rtld_global_ro _rtld_global_ro attribute_relro =
._dl_hwcap_mask = HWCAP_IMPORTANT,
._dl_lazy = 1,
._dl_fpu_control = _FPU_DEFAULT,
+ ._dl_pointer_guard = 1,
/* Function pointers. */
._dl_debug_printf = _dl_debug_printf,
@@ -1823,6 +1833,20 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
__stack_chk_guard = stack_chk_guard;
#endif
+ /* Set up the pointer guard as well, if necessary. */
+ if (GLRO(dl_pointer_guard))
+ {
+ // XXX If it is cheap, we should use a separate value.
+ uintptr_t pointer_chk_guard;
+ hp_timing_t now;
+ HP_TIMING_NOW (now);
+ pointer_chk_guard = stack_chk_guard ^ now;
+#ifdef THREAD_SET_POINTER_GUARD
+ THREAD_SET_POINTER_GUARD (pointer_chk_guard);
+#endif
+ __pointer_chk_guard_local = pointer_chk_guard;
+ }
+
if (__builtin_expect (mode, normal) != normal)
{
/* We were run just to list the shared libraries. It is
@@ -2575,7 +2599,13 @@ process_envvars (enum mode *modep)
#endif
if (!INTUSE(__libc_enable_secure)
&& memcmp (envline, "USE_LOAD_BIAS", 13) == 0)
- GLRO(dl_use_load_bias) = envline[14] == '1' ? -1 : 0;
+ {
+ GLRO(dl_use_load_bias) = envline[14] == '1' ? -1 : 0;
+ break;
+ }
+
+ if (memcmp (envline, "POINTER_GUARD", 13) == 0)
+ GLRO(dl_pointer_guard) = envline[14] == '0';
break;
case 14:
diff --git a/nptl/ChangeLog b/nptl/ChangeLog
index 9db2e49..7a35696 100644
--- a/nptl/ChangeLog
+++ b/nptl/ChangeLog
@@ -1,3 +1,13 @@
+2005-12-17 Ulrich Drepper <drepper@redhat.com>
+
+ * pthread_create.c (__pthread_create_2_1): Use
+ THREAD_COPY_POINTER_GUARD if available.
+ * sysdeps/i386/tcb-offsets.sym: Add POINTER_GUARD.
+ * sysdeps/x86_64/tcb-offsets.sym: Likewise.
+ * sysdeps/i386/tls.h (tcbhead_t): Add pointer_guard.
+ Define THREAD_SET_POINTER_GUARD and THREAD_COPY_POINTER_GUARD.
+ * sysdeps/x86_64/tls.h: Likewise.
+
2005-12-15 Roland McGrath <roland@redhat.com>
* sysdeps/unix/sysv/linux/mq_notify.c: Don't use sysdeps/generic.
diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c
index f2f206b..c11d972 100644
--- a/nptl/pthread_create.c
+++ b/nptl/pthread_create.c
@@ -415,6 +415,11 @@ __pthread_create_2_1 (newthread, attr, start_routine, arg)
THREAD_COPY_STACK_GUARD (pd);
#endif
+ /* Copy the pointer guard value. */
+#ifdef THREAD_COPY_POINTER_GUARD
+ THREAD_COPY_POINTER_GUARD (pd);
+#endif
+
/* Determine scheduling parameters for the thread. */
if (attr != NULL
&& __builtin_expect ((iattr->flags & ATTR_FLAG_NOTINHERITSCHED) != 0, 0)
diff --git a/nptl/sysdeps/i386/tcb-offsets.sym b/nptl/sysdeps/i386/tcb-offsets.sym
index 4e0444b..7c8d9a5 100644
--- a/nptl/sysdeps/i386/tcb-offsets.sym
+++ b/nptl/sysdeps/i386/tcb-offsets.sym
@@ -11,3 +11,4 @@ SYSINFO_OFFSET offsetof (tcbhead_t, sysinfo)
CLEANUP offsetof (struct pthread, cleanup)
CLEANUP_PREV offsetof (struct _pthread_cleanup_buffer, __prev)
MUTEX_FUTEX offsetof (pthread_mutex_t, __data.__lock)
+POINTER_GUARD offsetof (tcbhead_t, pointer_guard)
diff --git a/nptl/sysdeps/i386/tls.h b/nptl/sysdeps/i386/tls.h
index 65566ff..a870a84 100644
--- a/nptl/sysdeps/i386/tls.h
+++ b/nptl/sysdeps/i386/tls.h
@@ -50,6 +50,7 @@ typedef struct
int multiple_threads;
uintptr_t sysinfo;
uintptr_t stack_guard;
+ uintptr_t pointer_guard;
} tcbhead_t;
# define TLS_MULTIPLE_THREADS_IN_TCB 1
@@ -425,6 +426,14 @@ union user_desc_init
= THREAD_GETMEM (THREAD_SELF, header.stack_guard))
+/* Set the pointer guard field in the TCB head. */
+#define THREAD_SET_POINTER_GUARD(value) \
+ THREAD_SETMEM (THREAD_SELF, header.pointer_guard, value)
+#define THREAD_COPY_POINTER_GUARD(descr) \
+ ((descr)->header.pointer_guard \
+ = THREAD_GETMEM (THREAD_SELF, header.pointer_guard))
+
+
#endif /* __ASSEMBLER__ */
#endif /* tls.h */
diff --git a/nptl/sysdeps/x86_64/tcb-offsets.sym b/nptl/sysdeps/x86_64/tcb-offsets.sym
index 8118d2d..a9ede75 100644
--- a/nptl/sysdeps/x86_64/tcb-offsets.sym
+++ b/nptl/sysdeps/x86_64/tcb-offsets.sym
@@ -10,3 +10,4 @@ CLEANUP offsetof (struct pthread, cleanup)
CLEANUP_PREV offsetof (struct _pthread_cleanup_buffer, __prev)
MUTEX_FUTEX offsetof (pthread_mutex_t, __data.__lock)
MULTIPLE_THREADS_OFFSET offsetof (tcbhead_t, multiple_threads)
+POINTER_GUARD offsetof (tcbhead_t, pointer_guard)
diff --git a/nptl/sysdeps/x86_64/tls.h b/nptl/sysdeps/x86_64/tls.h
index 516827b..13cf6fb 100644
--- a/nptl/sysdeps/x86_64/tls.h
+++ b/nptl/sysdeps/x86_64/tls.h
@@ -49,6 +49,7 @@ typedef struct
int multiple_threads;
uintptr_t sysinfo;
uintptr_t stack_guard;
+ uintptr_t pointer_guard;
} tcbhead_t;
#else /* __ASSEMBLER__ */
@@ -329,6 +330,15 @@ typedef struct
((descr)->header.stack_guard \
= THREAD_GETMEM (THREAD_SELF, header.stack_guard))
+
+/* Set the pointer guard field in the TCB head. */
+#define THREAD_SET_POINTER_GUARD(value) \
+ THREAD_SETMEM (THREAD_SELF, header.pointer_guard, value)
+#define THREAD_COPY_POINTER_GUARD(descr) \
+ ((descr)->header.pointer_guard \
+ = THREAD_GETMEM (THREAD_SELF, header.pointer_guard))
+
+
#endif /* __ASSEMBLER__ */
#endif /* tls.h */
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
index 67a20ce..b5f7c3c 100644
--- a/sysdeps/generic/ldsodefs.h
+++ b/sysdeps/generic/ldsodefs.h
@@ -623,6 +623,9 @@ struct rtld_global_ro
/* Expected cache ID. */
EXTERN int _dl_correct_cache_id;
+ /* 0 if internal pointer values should not be guarded, 1 if they should. */
+ EXTERN int _dl_pointer_guard;
+
/* Mask for hardware capabilities that are available. */
EXTERN uint64_t _dl_hwcap;
diff --git a/sysdeps/i386/__longjmp.S b/sysdeps/i386/__longjmp.S
index 6b590f7..aced5f4 100644
--- a/sysdeps/i386/__longjmp.S
+++ b/sysdeps/i386/__longjmp.S
@@ -1,5 +1,5 @@
/* longjmp for i386.
- Copyright (C) 1995,1996,1997,1998,2000,2002 Free Software Foundation, Inc.
+ Copyright (C) 1995-1998,2000,2002,2005 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
@@ -44,6 +44,9 @@ ENTRY (BP_SYM (__longjmp))
movl (JB_DI*4)(%ecx), %edi
movl (JB_BP*4)(%ecx), %ebp
movl (JB_SP*4)(%ecx), %esp
+#ifdef PTR_DEMANGLE
+ PTR_DEMANGLE (%edx)
+#endif
/* Jump to saved PC. */
jmp *%edx
END (BP_SYM (__longjmp))
diff --git a/sysdeps/i386/bsd-_setjmp.S b/sysdeps/i386/bsd-_setjmp.S
index aa8df16..f80d239 100644
--- a/sysdeps/i386/bsd-_setjmp.S
+++ b/sysdeps/i386/bsd-_setjmp.S
@@ -1,5 +1,5 @@
/* BSD `_setjmp' entry point to `sigsetjmp (..., 0)'. i386 version.
- Copyright (C) 1994-1997,2000,2001,2002 Free Software Foundation, Inc.
+ Copyright (C) 1994-1997,2000-2002,2005 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
@@ -46,6 +46,9 @@ ENTRY (BP_SYM (_setjmp))
leal JMPBUF(%esp), %ecx /* Save SP as it will be after we return. */
movl %ecx, (JB_SP*4)(%edx)
movl PCOFF(%esp), %ecx /* Save PC we are returning to now. */
+#ifdef PTR_MANGLE
+ PTR_MANGLE (%ecx)
+#endif
movl %ecx, (JB_PC*4)(%edx)
LEAVE
movl %ebp, (JB_BP*4)(%edx) /* Save caller's frame pointer. */
diff --git a/sysdeps/i386/bsd-setjmp.S b/sysdeps/i386/bsd-setjmp.S
index b6934dc..f4257a0 100644
--- a/sysdeps/i386/bsd-setjmp.S
+++ b/sysdeps/i386/bsd-setjmp.S
@@ -28,6 +28,10 @@
#include "bp-sym.h"
#include "bp-asm.h"
+#define PARMS LINKAGE /* no space for saved regs */
+#define JMPBUF PARMS
+#define SIGMSK JMPBUF+PTR_SIZE
+
ENTRY (BP_SYM (setjmp))
/* Note that we have to use a non-exported symbol in the next
jump since otherwise gas will emit it as a jump through the
@@ -44,6 +48,9 @@ ENTRY (BP_SYM (setjmp))
leal JMPBUF(%esp), %ecx /* Save SP as it will be after we return. */
movl %ecx, (JB_SP*4)(%eax)
movl PCOFF(%esp), %ecx /* Save PC we are returning to now. */
+#ifdef PTR_MANGLE
+ PTR_MANGLE (%ecx)
+#endif
movl %ecx, (JB_PC*4)(%eax)
LEAVE /* pop frame pointer to prepare for tail-call. */
movl %ebp, (JB_BP*4)(%eax) /* Save caller's frame pointer. */
diff --git a/sysdeps/i386/elf/bsd-setjmp.S b/sysdeps/i386/elf/bsd-setjmp.S
deleted file mode 100644
index c421791..0000000
--- a/sysdeps/i386/elf/bsd-setjmp.S
+++ /dev/null
@@ -1,82 +0,0 @@
-/* BSD `setjmp' entry point to `sigsetjmp (..., 1)'. i386 version.
- Copyright (C) 1995-1997,2000-2003,2005 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, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 USA. */
-
-#include <sysdep.h>
-#define _ASM
-#define _SETJMP_H
-#include <bits/setjmp.h>
-#include "bp-sym.h"
-#include "bp-asm.h"
-
-#define PARMS LINKAGE /* no space for saved regs */
-#define JMPBUF PARMS
-#define SIGMSK JMPBUF+PTR_SIZE
-
-ENTRY (BP_SYM (setjmp))
- /* Note that we have to use a non-exported symbol in the next
- jump since otherwise gas will emit it as a jump through the
- PLT which is what we cannot use here. */
- ENTER
-
- movl JMPBUF(%esp), %eax
- CHECK_BOUNDS_BOTH_WIDE (%eax, JMPBUF(%esp), $JB_SIZE)
-
- /* Save registers. */
- movl %ebx, (JB_BX*4)(%eax)
- movl %esi, (JB_SI*4)(%eax)
- movl %edi, (JB_DI*4)(%eax)
- leal JMPBUF(%esp), %ecx /* Save SP as it will be after we return. */
- movl %ecx, (JB_SP*4)(%eax)
- movl PCOFF(%esp), %ecx /* Save PC we are returning to now. */
- movl %ecx, (JB_PC*4)(%eax)
- LEAVE /* pop frame pointer to prepare for tail-call. */
- movl %ebp, (JB_BP*4)(%eax) /* Save caller's frame pointer. */
-
- /* Call __sigjmp_save. */
- pushl $1
- cfi_adjust_cfa_offset (4)
- pushl 8(%esp)
- cfi_adjust_cfa_offset (4)
-#ifdef PIC
- /* We cannot use the PLT, because it requires that %ebx be set, but
- we can't save and restore our caller's value. Instead, we do an
- indirect jump through the GOT, using for the temporary register
- %ecx, which is call-clobbered. */
- call __i686.get_pc_thunk.cx
- addl $_GLOBAL_OFFSET_TABLE_, %ecx
- leal C_SYMBOL_NAME (BP_SYM (__sigjmp_save)@GOTOFF)(%ecx), %ecx
- call *%ecx
-#else
- call BP_SYM (__sigjmp_save)
-#endif
- popl %ecx
- cfi_adjust_cfa_offset (-4)
- popl %edx
- cfi_adjust_cfa_offset (-4)
- ret
-END (BP_SYM (setjmp))
-
- .section .gnu.linkonce.t.__i686.get_pc_thunk.cx,"ax",@progbits
- .globl __i686.get_pc_thunk.cx
- .hidden __i686.get_pc_thunk.cx
- .type __i686.get_pc_thunk.cx,@function
-__i686.get_pc_thunk.cx:
- movl (%esp), %ecx
- ret
- .size __i686.get_pc_thunk.cx, . - __i686.get_pc_thunk.cx
diff --git a/sysdeps/i386/elf/setjmp.S b/sysdeps/i386/elf/setjmp.S
deleted file mode 100644
index d6ae98b..0000000
--- a/sysdeps/i386/elf/setjmp.S
+++ /dev/null
@@ -1,70 +0,0 @@
-/* setjmp for i386, ELF version.
- Copyright (C) 1995-1997,2000,2001,2002,2003 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, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 USA. */
-
-#include <sysdep.h>
-#define _ASM
-#define _SETJMP_H
-#include <bits/setjmp.h>
-#include "bp-sym.h"
-#include "bp-asm.h"
-
-#define PARMS LINKAGE /* no space for saved regs */
-#define JMPBUF PARMS
-#define SIGMSK JMPBUF+PTR_SIZE
-
-ENTRY (BP_SYM (__sigsetjmp))
- ENTER
-
- movl JMPBUF(%esp), %eax
- CHECK_BOUNDS_BOTH_WIDE (%eax, JMPBUF(%esp), $JB_SIZE)
-
- /* Save registers. */
- movl %ebx, (JB_BX*4)(%eax)
- movl %esi, (JB_SI*4)(%eax)
- movl %edi, (JB_DI*4)(%eax)
- leal JMPBUF(%esp), %ecx /* Save SP as it will be after we return. */
- movl %ecx, (JB_SP*4)(%eax)
- movl PCOFF(%esp), %ecx /* Save PC we are returning to now. */
- movl %ecx, (JB_PC*4)(%eax)
- LEAVE /* pop frame pointer to prepare for tail-call. */
- movl %ebp, (JB_BP*4)(%eax) /* Save caller's frame pointer. */
-
- /* Make a tail call to __sigjmp_save; it takes the same args. */
-#ifdef PIC
- /* We cannot use the PLT, because it requires that %ebx be set, but
- we can't save and restore our caller's value. Instead, we do an
- indirect jump through the GOT, using for the temporary register
- %ecx, which is call-clobbered. */
- call __i686.get_pc_thunk.cx
- addl $_GLOBAL_OFFSET_TABLE_, %ecx
- leal C_SYMBOL_NAME (BP_SYM (__sigjmp_save)@GOTOFF)(%ecx), %ecx
- jmp *%ecx
-#else
- jmp BP_SYM (__sigjmp_save)
-#endif
-END (BP_SYM (__sigsetjmp))
-
- .section .gnu.linkonce.t.__i686.get_pc_thunk.cx,"ax",@progbits
- .globl __i686.get_pc_thunk.cx
- .hidden __i686.get_pc_thunk.cx
- .type __i686.get_pc_thunk.cx,@function
-__i686.get_pc_thunk.cx:
- movl (%esp), %ecx
- ret
- .size __i686.get_pc_thunk.cx, . - __i686.get_pc_thunk.cx
diff --git a/sysdeps/i386/setjmp.S b/sysdeps/i386/setjmp.S
index e01d32b..747499a 100644
--- a/sysdeps/i386/setjmp.S
+++ b/sysdeps/i386/setjmp.S
@@ -1,5 +1,5 @@
/* setjmp for i386.
- Copyright (C) 1995, 1996, 1997, 2000, 2001 Free Software Foundation, Inc.
+ Copyright (C) 1995,1996,1997,2000,2001,2005 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
@@ -42,10 +42,19 @@ ENTRY (BP_SYM (__sigsetjmp))
leal JMPBUF(%esp), %ecx /* Save SP as it will be after we return. */
movl %ecx, (JB_SP*4)(%eax)
movl PCOFF(%esp), %ecx /* Save PC we are returning to now. */
+#ifdef PTR_MANGLE
+ PTR_MANGLE (%ecx)
+#endif
movl %ecx, (JB_PC*4)(%eax)
LEAVE /* pop frame pointer to prepare for tail-call. */
movl %ebp, (JB_BP*4)(%eax) /* Save caller's frame pointer. */
+#if defined NOT_IN_libc && defined IS_IN_rtld
+ /* In ld.so we never save the signal mask. */
+ xorl %eax, %eax
+ ret
+#else
/* Make a tail call to __sigjmp_save; it takes the same args. */
- jmp BP_SYM (__sigjmp_save)
+ jmp __sigjmp_save
+#endif
END (BP_SYM (__sigsetjmp))
diff --git a/sysdeps/unix/sysv/linux/i386/sysdep.h b/sysdeps/unix/sysv/linux/i386/sysdep.h
index 99f9bf1..929c6e5 100644
--- a/sysdeps/unix/sysv/linux/i386/sysdep.h
+++ b/sysdeps/unix/sysv/linux/i386/sysdep.h
@@ -558,4 +558,15 @@ asm (".L__X'%ebx = 1\n\t"
#endif /* __ASSEMBLER__ */
+
+/* Pointer mangling support. */
+#if defined NOT_IN_libc && defined IS_IN_rtld
+/* We cannot use the thread descriptor because in ld.so we use setjmp
+ earlier than the descriptor is initialized. Using a global variable
+ is too complicated here since we have no PC-relative addressing mode. */
+#else
+# define PTR_MANGLE(reg) xorl %gs:POINTER_GUARD, reg
+# define PTR_DEMANGLE(reg) PTR_MANGLE (reg)
+#endif
+
#endif /* linux/i386/sysdep.h */
diff --git a/sysdeps/unix/sysv/linux/x86_64/sysdep.h b/sysdeps/unix/sysv/linux/x86_64/sysdep.h
index 0dc2f27..2ea69c3 100644
--- a/sysdeps/unix/sysv/linux/x86_64/sysdep.h
+++ b/sysdeps/unix/sysv/linux/x86_64/sysdep.h
@@ -311,4 +311,16 @@
#endif /* __ASSEMBLER__ */
+
+/* Pointer mangling support. */
+#if defined NOT_IN_libc && defined IS_IN_rtld
+/* We cannot use the thread descriptor because in ld.so we use setjmp
+ earlier than the descriptor is initialized. */
+# define PTR_MANGLE(reg) xorq __pointer_chk_guard_local(%rip), reg
+# define PTR_DEMANGLE(reg) PTR_MANGLE (reg)
+#else
+# define PTR_MANGLE(reg) xorq %fs:POINTER_GUARD, reg
+# define PTR_DEMANGLE(reg) PTR_MANGLE (reg)
+#endif
+
#endif /* linux/x86_64/sysdep.h */
diff --git a/sysdeps/x86_64/__longjmp.S b/sysdeps/x86_64/__longjmp.S
index 9ed480c..becfb4f 100644
--- a/sysdeps/x86_64/__longjmp.S
+++ b/sysdeps/x86_64/__longjmp.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2001, 2004, 2005 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
@@ -50,5 +50,8 @@ ENTRY(__longjmp)
mov %esi, %eax
movq (JB_PC*8)(%rdi),%rdx
movq (JB_RSP*8)(%rdi),%rsp
+#ifdef PTR_DEMANGLE
+ PTR_DEMANGLE (%rdx)
+#endif
jmpq *%rdx
END (BP_SYM (__longjmp))
diff --git a/sysdeps/x86_64/setjmp.S b/sysdeps/x86_64/setjmp.S
index 811ab1d..8af5502 100644
--- a/sysdeps/x86_64/setjmp.S
+++ b/sysdeps/x86_64/setjmp.S
@@ -1,5 +1,5 @@
/* setjmp for x86-64.
- Copyright (C) 2001, 2003 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2003, 2005 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
@@ -34,13 +34,22 @@ ENTRY (__sigsetjmp)
leaq 8(%rsp), %rdx /* Save SP as it will be after we return. */
movq %rdx, (JB_RSP*8)(%rdi)
movq (%rsp), %rax /* Save PC we are returning to now. */
+#ifdef PTR_MANGLE
+ PTR_MANGLE (%rax)
+#endif
movq %rax, (JB_PC*8)(%rdi)
+#if defined NOT_IN_libc && defined IS_IN_rtld
+ /* In ld.so we never save the signal mask. */
+ xorl %eax, %eax
+ retq
+#else
/* Make a tail call to __sigjmp_save; it takes the same args. */
-#ifdef PIC
+# ifdef PIC
jmp C_SYMBOL_NAME (BP_SYM (__sigjmp_save))@PLT
-#else
+# else
jmp BP_SYM (__sigjmp_save)
+# endif
#endif
END (BP_SYM (__sigsetjmp))
hidden_def (__sigsetjmp)