libc/libpthread: Inject threadsafe locking callbacks for rtld.
authorImre Vadász <imre@vdsz.com>
Sun, 2 Apr 2017 11:50:15 +0000 (13:50 +0200)
committerImre Vadász <imre@vdsz.com>
Sun, 2 Apr 2017 19:05:47 +0000 (21:05 +0200)
* Make rtld thread-safe. Add lib/libthread_xu/thread/thr_rtld.c
  to the build and use it to inject pthread based locking callbacks
  for rtld.

* In rtld_lock.c, do the thread_mask_clear(lock->mask); after releasing
  the actual lock, to avoid deadlocks when rtld is called recursively
  from the pthread locking callbacks.
  XXX An alternative solution for this issue would be, to flag the
      libpthread dynamic library as bind_now to avoid the recursive rtld
      calls.

lib/libthread_xu/Makefile
lib/libthread_xu/thread/Makefile.inc
lib/libthread_xu/thread/thr_kern.c
lib/libthread_xu/thread/thr_rtld.c
libexec/rtld-elf/rtld_lock.c

index da4020a..a77e0f9 100644 (file)
@@ -14,6 +14,7 @@ CFLAGS+=-I${.CURDIR}/../libc/include -I${.CURDIR}/thread \
        -I${.CURDIR}/../../include
 CFLAGS+=-I${.CURDIR}/arch/${MACHINE_ARCH}/include
 CFLAGS+=-I${.CURDIR}/../libthread_db
+CFLAGS+=-I${.CURDIR}/../../libexec/rtld-elf
 
 # XXX this breaks threaded applications
 #LDFLAGS=-Wl,-version-script=${.CURDIR}/pthread.map
index 4ed06da..27d0204 100644 (file)
@@ -35,6 +35,7 @@ SRCS+= \
        thr_printf.c \
        thr_pspinlock.c \
        thr_resume_np.c \
+       thr_rtld.c \
        thr_rwlock.c \
        thr_rwlockattr.c \
        thr_self.c \
index 2d2f2da..a6b2e08 100644 (file)
@@ -50,13 +50,12 @@ _thr_setthreaded(int threaded)
                return (0);
 
        __isthreaded = threaded;
-#if 0
        if (threaded != 0) {
                _thr_rtld_init();
        } else {
                _thr_rtld_fini();
        }
-#endif
+
        return (0);
 }
 
index 3cbec69..693889c 100644 (file)
  * $FreeBSD: src/lib/libpthread/thread/thr_rtld.c,v 1.5 2003/11/05 18:19:24 deischen Exp $
  */
 
+#include "namespace.h"
 #include <machine/tls.h>
 #include <stdlib.h>
 #include <pthread.h>
 
+#include "un-namespace.h"
 #include "rtld_lock.h"
 #include "thr_private.h"
 
@@ -66,7 +68,7 @@ _thr_rtld_rlock_acquire(void *lock)
        pthread_rwlock_t prwlock;
 
        prwlock = (pthread_rwlock_t)lock;
-       _thr_rwlock_rdlock(&prwlock);
+       _pthread_rwlock_rdlock(&prwlock);
 }
 
 static void
@@ -75,7 +77,7 @@ _thr_rtld_wlock_acquire(void *lock)
        pthread_rwlock_t prwlock;
 
        prwlock = (pthread_rwlock_t)lock;
-       _thr_rwlock_wrlock(&prwlock);
+       _pthread_rwlock_wrlock(&prwlock);
 }
 
 static void
@@ -84,7 +86,7 @@ _thr_rtld_lock_release(void *lock)
        pthread_rwlock_t prwlock;
 
        prwlock = (pthread_rwlock_t)lock;
-       _thr_rwlock_unlock(&prwlock);
+       _pthread_rwlock_unlock(&prwlock);
 }
 
 
index 50a7812..1cd30b9 100644 (file)
@@ -226,8 +226,8 @@ lock_release(rtld_lock_t lock, RtldLockState *lockstate)
                break;
        case RTLD_LOCK_RLOCKED:
        case RTLD_LOCK_WLOCKED:
-               thread_mask_clear(lock->mask);
                lockinfo.lock_release(lock->handle);
+               thread_mask_clear(lock->mask);
                break;
        default:
                assert(0);