* 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:
Ulrich Drepper 2007-01-17 08:37:26 +00:00
parent d78bce1c01
commit ea1533e08d
10 changed files with 94 additions and 49 deletions

View File

@ -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;

View File

@ -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

View File

@ -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) \

View File

@ -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)

View File

@ -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 */

View File

@ -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); \

View File

@ -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);
}

View File

@ -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

View File

@ -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
}

View File

@ -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