This should make things work even if application not using libpthread
dlopen():s a library pulling in libpthread.

Also some minor other fixes.

>From 73e70c465830884b98d5036cee0f47b8c77ba07e Mon Sep 17 00:00:00 2001
From: =?utf-8?q?Timo=20Ter=C3=A4s?= <[email protected]>
Date: Thu, 22 Apr 2010 05:41:17 +0000
Subject: [PATCH 1/5] nptl: fix malloc library locking
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit

Update malloc library to use internal uclibc locking primitives
to get the libpthread calls correct.

Signed-off-by: Timo Teräs <[email protected]
---
 libc/stdlib/malloc/heap.h   |    7 +++----
 libc/stdlib/malloc/malloc.h |   11 +++++------
 2 files changed, 8 insertions(+), 10 deletions(-)

diff --git a/libc/stdlib/malloc/heap.h b/libc/stdlib/malloc/heap.h
index c0c5df8..3038079 100644
--- a/libc/stdlib/malloc/heap.h
+++ b/libc/stdlib/malloc/heap.h
@@ -16,11 +16,10 @@
 
 /* On multi-threaded systems, the heap includes a lock.  */
 #ifdef __UCLIBC_HAS_THREADS__
-# include <pthread.h>
-# include <bits/uClibc_pthread.h>
+# include <bits/uClibc_mutex.h>
 # define HEAP_USE_LOCKING
-# define __heap_lock(heap_lock) __pthread_mutex_lock (heap_lock)
-# define __heap_unlock(heap_lock) __pthread_mutex_unlock (heap_lock)
+# define __heap_lock(heap_lock) __UCLIBC_MUTEX_LOCK_CANCEL_UNSAFE(*(heap_lock))
+# define __heap_unlock(heap_lock) __UCLIBC_MUTEX_UNLOCK_CANCEL_UNSAFE(*(heap_lock))
 #else
 # define __heap_lock(heap_lock)
 # define __heap_unlock(heap_lock)
diff --git a/libc/stdlib/malloc/malloc.h b/libc/stdlib/malloc/malloc.h
index 2afc3a8..0a4b43b 100644
--- a/libc/stdlib/malloc/malloc.h
+++ b/libc/stdlib/malloc/malloc.h
@@ -132,13 +132,12 @@ extern int __malloc_mmb_debug;
 /* Locking for multithreaded apps.  */
 #ifdef __UCLIBC_HAS_THREADS__
 
-# include <pthread.h>
-# include <bits/uClibc_pthread.h>
+# include <bits/uClibc_mutex.h>
 
 # define MALLOC_USE_LOCKING
 
-typedef pthread_mutex_t malloc_mutex_t;
-# define MALLOC_MUTEX_INIT	PTHREAD_MUTEX_INITIALIZER
+typedef __UCLIBC_MUTEX_TYPE malloc_mutex_t;
+# define MALLOC_MUTEX_INIT	__UCLIBC_MUTEX_INITIALIZER
 
 # ifdef MALLOC_USE_SBRK
 /* This lock is used to serialize uses of the `sbrk' function (in both
@@ -146,8 +145,8 @@ typedef pthread_mutex_t malloc_mutex_t;
    things will break if these multiple calls are interleaved with another
    thread's use of sbrk!).  */
 extern malloc_mutex_t __malloc_sbrk_lock;
-#  define __malloc_lock_sbrk()	__pthread_mutex_lock (&__malloc_sbrk_lock)
-#  define __malloc_unlock_sbrk() __pthread_mutex_unlock (&__malloc_sbrk_lock)
+#  define __malloc_lock_sbrk()	__UCLIBC_MUTEX_LOCK_CANCEL_UNSAFE (__malloc_sbrk_lock)
+#  define __malloc_unlock_sbrk() __UCLIBC_MUTEX_UNLOCK_CANCEL_UNSAFE (__malloc_sbrk_lock)
 # endif /* MALLOC_USE_SBRK */
 
 #else /* !__UCLIBC_HAS_THREADS__ */
-- 
1.6.3.3

>From 0c701f4fcdda60b7abd5e02c74d35dd7127ff773 Mon Sep 17 00:00:00 2001
From: =?utf-8?q?Timo=20Ter=C3=A4s?= <[email protected]>
Date: Thu, 22 Apr 2010 05:43:00 +0000
Subject: [PATCH 2/5] nptl: fix warnings of shadowing __self
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit

Stdio locking macroes do:
  void *__self = THREAD_SELF;

But THREAD_SELF uses __self also internally which causes shadowing
warnings. Just rename the outer variable for now. Might be an idea
to convert the macroes to static inline functions.

Signed-off-by: Timo Teräs <[email protected]>
---
 libpthread/nptl/sysdeps/pthread/bits/stdio-lock.h |   12 ++++++------
 1 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/libpthread/nptl/sysdeps/pthread/bits/stdio-lock.h b/libpthread/nptl/sysdeps/pthread/bits/stdio-lock.h
index b8efdd8..3437e61 100644
--- a/libpthread/nptl/sysdeps/pthread/bits/stdio-lock.h
+++ b/libpthread/nptl/sysdeps/pthread/bits/stdio-lock.h
@@ -39,11 +39,11 @@ typedef struct { int lock; int cnt; void *owner; } _IO_lock_t;
 
 #define _IO_lock_lock(_name) \
   do {									      \
-    void *__self = THREAD_SELF;						      \
-    if ((_name).owner != __self)					      \
+    void *__meself = THREAD_SELF;						      \
+    if ((_name).owner != __meself)					      \
       {									      \
 	lll_lock ((_name).lock, LLL_PRIVATE);				      \
-        (_name).owner = __self;						      \
+        (_name).owner = __meself;						      \
       }									      \
     ++(_name).cnt;							      \
   } while (0)
@@ -51,12 +51,12 @@ typedef struct { int lock; int cnt; void *owner; } _IO_lock_t;
 #define _IO_lock_trylock(_name) \
   ({									      \
     int __result = 0;							      \
-    void *__self = THREAD_SELF;						      \
-    if ((_name).owner != __self)					      \
+    void *__meself = THREAD_SELF;						      \
+    if ((_name).owner != __meself)					      \
       {									      \
         if (lll_trylock ((_name).lock) == 0)				      \
           {								      \
-            (_name).owner = __self;					      \
+            (_name).owner = __meself;					      \
             (_name).cnt = 1;						      \
           }								      \
         else								      \
-- 
1.6.3.3

>From 92163d49311f3ce22559d5069c887a65efee0111 Mon Sep 17 00:00:00 2001
From: =?utf-8?q?Timo=20Ter=C3=A4s?= <[email protected]>
Date: Thu, 22 Apr 2010 08:28:10 +0000
Subject: [PATCH 3/5] ldso: support RTLD_NODELETE and DF_1_NODELETE
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit

Honor the nodelete flags so we don't delete shared library if it's
sticky. This is useful for libpthread if it gets pulled in by a
dlopen'ed library.

Signed-off-by: Timo Teräs <[email protected]>
---
 ldso/include/dl-elf.h |   20 +++++++++++++-------
 ldso/ldso/dl-elf.c    |   10 ++++++----
 ldso/libdl/libdl.c    |    5 +++--
 3 files changed, 22 insertions(+), 13 deletions(-)

diff --git a/ldso/include/dl-elf.h b/ldso/include/dl-elf.h
index 076678c..9c2888f 100644
--- a/ldso/include/dl-elf.h
+++ b/ldso/include/dl-elf.h
@@ -104,13 +104,15 @@ extern void _dl_protect_relro (struct elf_resolve *l);
 # define DT_GNU_HASH_IDX (DT_RELCONT_IDX + 1)
 #endif
 
-extern void _dl_parse_dynamic_info(ElfW(Dyn) *dpnt, unsigned long dynamic_info[],
-                                   void *debug_addr, DL_LOADADDR_TYPE load_off);
+extern unsigned int _dl_parse_dynamic_info(ElfW(Dyn) *dpnt, unsigned long dynamic_info[],
+                                           void *debug_addr, DL_LOADADDR_TYPE load_off);
 
 static __always_inline
-void __dl_parse_dynamic_info(ElfW(Dyn) *dpnt, unsigned long dynamic_info[],
-                             void *debug_addr, DL_LOADADDR_TYPE load_off)
+unsigned int __dl_parse_dynamic_info(ElfW(Dyn) *dpnt, unsigned long dynamic_info[],
+                                     void *debug_addr, DL_LOADADDR_TYPE load_off)
 {
+	unsigned int rtld_flags = 0;
+
 	for (; dpnt->d_tag; dpnt++) {
 		if (dpnt->d_tag < DT_NUM) {
 			dynamic_info[dpnt->d_tag] = dpnt->d_un.d_val;
@@ -138,9 +140,12 @@ void __dl_parse_dynamic_info(ElfW(Dyn) *dpnt, unsigned long dynamic_info[],
 		} else if (dpnt->d_tag < DT_LOPROC) {
 			if (dpnt->d_tag == DT_RELOCCOUNT)
 				dynamic_info[DT_RELCONT_IDX] = dpnt->d_un.d_val;
-			if (dpnt->d_tag == DT_FLAGS_1 &&
-			    (dpnt->d_un.d_val & DF_1_NOW))
-				dynamic_info[DT_BIND_NOW] = 1;
+			if (dpnt->d_tag == DT_FLAGS_1) {
+				if (dpnt->d_un.d_val & DF_1_NOW)
+					dynamic_info[DT_BIND_NOW] = 1;
+				if (dpnt->d_un.d_val & DF_1_NODELETE)
+					rtld_flags |= RTLD_NODELETE;
+			}
 #ifdef __LDSO_GNU_HASH_SUPPORT__
 			if (dpnt->d_tag == DT_GNU_HASH)
 				dynamic_info[DT_GNU_HASH_IDX] = dpnt->d_un.d_ptr;
@@ -167,6 +172,7 @@ void __dl_parse_dynamic_info(ElfW(Dyn) *dpnt, unsigned long dynamic_info[],
 	ADJUST_DYN_INFO(DT_GNU_HASH_IDX, load_off);
 #endif
 #undef ADJUST_DYN_INFO
+	return rtld_flags;
 }
 
 /* Reloc type classes as returned by elf_machine_type_class().
diff --git a/ldso/ldso/dl-elf.c b/ldso/ldso/dl-elf.c
index 8fb8ffa..5562e07 100644
--- a/ldso/ldso/dl-elf.c
+++ b/ldso/ldso/dl-elf.c
@@ -337,6 +337,7 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
 	unsigned long *lpnt;
 	unsigned long libaddr;
 	unsigned long minvma = 0xffffffff, maxvma = 0;
+	unsigned int rtld_flags;
 	int i, flags, piclib, infile;
 	ElfW(Addr) relro_addr = 0;
 	size_t relro_size = 0;
@@ -700,7 +701,7 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
 
 	dpnt = (ElfW(Dyn) *) dynamic_addr;
 	_dl_memset(dynamic_info, 0, sizeof(dynamic_info));
-	_dl_parse_dynamic_info(dpnt, dynamic_info, NULL, lib_loadaddr);
+	rtld_flags = _dl_parse_dynamic_info(dpnt, dynamic_info, NULL, lib_loadaddr);
 	/* If the TEXTREL is set, this means that we need to make the pages
 	   writable before we perform relocations.  Do this now. They get set
 	   back again later. */
@@ -732,6 +733,7 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
 	tpnt->st_ino = st.st_ino;
 	tpnt->ppnt = (ElfW(Phdr) *) DL_RELOC_ADDR(tpnt->loadaddr, epnt->e_phoff);
 	tpnt->n_phent = epnt->e_phnum;
+	tpnt->rtld_flags |= rtld_flags;
 
 #if defined(USE_TLS) && USE_TLS
 	if (tlsppnt) {
@@ -991,8 +993,8 @@ char *_dl_strdup(const char *string)
 	return retval;
 }
 
-void _dl_parse_dynamic_info(ElfW(Dyn) *dpnt, unsigned long dynamic_info[],
-                            void *debug_addr, DL_LOADADDR_TYPE load_off)
+unsigned int _dl_parse_dynamic_info(ElfW(Dyn) *dpnt, unsigned long dynamic_info[],
+                                    void *debug_addr, DL_LOADADDR_TYPE load_off)
 {
-	__dl_parse_dynamic_info(dpnt, dynamic_info, debug_addr, load_off);
+	return __dl_parse_dynamic_info(dpnt, dynamic_info, debug_addr, load_off);
 }
diff --git a/ldso/libdl/libdl.c b/ldso/libdl/libdl.c
index 05a68dd..f19a015 100644
--- a/ldso/libdl/libdl.c
+++ b/ldso/libdl/libdl.c
@@ -736,7 +736,7 @@ static int do_dlclose(void *vhandle, int need_fini)
 		_dl_handles = rpnt->next_handle;
 	_dl_if_debug_print("%s: usage count: %d\n",
 			handle->dyn->libname, handle->dyn->usage_count);
-	if (handle->dyn->usage_count != 1) {
+	if (handle->dyn->usage_count != 1 || (handle->dyn->rtld_flags & RTLD_NODELETE)) {
 		handle->dyn->usage_count--;
 		free(handle);
 		return 0;
@@ -744,7 +744,8 @@ static int do_dlclose(void *vhandle, int need_fini)
 	/* OK, this is a valid handle - now close out the file */
 	for (j = 0; j < handle->init_fini.nlist; ++j) {
 		tpnt = handle->init_fini.init_fini[j];
-		if (--tpnt->usage_count == 0) {
+		tpnt->usage_count--;
+		if (tpnt->usage_count == 0 && !(tpnt->rtld_flags & RTLD_NODELETE)) {
 			if ((tpnt->dynamic_info[DT_FINI]
 			     || tpnt->dynamic_info[DT_FINI_ARRAY])
 			 && need_fini
-- 
1.6.3.3

>From c7d930d10abef6188c7b6f9f6f47720ef1362124 Mon Sep 17 00:00:00 2001
From: =?utf-8?q?Timo=20Ter=C3=A4s?= <[email protected]>
Date: Thu, 22 Apr 2010 11:06:41 +0000
Subject: [PATCH 4/5] nptl: fix libc internal, dynamically enabled locking
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit

Final iteration to fix libc internal locking if libpthread is pulled
in by dlopen call (directly or indirectly).

We cannot really use the weak symbol trick for shared build, since
the symbols won't get refreshed if libpthread is pulled in dynamically.
In glibc, they have #ifdef SHARED magic to either use pthread_functions
table, or weaks. But as we shared object files with both builds, this
does not sounds good either.

The reintroduces the libc weaks.c, but uses them now only with static
build. For dynamic build, we still use the symbols with same name, but
provide weaks in forward.c so they end up dereferencing the
pthread_functions table indirectly if we are not linked to libpthread.
Mutex initialization is hard coded as inline, as it needs to happen even
if libpthread is not initially loaded.

Signed-off-by: Timo Teräs <[email protected]>
---
 libc/misc/pthread/Makefile.in                 |    1 +
 libc/misc/pthread/weaks.c                     |   40 +++++++++++++++++++++++++
 libc/sysdeps/linux/common/bits/uClibc_mutex.h |   17 +++-------
 libpthread/nptl/forward.c                     |   20 ++++++++++--
 4 files changed, 62 insertions(+), 16 deletions(-)
 create mode 100644 libc/misc/pthread/weaks.c

diff --git a/libc/misc/pthread/Makefile.in b/libc/misc/pthread/Makefile.in
index 2f436ac..69cdf10 100644
--- a/libc/misc/pthread/Makefile.in
+++ b/libc/misc/pthread/Makefile.in
@@ -11,6 +11,7 @@ MISC_PTHREAD_DIR := $(top_srcdir)libc/misc/pthread
 MISC_PTHREAD_OUT := $(top_builddir)libc/misc/pthread
 
 libc-shared-$(UCLIBC_HAS_TLS) += $(MISC_PTHREAD_OUT)/tsd.os
+libc-static-$(UCLIBC_HAS_THREADS) += $(MISC_PTHREAD_OUT)/weaks.o
 
 objclean-y += CLEAN_libc/misc/pthread
 
diff --git a/libc/misc/pthread/weaks.c b/libc/misc/pthread/weaks.c
new file mode 100644
index 0000000..fb1d85f
--- /dev/null
+++ b/libc/misc/pthread/weaks.c
@@ -0,0 +1,40 @@
+/* The weak pthread functions for Linux.
+   Copyright (C) 1996, 1997, 1998 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
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <libc-internal.h>
+
+/* Weaks for internal library use only.
+ *
+ * We need to define weaks here to cover all the pthread functions that
+ * libc itself will use so that we aren't forced to link libc against
+ * libpthread.  This file is only used in libc.a and since we have
+ * weaks here, they will be automatically overridden by libpthread.a
+ * if it gets linked in.
+ */
+
+static int __pthread_return_0 (void) { return 0; }
+static void __pthread_return_void (void) { return; }
+
+weak_alias (__pthread_return_0, __pthread_mutex_init)
+weak_alias (__pthread_return_0, __pthread_mutex_lock)
+weak_alias (__pthread_return_0, __pthread_mutex_trylock)
+weak_alias (__pthread_return_0, __pthread_mutex_unlock)
+weak_alias (__pthread_return_void, _pthread_cleanup_push_defer)
+weak_alias (__pthread_return_void, _pthread_cleanup_pop_restore)
+
diff --git a/libc/sysdeps/linux/common/bits/uClibc_mutex.h b/libc/sysdeps/linux/common/bits/uClibc_mutex.h
index 6d004bb..3e3d006 100644
--- a/libc/sysdeps/linux/common/bits/uClibc_mutex.h
+++ b/libc/sysdeps/linux/common/bits/uClibc_mutex.h
@@ -15,13 +15,6 @@
 #include <pthread.h>
 #include <bits/uClibc_pthread.h>
 
-#define __uclibc_maybe_call(FUNC, ARGS) \
-	(__extension__ ({					\
-		__typeof (FUNC) *_fn = (FUNC);			\
-		if (_fn != NULL) { (*_fn) ARGS; }		\
-	}))
-
-
 #define __UCLIBC_MUTEX_TYPE				pthread_mutex_t
 
 #define __UCLIBC_MUTEX(M)				pthread_mutex_t M
@@ -30,21 +23,21 @@
 #define __UCLIBC_MUTEX_EXTERN(M)			extern pthread_mutex_t M
 
 #define __UCLIBC_MUTEX_INIT_VAR(M)								\
-		__uclibc_maybe_call(__pthread_mutex_init,(&(M),NULL))
+		((M) = (pthread_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP)
 
 #define __UCLIBC_MUTEX_LOCK_CANCEL_UNSAFE(M)								\
-		__uclibc_maybe_call(__pthread_mutex_lock,(&(M)))
+		__pthread_mutex_lock(&(M))
 
 #define __UCLIBC_MUTEX_UNLOCK_CANCEL_UNSAFE(M)								\
-		__uclibc_maybe_call(__pthread_mutex_unlock,(&(M)))
+		__pthread_mutex_unlock(&(M))
 
 #define __UCLIBC_MUTEX_TRYLOCK_CANCEL_UNSAFE(M)								\
-		__uclibc_maybe_call(__pthread_mutex_trylock,(&(M)))
+		__pthread_mutex_trylock,(&(M))
 
 #define __UCLIBC_MUTEX_CONDITIONAL_LOCK(M,C)								\
 	do {												\
 		struct _pthread_cleanup_buffer __infunc_pthread_cleanup_buffer;				\
-		int __infunc_need_locking = ((C) && (__pthread_mutex_lock != NULL));			\
+		int __infunc_need_locking = (C);							\
 		if (__infunc_need_locking) {								\
 			_pthread_cleanup_push_defer(&__infunc_pthread_cleanup_buffer,			\
 					   (void (*) (void *))__pthread_mutex_unlock,			\
diff --git a/libpthread/nptl/forward.c b/libpthread/nptl/forward.c
index 8f528d0..7878334 100644
--- a/libpthread/nptl/forward.c
+++ b/libpthread/nptl/forward.c
@@ -35,10 +35,11 @@ int __libc_pthread_functions_init attribute_hidden;
 rettype									      \
 name decl								      \
 {									      \
-  if (!__libc_pthread_functions_init)					      \
+  if (!__libc_pthread_functions_init) {					      \
     defaction;								      \
-									      \
-  return PTHFCT_CALL (ptr_##name, params);				      \
+  } else {								      \
+    return PTHFCT_CALL (ptr_##name, params);				      \
+  }									      \
 }
 
 #define FORWARD(name, decl, params, defretval) \
@@ -130,9 +131,10 @@ FORWARD (pthread_mutex_init,
 	 (mutex, mutexattr), 0)
 
 FORWARD (pthread_mutex_lock, (pthread_mutex_t *mutex), (mutex), 0)
+weak_alias (pthread_mutex_lock, __pthread_mutex_lock)
 
 FORWARD (pthread_mutex_unlock, (pthread_mutex_t *mutex), (mutex), 0)
-
+weak_alias (pthread_mutex_unlock, __pthread_mutex_unlock)
 
 FORWARD2 (pthread_self, pthread_t, (void), (), return 0)
 
@@ -143,6 +145,16 @@ FORWARD (pthread_setcancelstate, (int state, int *oldstate), (state, oldstate),
 FORWARD (pthread_setcanceltype, (int type, int *oldtype), (type, oldtype), 0)
 
 #define return /* value is void */
+FORWARD2(_pthread_cleanup_push_defer,
+	 void, (struct _pthread_cleanup_buffer *buffer, void (*routine)(void *), void *arg),
+	 (buffer, routine, arg),
+	 { buffer->__routine = routine; buffer->__arg = arg; });
+
+FORWARD2(_pthread_cleanup_pop_restore,
+	 void, (struct _pthread_cleanup_buffer *buffer, int execute),
+	 (buffer, execute),
+	 if (execute) { buffer->__routine(buffer->__arg); });
+
 FORWARD2(__pthread_unwind,
 	 void attribute_hidden __attribute ((noreturn)) __cleanup_fct_attribute,
 	 (__pthread_unwind_buf_t *buf), (buf), {
-- 
1.6.3.3

>From 3e0f5021c9702a5d45764f029ef9a2f09a8738f3 Mon Sep 17 00:00:00 2001
From: =?utf-8?q?Timo=20Ter=C3=A4s?= <[email protected]>
Date: Thu, 22 Apr 2010 05:53:43 +0000
Subject: [PATCH 5/5] nptl: fix dynamic initialization of libpthread
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit

If libpthread get's pulled in via dlopen(), we need to do libpthread
initialization in dlopen(). Achieve this by making initializer function
out of __pthread_initialize_minimal_internal. Add the proper linker
flags and make it callable multiple times.

Add also nodelete flag which ensures that libpthread will not get
unmapped after it's been loading. Though, ld.so does not yet
support this.

Signed-off-by: Timo Teräs <[email protected]>
---
 libpthread/nptl/Makefile.in |    2 +-
 libpthread/nptl/init.c      |    6 ++++++
 2 files changed, 7 insertions(+), 1 deletions(-)

diff --git a/libpthread/nptl/Makefile.in b/libpthread/nptl/Makefile.in
index d9f2d23..20f4cbc 100644
--- a/libpthread/nptl/Makefile.in
+++ b/libpthread/nptl/Makefile.in
@@ -220,7 +220,7 @@ else
 LDFLAGS-libpthread.so := $(LDFLAGS)
 endif
 
-LDFLAGS-libpthread.so += $(top_builddir)lib/$(UCLIBC_LDSO_NAME)-$(VERSION).so $(top_builddir)lib/libdl-$(VERSION).so
+LDFLAGS-libpthread.so += $(top_builddir)lib/$(UCLIBC_LDSO_NAME)-$(VERSION).so $(top_builddir)lib/libdl-$(VERSION).so -Wl,-z,nodelete,-z,initfirst,-init=__pthread_initialize_minimal_internal
 
 LIBS-libpthread.so := $(LIBS)
 
diff --git a/libpthread/nptl/init.c b/libpthread/nptl/init.c
index 44f2c86..b70de84 100644
--- a/libpthread/nptl/init.c
+++ b/libpthread/nptl/init.c
@@ -260,6 +260,12 @@ static bool __nptl_initial_report_events __attribute_used__;
 void
 __pthread_initialize_minimal_internal (void)
 {
+  static int initialized = 0;
+
+  if (initialized)
+    return;
+  initialized = 1;
+
 #ifndef SHARED
   /* Unlike in the dynamically linked case the dynamic linker has not
      taken care of initializing the TLS data structures.  */
-- 
1.6.3.3

_______________________________________________
uClibc mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/uclibc

Reply via email to