summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJari Vetoniemi <mailroxas@gmail.com>2018-03-10 17:20:28 +0200
committerJari Vetoniemi <mailroxas@gmail.com>2018-03-10 17:20:28 +0200
commitb8be671580f22479d534e188aec9c81a01a3d5f8 (patch)
treefdc4ab3b4f78a6378b302bc33c9740feb41a1b40
parentdcc9c06d34aff4853a594dc4029b7594d3f20d1e (diff)
linker: Refactor glibc dlopen hacks
Allows us to return "valid" pointer when bionic program calls dlopen.
-rw-r--r--src/linker/dlfcn.c16
-rw-r--r--src/linker/linker.c17
-rw-r--r--src/linker/linker.h3
3 files changed, 17 insertions, 19 deletions
diff --git a/src/linker/dlfcn.c b/src/linker/dlfcn.c
index 38fc215..22d212a 100644
--- a/src/linker/dlfcn.c
+++ b/src/linker/dlfcn.c
@@ -67,10 +67,11 @@ void *bionic_dlopen(const char *filename, int flag)
verbose("%s (%d)", filename, flag);
soinfo *ret;
pthread_mutex_lock(&apkenv_dl_lock);
- ret = apkenv_find_library(filename);
+ ret = apkenv_find_library(filename, false);
if (unlikely(ret == NULL)) {
- set_dlerror(DL_ERR_CANNOT_LOAD_LIBRARY);
+ if (!(ret = dlopen(filename, flag)))
+ set_dlerror(DL_ERR_CANNOT_LOAD_LIBRARY);
} else {
apkenv_call_constructors_recursive(ret);
ret->refcount++;
@@ -102,12 +103,6 @@ void *bionic_dlsym(void *handle, const char *symbol)
pthread_mutex_lock(&apkenv_dl_lock);
-#if 0
- if(unlikely(handle == 0)) {
- set_dlerror(DL_ERR_INVALID_LIBRARY_HANDLE);
- goto err;
- }
-#endif
if(unlikely(symbol == 0)) {
set_dlerror(DL_ERR_BAD_SYMBOL_NAME);
goto err;
@@ -127,6 +122,11 @@ void *bionic_dlsym(void *handle, const char *symbol)
}
}
+ if(unlikely(handle == 0)) {
+ set_dlerror(DL_ERR_INVALID_LIBRARY_HANDLE);
+ goto err;
+ }
+
if(handle == RTLD_DEFAULT) {
sym = apkenv_lookup(symbol, &found, NULL);
} else if(handle == RTLD_NEXT) {
diff --git a/src/linker/linker.c b/src/linker/linker.c
index e72b9aa..12a3521 100644
--- a/src/linker/linker.c
+++ b/src/linker/linker.c
@@ -1121,7 +1121,7 @@ get_wr_offset(int fd, const char *name, Elf32_Ehdr *ehdr)
#endif
static soinfo *
-apkenv_load_library(const char *name)
+apkenv_load_library(const char *name, const bool try_glibc)
{
char fullpath[512];
int fd = apkenv_open_library(name, fullpath);
@@ -1133,14 +1133,11 @@ apkenv_load_library(const char *name)
Elf32_Ehdr *hdr;
if(fd == -1) {
- if (dlopen(name, RTLD_NOW | RTLD_GLOBAL)) {
+ if (try_glibc && dlopen(name, RTLD_NOW | RTLD_GLOBAL)) {
DEBUG("Loaded %s with glibc dlopen\n", name);
return NULL;
}
-#if !LINKER_DEBUG
- if (!is_lib_optional(name))
-#endif
- DL_ERR("Library '%s' not found", name);
+ DL_ERR("Bionic library '%s' not found", name);
return NULL;
}
@@ -1245,7 +1242,7 @@ apkenv_init_library(soinfo *si)
return si;
}
-soinfo *apkenv_find_library(const char *name)
+soinfo *apkenv_find_library(const char *name, const bool try_glibc)
{
soinfo *si;
const char *bname;
@@ -1274,7 +1271,7 @@ soinfo *apkenv_find_library(const char *name)
}
TRACE("[ %5d '%s' has not been loaded yet. Locating...]\n", apkenv_pid, name);
- si = apkenv_load_library(name);
+ si = apkenv_load_library(name, try_glibc);
if(si == NULL)
return NULL;
return apkenv_init_library(si);
@@ -2055,7 +2052,7 @@ static int apkenv_link_image(soinfo *si, unsigned wr_offset)
int i;
memset(apkenv_preloads, 0, sizeof(apkenv_preloads));
for(i = 0; apkenv_ldpreload_names[i] != NULL; i++) {
- soinfo *lsi = apkenv_find_library(apkenv_ldpreload_names[i]);
+ soinfo *lsi = apkenv_find_library(apkenv_ldpreload_names[i], true);
if(lsi == 0) {
apkenv_strlcpy(apkenv_tmp_err_buf, apkenv_linker_get_error(), sizeof(apkenv_tmp_err_buf));
DL_ERR("%5d could not load needed library '%s' for '%s' (%s)",
@@ -2072,7 +2069,7 @@ static int apkenv_link_image(soinfo *si, unsigned wr_offset)
DEBUG("%5d %s needs %s\n", apkenv_pid, si->name, si->strtab + d[1]);
soinfo *lsi = NULL;
// if (get_builtin_lib_handle(si->strtab + d[1]) == NULL)
- lsi = apkenv_find_library(si->strtab + d[1]);
+ lsi = apkenv_find_library(si->strtab + d[1], true);
if(lsi == 0) {
/**
* XXX Dirty Hack Alarm --thp XXX
diff --git a/src/linker/linker.h b/src/linker/linker.h
index 13d9bff..6b1924b 100644
--- a/src/linker/linker.h
+++ b/src/linker/linker.h
@@ -33,6 +33,7 @@
#include <sys/types.h>
#include <elf.h>
#include <link.h>
+#include <stdbool.h>
#undef PAGE_MASK
#undef PAGE_SIZE
@@ -204,7 +205,7 @@ extern soinfo apkenv_libdl_info;
#define DT_PREINIT_ARRAYSZ 33
#endif
-soinfo *apkenv_find_library(const char *name);
+soinfo *apkenv_find_library(const char *name, const bool try_glibc);
unsigned apkenv_unload_library(soinfo *si);
Elf32_Sym *apkenv_lookup_in_library(soinfo *si, const char *name);
Elf32_Sym *apkenv_lookup(const char *name, soinfo **found, soinfo *start);