Skip to content

Commit

Permalink
* sysdeps/unix/sysv/linux/libc_pthread_init.c: Don't just copy the
Browse files Browse the repository at this point in the history
	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.
Ulrich Drepper committed Jan 17, 2007
1 parent d78bce1 commit ea1533e
Showing 10 changed files with 93 additions and 48 deletions.
7 changes: 4 additions & 3 deletions csu/libc-start.c
Original file line number Diff line number Diff line change
@@ -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;
13 changes: 13 additions & 0 deletions nptl/ChangeLog
Original file line number Diff line number Diff line change
@@ -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
7 changes: 4 additions & 3 deletions nptl/forward.c
Original file line number Diff line number Diff line change
@@ -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) \
26 changes: 16 additions & 10 deletions nptl/sysdeps/pthread/bits/libc-lock.h
Original file line number Diff line number Diff line change
@@ -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,15 +400,15 @@ 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); \
}

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

10 changes: 9 additions & 1 deletion nptl/sysdeps/pthread/pthread-functions.h
Original file line number Diff line number Diff line change
@@ -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 */
7 changes: 3 additions & 4 deletions nptl/sysdeps/pthread/setxid.h
Original file line number Diff line number Diff line change
@@ -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); \
12 changes: 6 additions & 6 deletions nptl/sysdeps/unix/sysv/linux/jmp-unwind.c
Original file line number Diff line number Diff line change
@@ -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);
}
35 changes: 27 additions & 8 deletions nptl/sysdeps/unix/sysv/linux/libc_pthread_init.c
Original file line number Diff line number Diff line change
@@ -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
15 changes: 7 additions & 8 deletions nptl/sysdeps/unix/sysv/linux/s390/jmp-unwind.c
Original file line number Diff line number Diff line change
@@ -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)
{
unsigned char local_var;

#ifdef SHARED
# define fptr __libc_pthread_functions.ptr___pthread_cleanup_upto
if (__libc_pthread_functions_init)
PTHFCT_CALL (ptr___pthread_cleanup_upto, (env->__jmpbuf, &local_var));
#else
# define fptr __pthread_cleanup_upto
if (__pthread_cleanup_upto != NULL)
__pthread_cleanup_upto (env->__jmpbuf, &local_var);
#endif

unsigned char local_var;

if (fptr != NULL)
fptr (env->__jmpbuf, &local_var);
}
9 changes: 4 additions & 5 deletions sysdeps/unix/sysv/linux/fatal-prepare.h
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit ea1533e

Please sign in to comment.