* sysdeps/unix/sysv/linux/libc_pthread_init.c: Don't just copy the
function table, mangle the pointers. * sysdeps/pthread/pthread-functions.h: Define PTHFCT_CALL. * forward.c: Use PTHFCT_CALL and __libc_pthread_functions_init. * sysdeps/pthread/bits/libc-lock.h: When using __libc_pthread_functions demangle pointers before use. * sysdeps/unix/sysv/linux/s390/jmp-unwind.c: Use PTHFCT_CALL to demangle pointer. * sysdeps/unix/sysv/linux/jmp-unwind.c: Likewise. * sysdeps/pthread/setxid.h: Likewise.
This commit is contained in:
parent
d78bce1c01
commit
ea1533e08d
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 1998-2003, 2004, 2005, 2006 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1998-2006, 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
|
||||
@ -225,7 +225,7 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL),
|
||||
{
|
||||
/* Remove the thread-local data. */
|
||||
# ifdef SHARED
|
||||
__libc_pthread_functions.ptr__nptl_deallocate_tsd ();
|
||||
PTHFCT_CALL (ptr__nptl_deallocate_tsd, ());
|
||||
# else
|
||||
extern void __nptl_deallocate_tsd (void) __attribute ((weak));
|
||||
__nptl_deallocate_tsd ();
|
||||
@ -235,7 +235,8 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL),
|
||||
terminate the entire process. */
|
||||
result = 0;
|
||||
# ifdef SHARED
|
||||
unsigned int *const ptr = __libc_pthread_functions.ptr_nthreads;
|
||||
unsigned int *ptr = __libc_pthread_functions.ptr_nthreads;
|
||||
PTR_DEMANGLE (ptr);
|
||||
# else
|
||||
extern unsigned int __nptl_nthreads __attribute ((weak));
|
||||
unsigned int *const ptr = &__nptl_nthreads;
|
||||
|
@ -1,3 +1,16 @@
|
||||
2007-01-17 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* sysdeps/unix/sysv/linux/libc_pthread_init.c: Don't just copy the
|
||||
function table, mangle the pointers.
|
||||
* sysdeps/pthread/pthread-functions.h: Define PTHFCT_CALL.
|
||||
* forward.c: Use PTHFCT_CALL and __libc_pthread_functions_init.
|
||||
* sysdeps/pthread/bits/libc-lock.h: When using __libc_pthread_functions
|
||||
demangle pointers before use.
|
||||
* sysdeps/unix/sysv/linux/s390/jmp-unwind.c: Use PTHFCT_CALL to
|
||||
demangle pointer.
|
||||
* sysdeps/unix/sysv/linux/jmp-unwind.c: Likewise.
|
||||
* sysdeps/pthread/setxid.h: Likewise.
|
||||
|
||||
2007-01-12 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* tst-rwlock7.c: Show some more information in case of correct
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 2002, 2003, 2004, 2007 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
|
||||
|
||||
@ -29,16 +29,17 @@
|
||||
|
||||
/* Pointers to the libc functions. */
|
||||
struct pthread_functions __libc_pthread_functions attribute_hidden;
|
||||
int __libc_pthread_functions_init attribute_hidden;
|
||||
|
||||
|
||||
#define FORWARD2(name, rettype, decl, params, defaction) \
|
||||
rettype \
|
||||
name decl \
|
||||
{ \
|
||||
if (__libc_pthread_functions.ptr_##name == NULL) \
|
||||
if (!__libc_pthread_functions_init) \
|
||||
defaction; \
|
||||
\
|
||||
return __libc_pthread_functions.ptr_##name params; \
|
||||
return PTHFCT_CALL (ptr_##name, params); \
|
||||
}
|
||||
|
||||
#define FORWARD(name, decl, params, defretval) \
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* libc-internal interface for mutex locks. NPTL version.
|
||||
Copyright (C) 1996-2001, 2002, 2003, 2005 Free Software Foundation, Inc.
|
||||
Copyright (C) 1996-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
|
||||
@ -150,13 +150,17 @@ typedef pthread_key_t __libc_key_t;
|
||||
|
||||
/* Call thread functions through the function pointer table. */
|
||||
#if defined SHARED && !defined NOT_IN_libc
|
||||
# define PTF(NAME) __libc_pthread_functions.ptr_##NAME
|
||||
# define PTFAVAIL(NAME) __libc_pthread_functions_init
|
||||
# define __libc_ptf_call(FUNC, ARGS, ELSE) \
|
||||
(PTF(FUNC) != NULL ? PTF(FUNC) ARGS : ELSE)
|
||||
(__libc_pthread_functions_init ? PTHFCT_CALL (ptr_##FUNC, ARGS) : ELSE)
|
||||
# define __libc_ptf_call_always(FUNC, ARGS) \
|
||||
PTHFCT_CALL (ptr_##FUNC, ARGS)
|
||||
#else
|
||||
# define PTF(NAME) NAME
|
||||
# define PTFAVAIL(NAME) (NAME != NULL)
|
||||
# define __libc_ptf_call(FUNC, ARGS, ELSE) \
|
||||
__libc_maybe_call (FUNC, ARGS, ELSE)
|
||||
# define __libc_ptf_call_always(FUNC, ARGS) \
|
||||
FUNC ARGS
|
||||
#endif
|
||||
|
||||
|
||||
@ -353,8 +357,9 @@ typedef pthread_key_t __libc_key_t;
|
||||
/* Call handler iff the first call. */
|
||||
#define __libc_once(ONCE_CONTROL, INIT_FUNCTION) \
|
||||
do { \
|
||||
if (PTF(__pthread_once) != NULL) \
|
||||
PTF(__pthread_once) (&(ONCE_CONTROL), INIT_FUNCTION); \
|
||||
if (PTFAVAIL (__pthread_once)) \
|
||||
__libc_ptf_call_always (__pthread_once, (&(ONCE_CONTROL), \
|
||||
INIT_FUNCTION)); \
|
||||
else if ((ONCE_CONTROL) == PTHREAD_ONCE_INIT) { \
|
||||
INIT_FUNCTION (); \
|
||||
(ONCE_CONTROL) |= 2; \
|
||||
@ -380,9 +385,10 @@ extern void _pthread_cleanup_pop_restore (struct _pthread_cleanup_buffer *buffer
|
||||
{ struct _pthread_cleanup_buffer _buffer; \
|
||||
int _avail; \
|
||||
if (DOIT) { \
|
||||
_avail = PTF(_pthread_cleanup_push_defer) != NULL; \
|
||||
_avail = PTFAVAIL (_pthread_cleanup_push_defer); \
|
||||
if (_avail) { \
|
||||
PTF(_pthread_cleanup_push_defer) (&_buffer, FCT, ARG); \
|
||||
__libc_ptf_call_always (_pthread_cleanup_push_defer, (&_buffer, FCT, \
|
||||
ARG)); \
|
||||
} else { \
|
||||
_buffer.__routine = (FCT); \
|
||||
_buffer.__arg = (ARG); \
|
||||
@ -394,7 +400,7 @@ extern void _pthread_cleanup_pop_restore (struct _pthread_cleanup_buffer *buffer
|
||||
/* End critical region with cleanup. */
|
||||
#define __libc_cleanup_region_end(DOIT) \
|
||||
if (_avail) { \
|
||||
PTF(_pthread_cleanup_pop_restore) (&_buffer, DOIT); \
|
||||
__libc_ptf_call_always (_pthread_cleanup_pop_restore, (&_buffer, DOIT));\
|
||||
} else if (DOIT) \
|
||||
_buffer.__routine (_buffer.__arg); \
|
||||
}
|
||||
@ -402,7 +408,7 @@ extern void _pthread_cleanup_pop_restore (struct _pthread_cleanup_buffer *buffer
|
||||
/* Sometimes we have to exit the block in the middle. */
|
||||
#define __libc_cleanup_end(DOIT) \
|
||||
if (_avail) { \
|
||||
PTF(_pthread_cleanup_pop_restore) (&_buffer, DOIT); \
|
||||
__libc_ptf_call_always (_pthread_cleanup_pop_restore, (&_buffer, DOIT));\
|
||||
} else if (DOIT) \
|
||||
_buffer.__routine (_buffer.__arg)
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
|
||||
|
||||
@ -23,6 +23,7 @@
|
||||
#include <pthread.h>
|
||||
#include <setjmp.h>
|
||||
#include <internaltypes.h>
|
||||
#include <sysdep.h>
|
||||
|
||||
struct xid_command;
|
||||
|
||||
@ -100,5 +101,12 @@ struct pthread_functions
|
||||
|
||||
/* Variable in libc.so. */
|
||||
extern struct pthread_functions __libc_pthread_functions attribute_hidden;
|
||||
extern int __libc_pthread_functions_init attribute_hidden;
|
||||
|
||||
#define PTHFCT_CALL(fct, params) \
|
||||
({ __typeof (__libc_pthread_functions.fct) __p; \
|
||||
__p = __libc_pthread_functions.fct; \
|
||||
PTR_DEMANGLE (__p); \
|
||||
__p params; })
|
||||
|
||||
#endif /* pthread-functions.h */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 2004, 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
|
||||
@ -33,13 +33,12 @@
|
||||
# define INLINE_SETXID_SYSCALL(name, nr, args...) \
|
||||
({ \
|
||||
int __result; \
|
||||
if (__builtin_expect (__libc_pthread_functions.ptr__nptl_setxid \
|
||||
!= NULL, 0)) \
|
||||
if (__builtin_expect (__libc_pthread_functions_init, 0)) \
|
||||
{ \
|
||||
struct xid_command __cmd; \
|
||||
__cmd.syscall_no = __NR_##name; \
|
||||
__SETXID_##nr (__cmd, args); \
|
||||
__result = __libc_pthread_functions.ptr__nptl_setxid (&__cmd); \
|
||||
__result = PTHFCT_CALL (ptr__nptl_setxid, (&__cmd)); \
|
||||
} \
|
||||
else \
|
||||
__result = INLINE_SYSCALL (name, nr, args); \
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Clean up stack frames unwound by longjmp. Linux version.
|
||||
Copyright (C) 1995, 1997, 2002, 2003 Free Software Foundation, Inc.
|
||||
Copyright (C) 1995, 1997, 2002, 2003, 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
|
||||
@ -29,11 +29,11 @@ void
|
||||
_longjmp_unwind (jmp_buf env, int val)
|
||||
{
|
||||
#ifdef SHARED
|
||||
# define fptr __libc_pthread_functions.ptr___pthread_cleanup_upto
|
||||
if (__libc_pthread_functions_init)
|
||||
PTHFCT_CALL (ptr___pthread_cleanup_upto, (env->__jmpbuf,
|
||||
CURRENT_STACK_FRAME));
|
||||
#else
|
||||
# define fptr __pthread_cleanup_upto
|
||||
if (__pthread_cleanup_upto != NULL)
|
||||
__pthread_cleanup_upto (env->__jmpbuf, CURRENT_STACK_FRAME);
|
||||
#endif
|
||||
|
||||
if (fptr != NULL)
|
||||
fptr (env->__jmpbuf, CURRENT_STACK_FRAME);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2002, 2003, 2005, 2006 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 2002, 2003, 2005, 2006, 2007 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
|
||||
|
||||
@ -25,6 +25,7 @@
|
||||
#include <string.h>
|
||||
#include <pthreadP.h>
|
||||
#include <bits/libc-lock.h>
|
||||
#include <sysdep.h>
|
||||
|
||||
|
||||
#ifdef TLS_MULTIPLE_THREADS_IN_TCB
|
||||
@ -46,11 +47,29 @@ __libc_pthread_init (ptr, reclaim, functions)
|
||||
__register_atfork (NULL, NULL, reclaim, NULL);
|
||||
|
||||
#ifdef SHARED
|
||||
/* We copy the content of the variable pointed to by the FUNCTIONS
|
||||
parameter to one in libc.so since this means access to the array
|
||||
can be done with one memory access instead of two. */
|
||||
memcpy (&__libc_pthread_functions, functions,
|
||||
sizeof (__libc_pthread_functions));
|
||||
/* Copy the function pointers into an array in libc. This enables
|
||||
access with just one memory reference but moreso, it prevents
|
||||
hijacking the function pointers with just one pointer change. We
|
||||
"encrypt" the function pointers since we cannot write-protect the
|
||||
array easily enough. */
|
||||
union ptrhack
|
||||
{
|
||||
struct pthread_functions pf;
|
||||
void *parr[1];
|
||||
} const *src;
|
||||
union ptrhack *dest;
|
||||
# define NPTRS (sizeof (struct pthread_functions) / sizeof (void *))
|
||||
|
||||
src = (const void *) functions;
|
||||
dest = (void *) &__libc_pthread_functions;
|
||||
|
||||
for (size_t cnt = 0; cnt < NPTRS; ++cnt)
|
||||
{
|
||||
void *p = src->parr[cnt];
|
||||
PTR_MANGLE (p);
|
||||
dest->parr[cnt] = p;
|
||||
}
|
||||
__libc_pthread_functions_init = 1;
|
||||
#endif
|
||||
|
||||
#ifndef TLS_MULTIPLE_THREADS_IN_TCB
|
||||
@ -61,7 +80,7 @@ __libc_pthread_init (ptr, reclaim, functions)
|
||||
#ifdef SHARED
|
||||
libc_freeres_fn (freeres_libptread)
|
||||
{
|
||||
if (__libc_pthread_functions.ptr_freeres != NULL)
|
||||
__libc_pthread_functions.ptr_freeres ();
|
||||
if (__libc_pthread_functions_init)
|
||||
PTHFCT_CALL (ptr_freeres, ());
|
||||
}
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Clean up stack frames unwound by longjmp. Linux/s390 version.
|
||||
Copyright (C) 2003, 2004 Free Software Foundation, Inc.
|
||||
Copyright (C) 2003, 2004, 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
|
||||
@ -28,14 +28,13 @@ extern void __pthread_cleanup_upto (__jmp_buf env, char *targetframe);
|
||||
void
|
||||
_longjmp_unwind (jmp_buf env, int val)
|
||||
{
|
||||
#ifdef SHARED
|
||||
# define fptr __libc_pthread_functions.ptr___pthread_cleanup_upto
|
||||
#else
|
||||
# define fptr __pthread_cleanup_upto
|
||||
#endif
|
||||
|
||||
unsigned char local_var;
|
||||
|
||||
if (fptr != NULL)
|
||||
fptr (env->__jmpbuf, &local_var);
|
||||
#ifdef SHARED
|
||||
if (__libc_pthread_functions_init)
|
||||
PTHFCT_CALL (ptr___pthread_cleanup_upto, (env->__jmpbuf, &local_var));
|
||||
#else
|
||||
if (__pthread_cleanup_upto != NULL)
|
||||
__pthread_cleanup_upto (env->__jmpbuf, &local_var);
|
||||
#endif
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2003 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 2003, 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
|
||||
@ -24,10 +24,9 @@
|
||||
# include <pthread-functions.h>
|
||||
# define FATAL_PREPARE \
|
||||
{ \
|
||||
int (*fp) (int, int *); \
|
||||
fp = __libc_pthread_functions.ptr_pthread_setcancelstate; \
|
||||
if (fp != NULL) \
|
||||
fp (PTHREAD_CANCEL_DISABLE, NULL); \
|
||||
if (__libc_pthread_functions_init) \
|
||||
PTHFCT_CALL (ptr_pthread_setcancelstate, (PTHREAD_CANCEL_DISABLE, \
|
||||
NULL)); \
|
||||
}
|
||||
#else
|
||||
# pragma weak pthread_setcancelstate
|
||||
|
Loading…
Reference in New Issue
Block a user