This is the mail archive of the libc-hacker@sources.redhat.com mailing list for the glibc project.

Note that libc-hacker is a closed list. You may look at the archives of this list, but subscription and posting are not open.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] __rtld_*lock_recursive changes


Hi!

ATM ld.so and libc.so have weak undef references to __pthread_mutex_{,un}lock
and use it for GL(dl_load_lock) locking.
This is bad, in case libpthread is dlopened later.
Until libpthread is loaded, ld.so can use simple ++count/--count,
when libpthread is loaded, it can just take this count and lock the
recursive lock that many times so that lock recursion is preserved.
The following patch also kills one unneeded GOT relocation.

2003-08-07  Jakub Jelinek  <jakub@redhat.com>

	* sysdeps/generic/ldsodefs.h (_rtld_global): Add
	_dl_rtld_lock_recursive and _dl_rtld_unlock_recursive.
	* elf/rtld.c (rtld_lock_default_lock_recursive,
	rtld_lock_default_unlock_recursive): New functions.
	(dl_main): Initialize _dl_rtld_lock_recursive and
	_dl_rtld_unlock_recursive.
nptl/
	* sysdeps/pthread/bits/libc-lock.h [_LIBC && SHARED]
	(__rtld_lock_default_lock_recursive,
	__rtld_lock_default_unlock_recursive): Define.
	[_LIBC && SHARED] (__rtld_lock_lock_recursive,
	__rtld_lock_unlock_recursive): Define using
	GL(_dl_rtld_*lock_recursive).
	* init.c (__pthread_initialize_minimal_internal): Initialize
	_dl_rtld_lock_recursive and _dl_rtld_unlock_recursive.
	Lock GL(_dl_load_lock) the same number of times as
	GL(_dl_load_lock) using non-mt implementation was nested.

	* pthreadP.h (__pthread_cleanup_upto): Add hidden_proto.
	* pt-longjmp.c (__pthread_cleanup_upto): Add hidden_def.
linuxthreads/
	* sysdeps/pthread/bits/libc-lock.h [_LIBC && SHARED]
	(__rtld_lock_default_lock_recursive,
	__rtld_lock_default_unlock_recursive): Define.
	[_LIBC && SHARED] (__rtld_lock_lock_recursive,
	__rtld_lock_unlock_recursive): Define using
	GL(_dl_rtld_*lock_recursive).
	* pthread.c (pthread_initialize): Initialize _dl_rtld_lock_recursive
	and _dl_rtld_unlock_recursive.  Lock GL(_dl_load_lock) the same
	number of times as GL(_dl_load_lock) using non-mt implementation was
	nested.

--- libc/nptl/sysdeps/pthread/bits/libc-lock.h.jj	2003-07-08 09:54:09.000000000 -0400
+++ libc/nptl/sysdeps/pthread/bits/libc-lock.h	2003-08-07 06:43:04.000000000 -0400
@@ -248,9 +248,6 @@ typedef pthread_key_t __libc_key_t;
   __libc_maybe_call (__pthread_mutex_lock, (&(NAME).mutex), 0)
 #endif
 
-#define __rtld_lock_lock_recursive(NAME) \
-  __libc_maybe_call (__pthread_mutex_lock, (&(NAME).mutex), 0)
-
 /* Try to lock the named lock variable.  */
 #if defined _LIBC && (!defined NOT_IN_libc || defined IS_IN_libpthread)
 # define __libc_lock_trylock(NAME) \
@@ -319,8 +316,25 @@ typedef pthread_key_t __libc_key_t;
   __libc_maybe_call (__pthread_mutex_unlock, (&(NAME)), 0)
 #endif
 
-#define __rtld_lock_unlock_recursive(NAME) \
+#if defined _LIBC && defined SHARED
+# define __rtld_lock_default_lock_recursive(lock) \
+  ++((pthread_mutex_t *)(lock))->__data.__count;
+
+# define __rtld_lock_default_unlock_recursive(lock) \
+  --((pthread_mutex_t *)(lock))->__data.__count;
+
+# define __rtld_lock_lock_recursive(NAME) \
+  GL(dl_rtld_lock_recursive) (&(NAME).mutex)
+
+# define __rtld_lock_unlock_recursive(NAME) \
+  GL(dl_rtld_unlock_recursive) (&(NAME).mutex)
+#else
+# define __rtld_lock_lock_recursive(NAME) \
+  __libc_maybe_call (__pthread_mutex_lock, (&(NAME).mutex), 0)
+
+# define __rtld_lock_unlock_recursive(NAME) \
   __libc_maybe_call (__pthread_mutex_unlock, (&(NAME).mutex), 0)
+#endif
 
 /* Define once control variable.  */
 #if PTHREAD_ONCE_INIT == 0
--- libc/nptl/init.c.jj	2003-08-03 04:15:48.000000000 -0400
+++ libc/nptl/init.c	2003-08-07 08:20:34.000000000 -0400
@@ -270,6 +270,15 @@ __pthread_initialize_minimal_internal (v
   /* Transfer the old value from the dynamic linker's internal location.  */
   *__libc_dl_error_tsd () = *(*GL(dl_error_catch_tsd)) ();
   GL(dl_error_catch_tsd) = &__libc_dl_error_tsd;
+
+  /* Make __rtld_lock_{,un}lock_recursive use pthread_mutex_{,un}lock,
+     keep the lock count from the ld.so implementation.  */
+  GL(dl_rtld_lock_recursive) = (void *) INTUSE (__pthread_mutex_lock);
+  GL(dl_rtld_unlock_recursive) = (void *) INTUSE (__pthread_mutex_unlock);
+  unsigned int rtld_lock_count = GL(dl_load_lock).mutex.__data.__count;
+  GL(dl_load_lock).mutex.__data.__count = 0;
+  while (rtld_lock_count-- > 0)
+    INTUSE (__pthread_mutex_lock) (&GL(dl_load_lock).mutex);
 #endif
 
   GL(dl_init_static_tls) = &__pthread_init_static_tls;
--- libc/nptl/pt-longjmp.c.jj	2002-11-26 17:49:18.000000000 -0500
+++ libc/nptl/pt-longjmp.c	2003-08-07 07:38:47.000000000 -0400
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -54,7 +54,7 @@ __pthread_cleanup_upto (__jmp_buf target
 
   THREAD_SETMEM (self, cleanup, cbuf);
 }
-
+hidden_def (__pthread_cleanup_upto)
 
 
 void
--- libc/nptl/pthreadP.h.jj	2003-08-03 04:15:48.000000000 -0400
+++ libc/nptl/pthreadP.h	2003-08-03 04:15:48.000000000 -0400
@@ -217,6 +217,9 @@ extern void __reclaim_stacks (void) attr
 
 /* longjmp handling.  */
 extern void __pthread_cleanup_upto (__jmp_buf target, char *targetframe);
+#if defined NOT_IN_libc && defined IS_IN_libpthread
+hidden_proto (__pthread_cleanup_upto)
+#endif
 
 
 /* Functions with versioned interfaces.  */
--- libc/elf/rtld.c.jj	2003-08-06 14:36:13.000000000 -0400
+++ libc/elf/rtld.c	2003-08-07 06:57:42.000000000 -0400
@@ -588,6 +588,20 @@ _dl_initial_error_catch_tsd (void)
 }
 #endif
 
+#if defined SHARED && defined _LIBC_REENTRANT \
+    && defined __rtld_lock_default_lock_recursive
+static void rtld_lock_default_lock_recursive (void *lock)
+{
+  __rtld_lock_default_lock_recursive (lock);
+}
+
+static void rtld_lock_default_unlock_recursive (void *lock)
+{
+  __rtld_lock_default_unlock_recursive (lock);
+}
+#endif
+
+
 static const char *library_path;	/* The library search path.  */
 static const char *preloadlist;		/* The list preloaded objects.  */
 static int version_info;		/* Nonzero if information about
@@ -626,6 +640,12 @@ dl_main (const ElfW(Phdr) *phdr,
   GL(dl_init_static_tls) = &_dl_nothread_init_static_tls;
 #endif
 
+#if defined SHARED && defined _LIBC_REENTRANT \
+    && defined __rtld_lock_default_lock_recursive
+  GL(dl_rtld_lock_recursive) = rtld_lock_default_lock_recursive;
+  GL(dl_rtld_unlock_recursive) = rtld_lock_default_unlock_recursive;
+#endif
+
   /* Process the environment variable which control the behaviour.  */
   process_envvars (&mode);
 
--- libc/linuxthreads/pthread.c.jj	2003-07-31 04:35:47.000000000 -0400
+++ libc/linuxthreads/pthread.c	2003-08-07 08:37:43.000000000 -0400
@@ -588,6 +588,15 @@ static void pthread_initialize(void)
   /* Transfer the old value from the dynamic linker's internal location.  */
   *__libc_dl_error_tsd () = *(*GL(dl_error_catch_tsd)) ();
   GL(dl_error_catch_tsd) = &__libc_dl_error_tsd;
+
+  /* Make __rtld_lock_{,un}lock_recursive use pthread_mutex_{,un}lock,
+     keep the lock count from the ld.so implementation.  */
+  GL(dl_rtld_lock_recursive) = (void *) __pthread_mutex_lock;
+  GL(dl_rtld_unlock_recursive) = (void *) __pthread_mutex_unlock;
+  unsigned int rtld_lock_count = GL(dl_load_lock).mutex.__m_count;
+  GL(dl_load_lock).mutex.__m_count = 0;
+  while (rtld_lock_count-- > 0)
+    __pthread_mutex_lock (&GL(dl_load_lock).mutex);
 #endif
 
 #ifdef USE_TLS
--- libc/linuxthreads/sysdeps/pthread/bits/libc-lock.h.jj	2003-07-21 07:30:23.000000000 -0400
+++ libc/linuxthreads/sysdeps/pthread/bits/libc-lock.h	2003-08-07 08:32:13.000000000 -0400
@@ -180,7 +180,6 @@ typedef pthread_key_t __libc_key_t;
 
 /* Lock the recursive named lock variable.  */
 #define __libc_lock_lock_recursive(NAME) __libc_lock_lock ((NAME).mutex)
-#define __rtld_lock_lock_recursive(NAME) __libc_lock_lock_recursive (NAME)
 
 /* Try to lock the named lock variable.  */
 #define __libc_lock_trylock(NAME) \
@@ -203,8 +202,23 @@ typedef pthread_key_t __libc_key_t;
 
 /* Unlock the recursive named lock variable.  */
 #define __libc_lock_unlock_recursive(NAME) __libc_lock_unlock ((NAME).mutex)
-#define __rtld_lock_unlock_recursive(NAME) __libc_lock_unlock_recursive (NAME)
 
+#if defined _LIBC && defined SHARED
+# define __rtld_lock_default_lock_recursive(lock) \
+  ++((pthread_mutex_t *)(lock))->__m_count;
+
+# define __rtld_lock_default_unlock_recursive(lock) \
+  --((pthread_mutex_t *)(lock))->__m_count;
+
+# define __rtld_lock_lock_recursive(NAME) \
+  GL(dl_rtld_lock_recursive) (&(NAME).mutex)
+
+# define __rtld_lock_unlock_recursive(NAME) \
+  GL(dl_rtld_unlock_recursive) (&(NAME).mutex)
+#else
+#define __rtld_lock_lock_recursive(NAME) __libc_lock_lock_recursive (NAME)
+#define __rtld_lock_unlock_recursive(NAME) __libc_lock_unlock_recursive (NAME)
+#endif
 
 /* Define once control variable.  */
 #if PTHREAD_ONCE_INIT == 0
--- libc/sysdeps/generic/ldsodefs.h.jj	2003-07-31 04:35:54.000000000 -0400
+++ libc/sysdeps/generic/ldsodefs.h	2003-08-07 06:57:29.000000000 -0400
@@ -349,6 +349,12 @@ struct rtld_global
   /* Structure describing the dynamic linker itself.  */
   EXTERN struct link_map _dl_rtld_map;
 
+#if defined SHARED && defined _LIBC_REENTRANT \
+    && defined __rtld_lock_default_lock_recursive
+  EXTERN void (*_dl_rtld_lock_recursive) (void *);
+  EXTERN void (*_dl_rtld_unlock_recursive) (void *);
+#endif
+
   /* Keep the conditional TLS members at the end so the layout of the
      structure used by !USE_TLS code matches the prefix of the layout in
      the USE_TLS rtld.  Note that `struct link_map' is conditionally

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]