diff options
Diffstat (limited to 'nptl/sysdeps/powerpc')
-rw-r--r-- | nptl/sysdeps/powerpc/jmpbuf-unwind.h | 31 | ||||
-rw-r--r-- | nptl/sysdeps/powerpc/tcb-offsets.sym | 4 | ||||
-rw-r--r-- | nptl/sysdeps/powerpc/tls.h | 67 |
3 files changed, 62 insertions, 40 deletions
diff --git a/nptl/sysdeps/powerpc/jmpbuf-unwind.h b/nptl/sysdeps/powerpc/jmpbuf-unwind.h deleted file mode 100644 index 0b817160d3..0000000000 --- a/nptl/sysdeps/powerpc/jmpbuf-unwind.h +++ /dev/null @@ -1,31 +0,0 @@ -/* Copyright (C) 2003, 2004 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Jakub Jelinek <jakub@redhat.com>, 2003. - - 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 <setjmp.h> -#include <stdint.h> -#include <unwind.h> - -#define _JMPBUF_CFA_UNWINDS_ADJ(_jmpbuf, _context, _adj) \ - _JMPBUF_UNWINDS_ADJ (_jmpbuf, (void *) _Unwind_GetCFA (_context), _adj) - -#define _JMPBUF_UNWINDS_ADJ(_jmpbuf, _address, _adj) \ - ((uintptr_t) (_address) - (_adj) < (uintptr_t) (_jmpbuf)[JB_GPR1] - (_adj)) - -/* We use the normal lobngjmp for unwinding. */ -#define __libc_unwind_longjmp(buf, val) __libc_longjmp (buf, val) diff --git a/nptl/sysdeps/powerpc/tcb-offsets.sym b/nptl/sysdeps/powerpc/tcb-offsets.sym index a9701fb5b7..4a8671e802 100644 --- a/nptl/sysdeps/powerpc/tcb-offsets.sym +++ b/nptl/sysdeps/powerpc/tcb-offsets.sym @@ -6,10 +6,12 @@ -- Abuse tls.h macros to derive offsets relative to the thread register. # undef __thread_register # define __thread_register ((void *) 0) -# define thread_offsetof(mem) ((void *) &THREAD_SELF->mem - (void *) 0) +# define thread_offsetof(mem) ((ptrdiff_t) THREAD_SELF + offsetof (struct pthread, mem)) + #if TLS_MULTIPLE_THREADS_IN_TCB MULTIPLE_THREADS_OFFSET thread_offsetof (header.multiple_threads) #endif PID thread_offsetof (pid) TID thread_offsetof (tid) +POINTER_GUARD (offsetof (tcbhead_t, pointer_guard) - TLS_TCB_OFFSET - sizeof (tcbhead_t)) diff --git a/nptl/sysdeps/powerpc/tls.h b/nptl/sysdeps/powerpc/tls.h index ce7f5bd53d..ad5698c6f8 100644 --- a/nptl/sysdeps/powerpc/tls.h +++ b/nptl/sysdeps/powerpc/tls.h @@ -1,5 +1,5 @@ /* Definition for thread-local data handling. NPTL/PowerPC version. - Copyright (C) 2003 Free Software Foundation, Inc. + Copyright (C) 2003, 2005, 2007 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 @@ -23,6 +23,7 @@ # include <dl-sysdep.h> #ifndef __ASSEMBLER__ +# include <stdbool.h> # include <stddef.h> # include <stdint.h> @@ -30,7 +31,11 @@ typedef union dtv { size_t counter; - void *pointer; + struct + { + void *val; + bool is_static; + } pointer; } dtv_t; #else /* __ASSEMBLER__ */ @@ -60,11 +65,13 @@ typedef union dtv /* Get the thread descriptor definition. */ # include <nptl/descr.h> -/* 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; @@ -122,7 +129,7 @@ register void *__thread_register __asm__ ("r13"); /* Return the address of the dtv for the current thread. */ # define THREAD_DTV() \ - (((tcbhead_t *) (__thread_register - TLS_TCB_OFFSET))[-1].dtv) + (((tcbhead_t *) (__thread_register - TLS_TCB_OFFSET))[-1].dtv) /* Return the thread descriptor for the current thread. */ # define THREAD_SELF \ @@ -131,9 +138,9 @@ register void *__thread_register __asm__ ("r13"); /* Magic for libthread_db to know how to do THREAD_SELF. */ # define DB_THREAD_SELF \ - REGISTER (32, 32, PT_THREAD_POINTER * 4, \ + REGISTER (32, 32, PT_THREAD_POINTER * 4, \ - TLS_TCB_OFFSET - TLS_PRE_TCB_SIZE) \ - REGISTER (64, 64, PT_THREAD_POINTER * 8, \ + REGISTER (64, 64, PT_THREAD_POINTER * 8, \ - TLS_TCB_OFFSET - TLS_PRE_TCB_SIZE) /* Read member of the thread descriptor directly. */ @@ -151,10 +158,54 @@ register void *__thread_register __asm__ ("r13"); # define THREAD_SETMEM_NC(descr, member, idx, value) \ ((void)(descr), (THREAD_SELF)->member[idx] = (value)) +/* 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()) + /* l_tls_offset == 0 is perfectly valid on PPC, so we have to use some different value to mean unset l_tls_offset. */ # define NO_TLS_OFFSET -1 +/* Get and set the global scope generation counter in struct pthread. */ +#define THREAD_GSCOPE_FLAG_UNUSED 0 +#define THREAD_GSCOPE_FLAG_USED 1 +#define THREAD_GSCOPE_FLAG_WAIT 2 +#define THREAD_GSCOPE_RESET_FLAG() \ + do \ + { int __res \ + = atomic_exchange_rel (&THREAD_SELF->header.gscope_flag, \ + THREAD_GSCOPE_FLAG_UNUSED); \ + if (__res == THREAD_GSCOPE_FLAG_WAIT) \ + lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1); \ + } \ + while (0) +#define THREAD_GSCOPE_SET_FLAG() \ + do \ + { \ + THREAD_SELF->header.gscope_flag = THREAD_GSCOPE_FLAG_USED; \ + atomic_write_barrier (); \ + } \ + while (0) +#define THREAD_GSCOPE_WAIT() \ + GL(dl_wait_lookup_done) () + #endif /* __ASSEMBLER__ */ #endif /* tls.h */ |