This is the mail archive of the
libc-ports@sources.redhat.com
mailing list for the libc-ports project.
Fix LinuxThreads 2.4 build for various TLS targets
- From: Daniel Jacobowitz <drow at false dot org>
- To: libc-ports at sourceware dot org
- Date: Wed, 26 Apr 2006 11:09:06 -0400
- Subject: Fix LinuxThreads 2.4 build for various TLS targets
LinuxThreads hasn't built on targets with pointer guards in a while,
because the bits in libc/sysdeps/ reference members of the TCB that
were defined under nptl/sysdeps/. This updates LinuxThreads to match.
I've only tested i686 and x86_64.
By the way, as many people have discovered for themselves, building a
default i686-pc-linux-gnu configuration with LinuxThreads doesn't work
(errors finding _errno, _h_errno, _res). I'm not planning to fix this,
since it is symptomatic of a larger problem that would take some
work to get right: we lie to LinuxThreads about whether TLS is
available if we support a kernel too early to use FLOATING_STACKS.
It's easy to fix: either --enable-kernel=2.4.0, or --without-__thread.
Both of those will give you a dynamic linker which supports TLS. The
former will give you a LinuxThreads which uses it, the latter won't.
The problem only arose when LinuxThreads was configured not to use
__thread variables, but libc was configured to use __thread int errno.
No relation to the i486/i586 TLS build failure reported recently.
--
Daniel Jacobowitz
CodeSourcery
2006-04-26 Daniel Jacobowitz <dan@codesourcery.com>
Import pointer and stack guard changes from NPTL.
* descr.h (struct _pthread_descr_struct): Include sysinfo
unconditionally. Add stack_guard and pointer_guard.
(PTHREAD_STRUCT_END_PADDING): Define.
* manager.c (pthread_handle_create): Copy the pointer and
stack guards.
* pthread.c (__pthread_initialize_manager): Likewise.
* sysdeps/i386/tcb-offsets.sym: Add POINTER_GUARD.
* sysdeps/i386/tls.h (tcbhead_t): Add stack_guard and pointer_guard.
(THREAD_SET_STACK_GUARD, THREAD_COPY_STACK_GUARD,
THREAD_SET_POINTER_GUARD, THREAD_COPY_POINTER_GUARD): Define.
* sysdeps/ia64/tls.h (TLS_PRE_TCB_SIZE): If PTHREAD_STRUCT_END_PADDING
is smaller than 16 bytes, increase TLS_PRE_TCB_SIZE by 16 bytes.
(THREAD_SYSINFO, THREAD_SELF): Don't assume TLS_PRE_TCB_SIZE is
sizeof (struct _pthread_descr_struct).
(THREAD_SET_STACK_GUARD, THREAD_COPY_STACK_GUARD,
THREAD_GET_POINTER_GUARD, THREAD_SET_POINTER_GUARD,
THREAD_COPY_POINTER_GUARD): Define.
* sysdeps/ia64/tcb-offsets.sym (MULTIPLE_THREADS_OFFSET):
Use TLS_PRE_TCB_SIZE instead of sizeof (struct pthread).
* sysdeps/powerpc/tcb-offsets.sym (POINTER_GUARD): Add.
* sysdeps/powerpc/tls.h (tcbhead_t): Add stack_guard and
pointer_guard.
(THREAD_SET_STACK_GUARD, THREAD_COPY_STACK_GUARD,
THREAD_GET_POINTER_GUARD, THREAD_SET_POINTER_GUARD,
THREAD_COPY_POINTER_GUARD): Define.
* sysdeps/s390/tcb-offsets.sym (STACK_GUARD): Add.
* sysdeps/s390/tls.h (tcbhead_t): Add stack_guard
field. Put in sysinfo field unconditionally.
(THREAD_SET_STACK_GUARD, THREAD_COPY_STACK_GUARD,
THREAD_GET_POINTER_GUARD, THREAD_SET_POINTER_GUARD,
THREAD_COPY_POINTER_GUARD): Define.
* sysdeps/sh/tcb-offsets.sym: Add POINTER_GUARD.
* sysdeps/sh/tls.h (tcbhead_t): Remove private and add pointer_guard.
(THREAD_GET_POINTER_GUARD, THREAD_SET_POINTER_GUARD,
THREAD_COPY_POINTER_GUARD): Define.
* sysdeps/sparc/tls.h (tcbhead_t): Add sysinfo, stack_guard,
and pointer_guard fields.
(THREAD_SET_STACK_GUARD, THREAD_COPY_STACK_GUARD,
THREAD_GET_POINTER_GUARD, THREAD_SET_POINTER_GUARD,
THREAD_COPY_POINTER_GUARD): Define.
* sysdeps/sparc/tcb-offsets.sym (POINTER_GUARD): Define.
* sysdeps/x86_64/tcb-offsets.sym (POINTER_GUARD): New.
* sysdeps/x86_64/tls.h: Include <stdint.h>.
(tcbhead_t): Add sysinfo, stack_guard, and pointer_guard.
(THREAD_SET_STACK_GUARD, THREAD_COPY_STACK_GUARD,
THREAD_SET_POINTER_GUARD, THREAD_COPY_POINTER_GUARD): New.
* Makefile: Add rules to build and run tst-stackguard1{,-static}
tests.
* tst-stackguard1.c: New file.
* tst-stackguard1-static.c: New file.
Index: linuxthreads/Makefile
===================================================================
RCS file: /cvs/glibc/linuxthreads/linuxthreads/Makefile,v
retrieving revision 1.100
diff -u -p -r1.100 Makefile
--- linuxthreads/Makefile 28 Feb 2006 07:13:34 -0000 1.100
+++ linuxthreads/Makefile 26 Apr 2006 14:58:00 -0000
@@ -117,13 +117,14 @@ test-srcs = tst-signal
tests-reverse += tst-cancel5
ifeq ($(build-static),yes)
-tests += tststatic tst-static-locale tst-cancel-static
-tests-static += tststatic tst-static-locale tst-cancel-static
+tests += tststatic tst-static-locale tst-cancel-static tst-stackguard1-static
+tests-static += tststatic tst-static-locale tst-cancel-static \
+ tst-stackguard1-static
endif
ifeq (yes,$(build-shared))
tests-nodelete-yes = unload
-tests += tst-tls1 tst-_res1
+tests += tst-tls1 tst-_res1 tst-stackguard1
endif
modules-names = tst-_res1mod1 tst-_res1mod2 \
@@ -340,3 +341,6 @@ $(objpfx)tst-cancel-wrappers.out: tst-ca
generated += tst-signal.out tst-cancel-wrappers.out
endif
endif
+
+tst-stackguard1-ARGS = --command "$(built-program-cmd) --child"
+tst-stackguard1-static-ARGS = --command "$(objpfx)tst-stackguard1-static --child"
Index: linuxthreads/descr.h
===================================================================
RCS file: /cvs/glibc/linuxthreads/linuxthreads/descr.h,v
retrieving revision 1.16
diff -u -p -r1.16 descr.h
--- linuxthreads/descr.h 11 Nov 2005 22:30:26 -0000 1.16
+++ linuxthreads/descr.h 26 Apr 2006 14:58:00 -0000
@@ -120,9 +120,9 @@ struct _pthread_descr_struct
union dtv *dtvp;
pthread_descr self; /* Pointer to this structure */
int multiple_threads;
-# ifdef NEED_DL_SYSINFO
uintptr_t sysinfo;
-# endif
+ uintptr_t stack_guard;
+ uintptr_t pointer_guard;
} data;
void *__padding[16];
} p_header;
@@ -190,6 +190,13 @@ struct _pthread_descr_struct
size_t p_alloca_cutoff; /* Maximum size which should be allocated
using alloca() instead of malloc(). */
/* New elements must be added at the end. */
+
+ /* This member must be last. */
+ char end_padding[];
+
+#define PTHREAD_STRUCT_END_PADDING \
+ (sizeof (struct _pthread_descr_struct) \
+ - offsetof (struct _pthread_descr_struct, end_padding))
} __attribute__ ((aligned(32))); /* We need to align the structure so that
doubles are aligned properly. This is 8
bytes on MIPS and 16 bytes on MIPS64.
Index: linuxthreads/manager.c
===================================================================
RCS file: /cvs/glibc/linuxthreads/linuxthreads/manager.c,v
retrieving revision 1.98
diff -u -p -r1.98 manager.c
--- linuxthreads/manager.c 3 May 2004 21:41:23 -0000 1.98
+++ linuxthreads/manager.c 26 Apr 2006 14:58:01 -0000
@@ -670,6 +670,17 @@ static int pthread_handle_create(pthread
new_thread->p_inheritsched = attr ? attr->__inheritsched : 0;
new_thread->p_alloca_cutoff = stksize / 4 > __MAX_ALLOCA_CUTOFF
? __MAX_ALLOCA_CUTOFF : stksize / 4;
+
+ /* Copy the stack guard canary. */
+#ifdef THREAD_COPY_STACK_GUARD
+ THREAD_COPY_STACK_GUARD (new_thread);
+#endif
+
+ /* Copy the pointer guard value. */
+#ifdef THREAD_COPY_POINTER_GUARD
+ THREAD_COPY_POINTER_GUARD (new_thread);
+#endif
+
/* Initialize the thread handle */
__pthread_init_lock(&__pthread_handles[sseg].h_lock);
__pthread_handles[sseg].h_descr = new_thread;
Index: linuxthreads/pthread.c
===================================================================
RCS file: /cvs/glibc/linuxthreads/linuxthreads/pthread.c,v
retrieving revision 1.136
diff -u -p -r1.136 pthread.c
--- linuxthreads/pthread.c 9 Jan 2005 20:02:37 -0000 1.136
+++ linuxthreads/pthread.c 26 Apr 2006 14:58:01 -0000
@@ -696,6 +696,16 @@ int __pthread_initialize_manager(void)
mgr = &__pthread_manager_thread;
#endif
+ /* Copy the stack guard canary. */
+#ifdef THREAD_COPY_STACK_GUARD
+ THREAD_COPY_STACK_GUARD (mgr);
+#endif
+
+ /* Copy the pointer guard value. */
+#ifdef THREAD_COPY_POINTER_GUARD
+ THREAD_COPY_POINTER_GUARD (mgr);
+#endif
+
__pthread_manager_request = manager_pipe[1]; /* writing end */
__pthread_manager_reader = manager_pipe[0]; /* reading end */
Index: linuxthreads/tst-stackguard1-static.c
===================================================================
RCS file: linuxthreads/tst-stackguard1-static.c
diff -N linuxthreads/tst-stackguard1-static.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linuxthreads/tst-stackguard1-static.c 26 Apr 2006 14:58:01 -0000
@@ -0,0 +1 @@
+#include "tst-stackguard1.c"
Index: linuxthreads/tst-stackguard1.c
===================================================================
RCS file: linuxthreads/tst-stackguard1.c
diff -N linuxthreads/tst-stackguard1.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linuxthreads/tst-stackguard1.c 26 Apr 2006 14:58:01 -0000
@@ -0,0 +1,226 @@
+/* Copyright (C) 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub@redhat.com>, 2005.
+
+ 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 <errno.h>
+#include <pthread.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/wait.h>
+#include <elf/stackguard-macros.h>
+#include <unistd.h>
+
+static const char *command;
+static bool child;
+static uintptr_t stack_chk_guard_copy;
+static bool stack_chk_guard_copy_set;
+static int fds[2];
+
+static void __attribute__ ((constructor))
+con (void)
+{
+ stack_chk_guard_copy = STACK_CHK_GUARD;
+ stack_chk_guard_copy_set = true;
+}
+
+static int
+uintptr_t_cmp (const void *a, const void *b)
+{
+ if (*(uintptr_t *) a < *(uintptr_t *) b)
+ return 1;
+ if (*(uintptr_t *) a > *(uintptr_t *) b)
+ return -1;
+ return 0;
+}
+
+static void *
+tf (void *arg)
+{
+ if (stack_chk_guard_copy != STACK_CHK_GUARD)
+ {
+ puts ("STACK_CHK_GUARD changed in thread");
+ return (void *) 1L;
+ }
+ return NULL;
+}
+
+static int
+do_test (void)
+{
+ if (!stack_chk_guard_copy_set)
+ {
+ puts ("constructor has not been run");
+ return 1;
+ }
+
+ if (stack_chk_guard_copy != STACK_CHK_GUARD)
+ {
+ puts ("STACK_CHK_GUARD changed between constructor and do_test");
+ return 1;
+ }
+
+ if (child)
+ {
+ int i;
+ pthread_t th[4];
+ void *ret;
+ for (i = 0; i < 4; ++i)
+ if (pthread_create (&th[i], NULL, tf, NULL))
+ {
+ puts ("thread creation failed");
+ return 1;
+ }
+ for (i = 0; i < 4; ++i)
+ if (pthread_join (th[i], &ret))
+ {
+ puts ("thread join failed");
+ return 1;
+ }
+ else if (ret != NULL)
+ return 1;
+
+ write (2, &stack_chk_guard_copy, sizeof (stack_chk_guard_copy));
+ return 0;
+ }
+
+ if (command == NULL)
+ {
+ puts ("missing --command or --child argument");
+ return 1;
+ }
+
+#define N 16
+ uintptr_t child_stack_chk_guards[N + 1];
+ child_stack_chk_guards[N] = stack_chk_guard_copy;
+ int i;
+ for (i = 0; i < N; ++i)
+ {
+ if (pipe (fds) < 0)
+ {
+ printf ("couldn't create pipe: %m\n");
+ return 1;
+ }
+
+ pid_t pid = fork ();
+ if (pid < 0)
+ {
+ printf ("fork failed: %m\n");
+ return 1;
+ }
+
+ if (!pid)
+ {
+ if (stack_chk_guard_copy != STACK_CHK_GUARD)
+ {
+ puts ("STACK_CHK_GUARD changed after fork");
+ exit (1);
+ }
+
+ close (fds[0]);
+ close (2);
+ dup2 (fds[1], 2);
+ close (fds[1]);
+
+ system (command);
+ exit (0);
+ }
+
+ close (fds[1]);
+
+ if (TEMP_FAILURE_RETRY (read (fds[0], &child_stack_chk_guards[i],
+ sizeof (uintptr_t))) != sizeof (uintptr_t))
+ {
+ puts ("could not read stack_chk_guard value from child");
+ return 1;
+ }
+
+ close (fds[0]);
+
+ pid_t termpid;
+ int status;
+ termpid = TEMP_FAILURE_RETRY (waitpid (pid, &status, 0));
+ if (termpid == -1)
+ {
+ printf ("waitpid failed: %m\n");
+ return 1;
+ }
+ else if (termpid != pid)
+ {
+ printf ("waitpid returned %ld != %ld\n",
+ (long int) termpid, (long int) pid);
+ return 1;
+ }
+ else if (!WIFEXITED (status) || WEXITSTATUS (status))
+ {
+ puts ("child hasn't exited with exit status 0");
+ return 1;
+ }
+ }
+
+ qsort (child_stack_chk_guards, N + 1, sizeof (uintptr_t), uintptr_t_cmp);
+
+ uintptr_t default_guard = 0;
+ unsigned char *p = (unsigned char *) &default_guard;
+ p[sizeof (uintptr_t) - 1] = 255;
+ p[sizeof (uintptr_t) - 2] = '\n';
+ p[0] = 0;
+
+ /* Test if the stack guard canaries are either randomized,
+ or equal to the default stack guard canary value.
+ Even with randomized stack guards it might happen
+ that the random number generator generates the same
+ values, but if that happens in more than half from
+ the 16 runs, something is very wrong. */
+ int ndifferences = 0;
+ int ndefaults = 0;
+ for (i = 0; i < N; ++i)
+ {
+ if (child_stack_chk_guards[i] != child_stack_chk_guards[i+1])
+ ndifferences++;
+ else if (child_stack_chk_guards[i] == default_guard)
+ ndefaults++;
+ }
+
+ printf ("differences %d defaults %d\n", ndifferences, ndefaults);
+
+ if (ndifferences < N / 2 && ndefaults < N / 2)
+ {
+ puts ("stack guard canaries are not randomized enough");
+ puts ("nor equal to the default canary value");
+ return 1;
+ }
+
+ return 0;
+}
+
+#define OPT_COMMAND 10000
+#define OPT_CHILD 10001
+#define CMDLINE_OPTIONS \
+ { "command", required_argument, NULL, OPT_COMMAND }, \
+ { "child", no_argument, NULL, OPT_CHILD },
+#define CMDLINE_PROCESS \
+ case OPT_COMMAND: \
+ command = optarg; \
+ break; \
+ case OPT_CHILD: \
+ child = true; \
+ break;
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
Index: linuxthreads/sysdeps/i386/tcb-offsets.sym
===================================================================
RCS file: /cvs/glibc/linuxthreads/linuxthreads/sysdeps/i386/tcb-offsets.sym,v
retrieving revision 1.1
diff -u -p -r1.1 tcb-offsets.sym
--- linuxthreads/sysdeps/i386/tcb-offsets.sym 28 Dec 2002 22:07:24 -0000 1.1
+++ linuxthreads/sysdeps/i386/tcb-offsets.sym 26 Apr 2006 14:58:01 -0000
@@ -5,3 +5,4 @@ MULTIPLE_THREADS_OFFSET offsetof (tcbhe
#ifdef NEED_DL_SYSINFO
SYSINFO_OFFSET offsetof (tcbhead_t, sysinfo)
#endif
+POINTER_GUARD offsetof (tcbhead_t, pointer_guard)
Index: linuxthreads/sysdeps/i386/tls.h
===================================================================
RCS file: /cvs/glibc/linuxthreads/linuxthreads/sysdeps/i386/tls.h,v
retrieving revision 1.38
diff -u -p -r1.38 tls.h
--- linuxthreads/sysdeps/i386/tls.h 9 Jan 2005 20:01:13 -0000 1.38
+++ linuxthreads/sysdeps/i386/tls.h 26 Apr 2006 14:58:01 -0000
@@ -47,9 +47,9 @@ typedef struct
dtv_t *dtv;
void *self; /* Pointer to the thread descriptor. */
int multiple_threads;
-#ifdef NEED_DL_SYSINFO
uintptr_t sysinfo;
-#endif
+ uintptr_t stack_guard;
+ uintptr_t pointer_guard;
} tcbhead_t;
#else /* __ASSEMBLER__ */
@@ -224,6 +224,23 @@ TLS_DO_MODIFY_LDT_KERNEL_CHECK(
({ struct _pthread_descr_struct *__descr; \
THREAD_GETMEM (__descr, p_header.data.dtvp); })
+
+/* Set the stack guard field in TCB head. */
+#define THREAD_SET_STACK_GUARD(value) \
+ THREAD_SETMEM (THREAD_SELF, p_header.data.stack_guard, value)
+#define THREAD_COPY_STACK_GUARD(descr) \
+ ((descr)->p_header.data.stack_guard \
+ = THREAD_GETMEM (THREAD_SELF, p_header.data.stack_guard))
+
+
+/* Set the pointer guard field in the TCB head. */
+#define THREAD_SET_POINTER_GUARD(value) \
+ THREAD_SETMEM (THREAD_SELF, p_header.data.pointer_guard, value)
+#define THREAD_COPY_POINTER_GUARD(descr) \
+ ((descr)->p_header.data.pointer_guard \
+ = THREAD_GETMEM (THREAD_SELF, p_header.data.pointer_guard))
+
+
# endif /* HAVE_TLS_SUPPORT && (FLOATING_STACKS || !IS_IN_libpthread) */
#endif /* __ASSEMBLER__ */
Index: linuxthreads/sysdeps/ia64/tcb-offsets.sym
===================================================================
RCS file: /cvs/glibc/linuxthreads/linuxthreads/sysdeps/ia64/tcb-offsets.sym,v
retrieving revision 1.6
diff -u -p -r1.6 tcb-offsets.sym
--- linuxthreads/sysdeps/ia64/tcb-offsets.sym 25 Apr 2003 22:04:27 -0000 1.6
+++ linuxthreads/sysdeps/ia64/tcb-offsets.sym 26 Apr 2006 14:58:01 -0000
@@ -3,7 +3,7 @@
--
#ifdef USE_TLS
-MULTIPLE_THREADS_OFFSET offsetof (struct _pthread_descr_struct, p_multiple_threads) - sizeof (struct _pthread_descr_struct)
+MULTIPLE_THREADS_OFFSET offsetof (struct _pthread_descr_struct, p_multiple_threads) - TCB_PRE_SIZE
#else
MULTIPLE_THREADS_OFFSET offsetof (tcbhead_t, multiple_threads)
#endif
Index: linuxthreads/sysdeps/ia64/tls.h
===================================================================
RCS file: /cvs/glibc/linuxthreads/linuxthreads/sysdeps/ia64/tls.h,v
retrieving revision 1.10
diff -u -p -r1.10 tls.h
--- linuxthreads/sysdeps/ia64/tls.h 9 Jan 2005 20:01:13 -0000 1.10
+++ linuxthreads/sysdeps/ia64/tls.h 26 Apr 2006 14:58:01 -0000
@@ -64,8 +64,16 @@ typedef struct
/* This is the size of the TCB. */
# define TLS_TCB_SIZE sizeof (tcbhead_t)
-/* This is the size we need before TCB. */
-# define TLS_PRE_TCB_SIZE sizeof (struct _pthread_descr_struct)
+/* This is the size we need before TCB.
+ If there is not any room for uintptr_t stack_guard and
+ uintptr_t pointer_guard in struct pthread's final padding,
+ we need to put struct pthread 16 byte slower. */
+# define TLS_PRE_TCB_SIZE \
+ (sizeof (struct pthread) \
+ + (PTHREAD_STRUCT_END_PADDING < 2 * sizeof (uintptr_t) \
+ ? ((2 * sizeof (uintptr_t) + __alignof__ (struct pthread) - 1) \
+ & ~(__alignof__ (struct pthread) - 1)) \
+ : 0))
/* Alignment requirements for the TCB. */
# define TLS_TCB_ALIGN __alignof__ (struct _pthread_descr_struct)
@@ -105,7 +113,8 @@ typedef struct
/* Return the thread descriptor for the current thread. */
# undef THREAD_SELF
-# define THREAD_SELF (__thread_self - 1)
+# define THREAD_SELF \
+ ((struct pthread *) ((char *) __thread_self - TLS_PRE_TCB_SIZE))
# undef INIT_THREAD_SELF
# define INIT_THREAD_SELF(descr, nr) \
@@ -113,6 +122,22 @@ typedef struct
# define TLS_MULTIPLE_THREADS_IN_TCB 1
+/* Set the stack guard field in TCB head. */
+#define THREAD_SET_STACK_GUARD(value) \
+ (((uintptr_t *) __thread_self)[-1] = (value))
+#define THREAD_COPY_STACK_GUARD(descr) \
+ (((uintptr_t *) ((char *) (descr) + TLS_PRE_TCB_SIZE))[-1] \
+ = ((uintptr_t *) __thread_self)[-1])
+
+/* Set the pointer guard field in TCB head. */
+#define THREAD_GET_POINTER_GUARD() \
+ (((uintptr_t *) __thread_self)[-2])
+#define THREAD_SET_POINTER_GUARD(value) \
+ (((uintptr_t *) __thread_self)[-2] = (value))
+#define THREAD_COPY_POINTER_GUARD(descr) \
+ (((uintptr_t *) ((char *) (descr) + TLS_PRE_TCB_SIZE))[-2] \
+ = THREAD_GET_POINTER_GUARD ())
+
/* Get the thread descriptor definition. */
# include <linuxthreads/descr.h>
Index: linuxthreads/sysdeps/powerpc/tcb-offsets.sym
===================================================================
RCS file: /cvs/glibc/linuxthreads/linuxthreads/sysdeps/powerpc/tcb-offsets.sym,v
retrieving revision 1.8
diff -u -p -r1.8 tcb-offsets.sym
--- linuxthreads/sysdeps/powerpc/tcb-offsets.sym 5 Mar 2005 19:27:55 -0000 1.8
+++ linuxthreads/sysdeps/powerpc/tcb-offsets.sym 26 Apr 2006 14:58:01 -0000
@@ -17,3 +17,4 @@
# endif
MULTIPLE_THREADS_OFFSET thread_offsetof (multiple_threads)
+POINTER_GUARD (offsetof (tcbhead_t, pointer_guard) - TLS_TCB_OFFSET - sizeof (tcbhead_t))
Index: linuxthreads/sysdeps/powerpc/tls.h
===================================================================
RCS file: /cvs/glibc/linuxthreads/linuxthreads/sysdeps/powerpc/tls.h,v
retrieving revision 1.9
diff -u -p -r1.9 tls.h
--- linuxthreads/sysdeps/powerpc/tls.h 9 Jan 2005 20:01:14 -0000 1.9
+++ linuxthreads/sysdeps/powerpc/tls.h 26 Apr 2006 14:58:01 -0000
@@ -48,11 +48,13 @@ typedef union dtv
# ifndef __ASSEMBLER__
-/* This layout is actually wholly private and not affected by the ABI.
- Nor does it overlap the pthread data structure, so we need nothing
- extra here at all. */
+/* The stack_guard is accessed directly by GCC -fstack-protector code,
+ so it is a part of public ABI. The dtv and pointer_guard fields
+ are private. */
typedef struct
-{
+{
+ uintptr_t pointer_guard;
+ uintptr_t stack_guard;
dtv_t *dtv;
} tcbhead_t;
@@ -131,6 +133,27 @@ typedef struct
See below. */
# define TLS_MULTIPLE_THREADS_IN_TCB 1
+/* Set the stack guard field in TCB head. */
+# define THREAD_SET_STACK_GUARD(value) \
+ (((tcbhead_t *) ((char *) __thread_register \
+ - TLS_TCB_OFFSET))[-1].stack_guard = (value))
+# define THREAD_COPY_STACK_GUARD(descr) \
+ (((tcbhead_t *) ((char *) (descr) \
+ + TLS_PRE_TCB_SIZE))[-1].stack_guard \
+ = ((tcbhead_t *) ((char *) __thread_register \
+ - TLS_TCB_OFFSET))[-1].stack_guard)
+
+/* Set the stack guard field in TCB head. */
+# define THREAD_GET_POINTER_GUARD() \
+ (((tcbhead_t *) ((char *) __thread_register \
+ - TLS_TCB_OFFSET))[-1].pointer_guard)
+# define THREAD_SET_POINTER_GUARD(value) \
+ (THREAD_GET_POINTER_GUARD () = (value))
+# define THREAD_COPY_POINTER_GUARD(descr) \
+ (((tcbhead_t *) ((char *) (descr) \
+ + TLS_PRE_TCB_SIZE))[-1].pointer_guard \
+ = THREAD_GET_POINTER_GUARD())
+
/* Get the thread descriptor definition. */
# include <linuxthreads/descr.h>
Index: linuxthreads/sysdeps/s390/tcb-offsets.sym
===================================================================
RCS file: /cvs/glibc/linuxthreads/linuxthreads/sysdeps/s390/tcb-offsets.sym,v
retrieving revision 1.1
diff -u -p -r1.1 tcb-offsets.sym
--- linuxthreads/sysdeps/s390/tcb-offsets.sym 5 Jan 2003 05:09:19 -0000 1.1
+++ linuxthreads/sysdeps/s390/tcb-offsets.sym 26 Apr 2006 14:58:01 -0000
@@ -2,3 +2,4 @@
#include <tls.h>
MULTIPLE_THREADS_OFFSET offsetof (tcbhead_t, multiple_threads)
+STACK_GUARD offsetof (tcbhead_t, stack_guard)
Index: linuxthreads/sysdeps/s390/tls.h
===================================================================
RCS file: /cvs/glibc/linuxthreads/linuxthreads/sysdeps/s390/tls.h,v
retrieving revision 1.4
diff -u -p -r1.4 tls.h
--- linuxthreads/sysdeps/s390/tls.h 9 Jan 2005 20:01:14 -0000 1.4
+++ linuxthreads/sysdeps/s390/tls.h 26 Apr 2006 14:58:01 -0000
@@ -44,6 +44,8 @@ typedef struct
dtv_t *dtv;
void *self; /* Pointer to the thread descriptor. */
int multiple_threads;
+ uintptr_t sysinfo;
+ uintptr_t stack_guard;
} tcbhead_t;
#else /* __ASSEMBLER__ */
@@ -122,6 +124,20 @@ typedef struct
# define THREAD_DTV() \
(((tcbhead_t *) __builtin_thread_pointer ())->dtv)
+/* Set the stack guard field in TCB head. */
+#define THREAD_SET_STACK_GUARD(value) \
+ THREAD_SETMEM (THREAD_SELF, header.stack_guard, value)
+#define THREAD_COPY_STACK_GUARD(descr) \
+ ((descr)->header.stack_guard \
+ = THREAD_GETMEM (THREAD_SELF, header.stack_guard))
+
+/* s390 doesn't have HP_TIMING_*, so for the time being
+ use stack_guard as pointer_guard. */
+#define THREAD_GET_POINTER_GUARD() \
+ THREAD_GETMEM (THREAD_SELF, header.stack_guard)
+#define THREAD_SET_POINTER_GUARD(value)
+#define THREAD_COPY_POINTER_GUARD(descr)
+
# endif /* __ASSEMBLER__ */
#else /* HAVE_TLS_SUPPORT && (FLOATING_STACKS || !IS_IN_libpthread) */
Index: linuxthreads/sysdeps/sh/tcb-offsets.sym
===================================================================
RCS file: /cvs/glibc/linuxthreads/linuxthreads/sysdeps/sh/tcb-offsets.sym,v
retrieving revision 1.4
diff -u -p -r1.4 tcb-offsets.sym
--- linuxthreads/sysdeps/sh/tcb-offsets.sym 25 Apr 2003 22:08:05 -0000 1.4
+++ linuxthreads/sysdeps/sh/tcb-offsets.sym 26 Apr 2006 14:58:01 -0000
@@ -8,3 +8,4 @@ TLS_PRE_TCB_SIZE sizeof (struct _pthread
#else
MULTIPLE_THREADS_OFFSET offsetof (tcbhead_t, multiple_threads)
#endif
+POINTER_GUARD offsetof (tcbhead_t, pointer_guard)
Index: linuxthreads/sysdeps/sh/tls.h
===================================================================
RCS file: /cvs/glibc/linuxthreads/linuxthreads/sysdeps/sh/tls.h,v
retrieving revision 1.11
diff -u -p -r1.11 tls.h
--- linuxthreads/sysdeps/sh/tls.h 12 Nov 2005 00:49:59 -0000 1.11
+++ linuxthreads/sysdeps/sh/tls.h 26 Apr 2006 14:58:01 -0000
@@ -63,7 +63,7 @@ typedef union dtv
typedef struct
{
dtv_t *dtv;
- void *private;
+ uintptr_t pointer_guard;
} tcbhead_t;
/* This is the size of the initial TCB. */
@@ -126,6 +126,19 @@ typedef struct
# define TLS_MULTIPLE_THREADS_IN_TCB 1
+#define THREAD_GET_POINTER_GUARD() \
+ ({ tcbhead_t *__tcbp; \
+ __asm __volatile ("stc gbr,%0" : "=r" (__tcbp)); \
+ __tcbp->pointer_guard;})
+ #define THREAD_SET_POINTER_GUARD(value) \
+ ({ tcbhead_t *__tcbp; \
+ __asm __volatile ("stc gbr,%0" : "=r" (__tcbp)); \
+ __tcbp->pointer_guard = (value);})
+#define THREAD_COPY_POINTER_GUARD(descr) \
+ ({ tcbhead_t *__tcbp; \
+ __asm __volatile ("stc gbr,%0" : "=r" (__tcbp)); \
+ ((tcbhead_t *) (descr + 1))->pointer_guard = __tcbp->pointer_guard;})
+
/* Get the thread descriptor definition. This must be after the
the definition of THREAD_SELF for TLS. */
# include <linuxthreads/descr.h>
Index: linuxthreads/sysdeps/sparc/tcb-offsets.sym
===================================================================
RCS file: /cvs/glibc/linuxthreads/linuxthreads/sysdeps/sparc/tcb-offsets.sym,v
retrieving revision 1.1
diff -u -p -r1.1 tcb-offsets.sym
--- linuxthreads/sysdeps/sparc/tcb-offsets.sym 28 Dec 2002 22:12:30 -0000 1.1
+++ linuxthreads/sysdeps/sparc/tcb-offsets.sym 26 Apr 2006 14:58:01 -0000
@@ -2,3 +2,4 @@
#include <tls.h>
MULTIPLE_THREADS_OFFSET offsetof (tcbhead_t, multiple_threads)
+POINTER_GUARD offsetof (tcbhead_t, pointer_guard)
Index: linuxthreads/sysdeps/sparc/tls.h
===================================================================
RCS file: /cvs/glibc/linuxthreads/linuxthreads/sysdeps/sparc/tls.h,v
retrieving revision 1.4
diff -u -p -r1.4 tls.h
--- linuxthreads/sysdeps/sparc/tls.h 9 Jan 2005 20:01:15 -0000 1.4
+++ linuxthreads/sysdeps/sparc/tls.h 26 Apr 2006 14:58:01 -0000
@@ -44,6 +44,9 @@ typedef struct
dtv_t *dtv;
void *self; /* Pointer to the thread descriptor. */
int multiple_threads;
+ uintptr_t sysinfo;
+ uintptr_t stack_guard;
+ uintptr_t pointer_guard;
} tcbhead_t;
#else /* __ASSEMBLER__ */
@@ -99,6 +102,21 @@ typedef struct
# define THREAD_DTV() \
(((tcbhead_t *) __thread_self)->dtv)
+/* Set the stack guard field in TCB head. */
+#define THREAD_SET_STACK_GUARD(value) \
+ THREAD_SETMEM (THREAD_SELF, p_header.data.stack_guard, value)
+# define THREAD_COPY_STACK_GUARD(descr) \
+ ((descr)->p_header.data.stack_guard \
+ = THREAD_GETMEM (THREAD_SELF, p_header.data.stack_guard))
+
+/* Get/set the stack guard field in TCB head. */
+#define THREAD_GET_POINTER_GUARD() \
+ THREAD_GETMEM (THREAD_SELF, p_header.data.pointer_guard)
+#define THREAD_SET_POINTER_GUARD(value) \
+ THREAD_SETMEM (THREAD_SELF, p_header.data.pointer_guard, value)
+# define THREAD_COPY_POINTER_GUARD(descr) \
+ ((descr)->p_header.data.pointer_guard = THREAD_GET_POINTER_GUARD ())
+
# endif
#else
Index: linuxthreads/sysdeps/x86_64/tcb-offsets.sym
===================================================================
RCS file: /cvs/glibc/linuxthreads/linuxthreads/sysdeps/x86_64/tcb-offsets.sym,v
retrieving revision 1.1
diff -u -p -r1.1 tcb-offsets.sym
--- linuxthreads/sysdeps/x86_64/tcb-offsets.sym 17 Jun 2003 22:23:41 -0000 1.1
+++ linuxthreads/sysdeps/x86_64/tcb-offsets.sym 26 Apr 2006 14:58:01 -0000
@@ -2,3 +2,4 @@
#include <tls.h>
MULTIPLE_THREADS_OFFSET offsetof (tcbhead_t, multiple_threads)
+POINTER_GUARD offsetof (tcbhead_t, pointer_guard)
Index: linuxthreads/sysdeps/x86_64/tls.h
===================================================================
RCS file: /cvs/glibc/linuxthreads/linuxthreads/sysdeps/x86_64/tls.h,v
retrieving revision 1.7
diff -u -p -r1.7 tls.h
--- linuxthreads/sysdeps/x86_64/tls.h 9 Jan 2005 20:01:15 -0000 1.7
+++ linuxthreads/sysdeps/x86_64/tls.h 26 Apr 2006 14:58:01 -0000
@@ -25,6 +25,7 @@
# include <pt-machine.h>
# include <stdbool.h>
# include <stddef.h>
+# include <stdint.h>
/* Type for the dtv. */
typedef union dtv
@@ -45,6 +46,9 @@ typedef struct
dtv_t *dtv;
void *self; /* Pointer to the thread descriptor. */
int multiple_threads;
+ uintptr_t sysinfo;
+ uintptr_t stack_guard;
+ uintptr_t pointer_guard;
} tcbhead_t;
#else /* __ASSEMBLER__ */
@@ -128,6 +132,21 @@ typedef struct
({ struct _pthread_descr_struct *__descr; \
THREAD_GETMEM (__descr, p_header.data.dtvp); })
+/* Set the stack guard field in TCB head. */
+# define THREAD_SET_STACK_GUARD(value) \
+ THREAD_SETMEM (THREAD_SELF, p_header.data.stack_guard, value)
+# define THREAD_COPY_STACK_GUARD(descr) \
+ ((descr)->p_header.data.stack_guard \
+ = THREAD_GETMEM (THREAD_SELF, p_header.data.stack_guard))
+
+
+/* Set the pointer guard field in the TCB head. */
+#define THREAD_SET_POINTER_GUARD(value) \
+ THREAD_SETMEM (THREAD_SELF, p_header.data.pointer_guard, value)
+#define THREAD_COPY_POINTER_GUARD(descr) \
+ ((descr)->p_header.data.pointer_guard \
+ = THREAD_GETMEM (THREAD_SELF, p_header.data.pointer_guard))
+
# endif /* HAVE_TLS_SUPPORT */
#endif /* __ASSEMBLER__ */