Commit 7b7af3b4 authored by Timo Teräs's avatar Timo Teräs

main/libc0.9.32: fix a libdl locking issue

parent 95ae5bb1
From 521807eb4d18c5e693f91ad53cb277c76aab8686 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timo=20Ter=C3=A4s?= <timo.teras@iki.fi>
Date: Thu, 24 Mar 2011 13:24:32 +0200
Subject: [PATCH] libdl: rudimentary locking for dlopen/dlsym/dlclose
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This implements big-dlfcn lock to allow multithreaded usage of
dlopen/dlsym/dlclose. We should really clean up the dl code so
we can use more fine grained locking or even RCU where appropriate.
But at least we won't crash now.
Signed-off-by: Timo Teräs <timo.teras@iki.fi>
---
TODO | 1 +
ldso/libdl/libdl.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++----
2 files changed, 50 insertions(+), 5 deletions(-)
diff --git a/TODO b/TODO
index ae305a5..95cabd5 100644
--- a/TODO
+++ b/TODO
@@ -101,6 +101,7 @@ TODO list for AFTER the uClibc 1.0.0 release:
*) run 'nm -D --size-sort -t d libuClibc-0.9.26.so' and work on the
biggest things (i.e. stuff at the end of the list) to make
them smaller.
+ *) Fix dlopen/dlsym/dlclose locking to more fine grained or use RCU
<more wishlist items here>
diff --git a/ldso/libdl/libdl.c b/ldso/libdl/libdl.c
index 68cd579..e007f54 100644
--- a/ldso/libdl/libdl.c
+++ b/ldso/libdl/libdl.c
@@ -34,6 +34,7 @@
#include <stdio.h>
#include <string.h> /* Needed for 'strstr' prototype' */
#include <stdbool.h>
+#include <bits/uClibc_mutex.h>
#ifdef __UCLIBC_HAS_TLS__
#include <tls.h>
@@ -44,6 +45,10 @@
extern void _dl_add_to_slotinfo(struct link_map *l);
#endif
+/* TODO: get rid of global lock and use more finegrained locking, or
+ * perhaps RCU for the global structures */
+__UCLIBC_MUTEX_STATIC(_dl_mutex, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP);
+
#ifdef SHARED
# if defined(USE_TLS) && USE_TLS
# include <dl-tls.h>
@@ -271,7 +276,7 @@ void dl_cleanup(void)
}
}
-void *dlopen(const char *libname, int flag)
+static void *do_dlopen(const char *libname, int flag)
{
struct elf_resolve *tpnt, *tfrom;
struct dyn_elf *dyn_chain, *rpnt = NULL, *dyn_ptr, *relro_ptr, *handle;
@@ -605,7 +610,18 @@ oops:
return NULL;
}
-void *dlsym(void *vhandle, const char *name)
+void *dlopen(const char *libname, int flag)
+{
+ void *ret;
+
+ __UCLIBC_MUTEX_CONDITIONAL_LOCK(_dl_mutex, 1);
+ ret = do_dlopen(libname, flag);
+ __UCLIBC_MUTEX_CONDITIONAL_UNLOCK(_dl_mutex, 1);
+
+ return ret;
+}
+
+static void *do_dlsym(void *vhandle, const char *name, void *caller_address)
{
struct elf_resolve *tpnt, *tfrom;
struct dyn_elf *handle;
@@ -653,7 +669,7 @@ void *dlsym(void *vhandle, const char *name)
* dynamic loader itself, as it doesn't know
* how to properly treat it.
*/
- from = (ElfW(Addr)) __builtin_return_address(0);
+ from = (ElfW(Addr)) caller_address;
tfrom = NULL;
for (rpnt = _dl_symbol_tables; rpnt; rpnt = rpnt->next) {
@@ -690,6 +706,17 @@ out:
return ret;
}
+void *dlsym(void *vhandle, const char *name)
+{
+ void *ret;
+
+ __UCLIBC_MUTEX_CONDITIONAL_LOCK(_dl_mutex, 1);
+ ret = do_dlsym(vhandle, name, __builtin_return_address(0));
+ __UCLIBC_MUTEX_CONDITIONAL_UNLOCK(_dl_mutex, 1);
+
+ return ret;
+}
+
#if 0
void *dlvsym(void *vhandle, const char *name, const char *version)
{
@@ -957,7 +984,13 @@ static int do_dlclose(void *vhandle, int need_fini)
int dlclose(void *vhandle)
{
- return do_dlclose(vhandle, 1);
+ int ret;
+
+ __UCLIBC_MUTEX_CONDITIONAL_LOCK(_dl_mutex, 1);
+ ret = do_dlclose(vhandle, 1);
+ __UCLIBC_MUTEX_CONDITIONAL_UNLOCK(_dl_mutex, 1);
+
+ return ret;
}
char *dlerror(void)
@@ -1004,7 +1037,7 @@ int dlinfo(void)
return 0;
}
-int dladdr(const void *__address, Dl_info * __info)
+static int do_dladdr(const void *__address, Dl_info * __info)
{
struct elf_resolve *pelf;
struct elf_resolve *rpnt;
@@ -1108,3 +1141,14 @@ int dladdr(const void *__address, Dl_info * __info)
}
}
#endif
+
+int dladdr(const void *__address, Dl_info * __info)
+{
+ int ret;
+
+ __UCLIBC_MUTEX_CONDITIONAL_LOCK(_dl_mutex, 1);
+ ret = do_dladdr(__address, __info);
+ __UCLIBC_MUTEX_CONDITIONAL_UNLOCK(_dl_mutex, 1);
+
+ return ret;
+}
--
1.7.1
......@@ -4,7 +4,7 @@ pkgname=libc$_abiver
_gitver=
pkgver=0.9.32_rc3
_ver=${pkgver/_/-}
pkgrel=1
pkgrel=2
pkgdesc="C library for developing embedded Linux systems"
url=http://uclibc.org
license="LGPL-2"
......@@ -24,6 +24,7 @@ source="http://uclibc.org/downloads/uClibc-${_ver}.tar.bz2
0001-ldso-limited-support-for-ORIGIN-in-rpath.patch
0002-stdlib-fix-arc4random-return-type-to-u_int32_t.patch
0003-ldso-support-RTLD_NOLOAD.patch
0001-libdl-rudimentary-locking-for-dlopen-dlsym-dlclose.patch
uclibcconfig.x86
uclibcconfig.x86_64
uclibcconfig.i486
......@@ -124,6 +125,7 @@ e0c901502602f7e9e002d910d0f32ab9 0001-libm-x86_64-implement-fesetround.patch
bc164e262c5feab55c800780704fa71c 0001-ldso-limited-support-for-ORIGIN-in-rpath.patch
b4fb68ad3d0e8331b1b40c30eb21dfdc 0002-stdlib-fix-arc4random-return-type-to-u_int32_t.patch
6147efd2eee5af5e734896823c2d1a3d 0003-ldso-support-RTLD_NOLOAD.patch
3e151ae3d3613dff9296d166aca3a800 0001-libdl-rudimentary-locking-for-dlopen-dlsym-dlclose.patch
3f87dc1f171493f5fde3bf4ae7180b8a uclibcconfig.x86
be0a43796e418d2733d91f9888d213c3 uclibcconfig.x86_64
3f87dc1f171493f5fde3bf4ae7180b8a uclibcconfig.i486
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment