From: Vyacheslav Cherkashin Date: Wed, 27 Mar 2019 13:00:43 +0000 (+0300) Subject: Fix libdl library internal implementation X-Git-Tag: accepted/tizen/5.5/unified/20191031.014931^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fheads%2Ftizen_5.5_tv;p=platform%2Fcore%2Fsystem%2Fswap-probe.git Fix libdl library internal implementation Internal calls to __libc_dl* of libc library do not match the API of the libdl library so we use the libdl library to implement the internal::dl* API. Change-Id: I2954df0bdae2132408a78c337f38ffbbf778ac18 Signed-off-by: Vyacheslav Cherkashin --- diff --git a/src/core/internal_libdl.cpp b/src/core/internal_libdl.cpp index 74e9d9d..e4b1865 100644 --- a/src/core/internal_libdl.cpp +++ b/src/core/internal_libdl.cpp @@ -1,4 +1,7 @@ #include "internal_libdl.h" +#include "compiler.h" +#include "common.h" +#include "log.h" // private libc interface #define __RTLD_DLOPEN 0x80000000 @@ -9,19 +12,60 @@ extern "C" int __libc_dlclose(void *handle); namespace __swap { namespace internal { +static void *g_libdl_handle; + +static void *(*g_dlopen_ptr)(const char *filename, int flag); +static void *(*g_dlsym_ptr)(void *handle, const char *symbol); +static int (*g_dlclose_ptr)(void *handle); + +static bool dl_is_init() +{ + return g_dlopen_ptr && g_dlsym_ptr && g_dlclose_ptr; +} + +static void dl_init() +{ + if (LIKELY(dl_is_init())) + return; + + // The 'libdl' library can be loaded multiple times (in a multithreaded application) + // but that's fine because we're not going to unload it. + if (!g_libdl_handle) { + // FIXME: This path can be different on other platforms + g_libdl_handle = __libc_dlopen_mode("/lib/libdl.so.2", __RTLD_DLOPEN | RTLD_NOW); + if (!g_libdl_handle) { + LOGE("Not found libdl library"); + die(); + } + } + + g_dlopen_ptr = (void *(*)(const char *, int))__libc_dlsym(g_libdl_handle, "dlopen"); + g_dlsym_ptr = (void *(*)(void *, const char *))__libc_dlsym(g_libdl_handle, "dlsym"); + g_dlclose_ptr = (int (*)(void *))__libc_dlsym(g_libdl_handle, "dlclose"); + + if (!dl_is_init()) { + LOGE("Cannot init libdl module: dlopen=%p dlsym=%p dlclose=%p", + g_dlopen_ptr, g_dlsym_ptr, g_dlclose_ptr); + die(); + } +} + void *dlopen(const char *filename, int flag) noexcept { - return __libc_dlopen_mode(filename, __RTLD_DLOPEN | flag); + dl_init(); + return g_dlopen_ptr(filename, flag); } void *dlsym(void *handle, const char *symbol) noexcept { - return __libc_dlsym(handle, symbol); + dl_init(); + return g_dlsym_ptr(handle, symbol); } int dlclose(void *handle) noexcept { - return __libc_dlclose(handle); + dl_init(); + return g_dlclose_ptr(handle); } } // namespace internal