summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Lillqvist <tml@iki.fi>2012-09-13 13:02:53 +0300
committerTor Lillqvist <tml@iki.fi>2012-09-24 17:32:03 +0300
commitbc9a4133af3cf49495f616bf3eff9d56e55ed214 (patch)
tree3f5e0fa5536f0dba74a316ad251ed227284fb489
parentd08fa24320cd4c6ad16e88eaa2f7c2d03ac4bbe1 (diff)
Further hacks to use an add-on Bionic linker copy, unfinished private/tml/android-use-bionic-linker-copy
Change-Id: I7c7e06ad172fc95912958c1f46baa74071f5d613
-rw-r--r--android/Bootstrap/src/org/libreoffice/android/Bootstrap.java2
-rw-r--r--sal/android/bionic/linker/dlfcn.c74
-rw-r--r--sal/android/bionic/linker/linker.cxx10
-rw-r--r--sal/android/bionic/linker/linker.h2
-rw-r--r--sal/android/bionic/linker/linker_debug.h3
-rw-r--r--sal/android/lo-bootstrap.c99
6 files changed, 133 insertions, 57 deletions
diff --git a/android/Bootstrap/src/org/libreoffice/android/Bootstrap.java b/android/Bootstrap/src/org/libreoffice/android/Bootstrap.java
index b97adfb6261a..db8745b8863a 100644
--- a/android/Bootstrap/src/org/libreoffice/android/Bootstrap.java
+++ b/android/Bootstrap/src/org/libreoffice/android/Bootstrap.java
@@ -292,8 +292,6 @@ public class Bootstrap extends NativeActivity
// time by the package manager.
static {
System.loadLibrary("lo-bootstrap");
- System.loadLibrary("gnustl_shared");
- System.loadLibrary("libotouchlo");
}
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sal/android/bionic/linker/dlfcn.c b/sal/android/bionic/linker/dlfcn.c
index a476092daec1..04eb8f7ffa3b 100644
--- a/sal/android/bionic/linker/dlfcn.c
+++ b/sal/android/bionic/linker/dlfcn.c
@@ -19,8 +19,6 @@
#include "linker.h"
#include "linker_format.h"
-/* This file hijacks the symbols stubbed out in libdl.so. */
-
#define DL_SUCCESS 0
#define DL_ERR_CANNOT_LOAD_LIBRARY 1
#define DL_ERR_INVALID_LIBRARY_HANDLE 2
@@ -169,24 +167,45 @@ int __lo_dlclose(void* handle) {
return result;
}
-/* Dummy replacement for the libdl_info in the real system dlfcn.c. */
+// 0000000000 11111111112 222222222 3
+// 0123456789 01234567890 123456789 0
+#define LO_LIBLO_BOOTSTRAP_STRTAB \
+ "lo_dlopen\0lo_dlclose\0lo_dlsym\0lo_dladdr\0"
void __lo_dummy_foo(void)
{
}
-#define ANDROID_LIBDL_STRTAB \
- "__lo_dummy_foo\0"
+/* The wrappers in lo-bootstrap.c */
+extern void *lo_dlopen(const char *path, int flags);
+extern void *lo_dlsym(void *handle, const char *symbol);
+extern int lo_dlclose(void *handle);
+extern int lo_dladdr(void *addr, Dl_info *info);
-static Elf32_Sym libdl_symtab[] = {
- // total length of libdl_info.strtab, including trailing 0
+static Elf32_Sym liblo_bootstrap_symtab[] = {
+ // total length of liblo_bootstrap_info.strtab, including trailing 0
// This is actually the the STH_UNDEF entry. Technically, it's
// supposed to have st_name == 0, but instead, it points to an index
// in the strtab with a \0 to make iterating through the symtab easier.
- { st_name: sizeof(ANDROID_LIBDL_STRTAB) - 1,
+ { st_name: sizeof(LO_LIBLO_BOOTSTRAP_STRTAB) - 1,
+ },
+ { st_name: 0, // starting index of the name in liblo_bootstrap_info.strtab
+ st_value: (Elf32_Addr) &lo_dlopen,
+ st_info: STB_GLOBAL << 4,
+ st_shndx: 1,
},
- { st_name: 0, // starting index of the name in libdl_info.strtab
- st_value: (Elf32_Addr) &__lo_dummy_foo,
+ { st_name: 10,
+ st_value: (Elf32_Addr) &lo_dlclose,
+ st_info: STB_GLOBAL << 4,
+ st_shndx: 1,
+ },
+ { st_name: 21,
+ st_value: (Elf32_Addr) &lo_dlsym,
+ st_info: STB_GLOBAL << 4,
+ st_shndx: 1,
+ },
+ { st_name: 30,
+ st_value: (Elf32_Addr) &lo_dladdr,
st_info: STB_GLOBAL << 4,
st_shndx: 1,
},
@@ -194,35 +213,32 @@ static Elf32_Sym libdl_symtab[] = {
/* Fake out a hash table with a single bucket.
* A search of the hash table will look through
- * libdl_symtab starting with index [1], then
- * use libdl_chains to find the next index to
- * look at. libdl_chains should be set up to
- * walk through every element in libdl_symtab,
+ * liblo_bootstrap_symtab starting with index [1], then
+ * use liblo_bootstrap_chains to find the next index to
+ * look at. liblo_bootstrap_chains should be set up to
+ * walk through every element in liblo_bootstrap_symtab,
* and then end with 0 (sentinel value).
*
- * I.e., libdl_chains should look like
+ * I.e., liblo_bootstrap_chains should look like
* { 0, 2, 3, ... N, 0 } where N is the number
- * of actual symbols, or nelems(libdl_symtab)-1
- * (since the first element of libdl_symtab is not
+ * of actual symbols, or nelems(liblo_bootstrap_symtab)-1
+ * (since the first element of liblo_bootstrap_symtab is not
* a real symbol).
*
* (see _elf_lookup())
- *
- * Note that adding any new symbols here requires
- * stubbing them out in libdl.
*/
-static unsigned libdl_buckets[1] = { 1 };
-static unsigned libdl_chains[3] = { 0, 2, 0 };
+static unsigned liblo_bootstrap_buckets[1] = { 1 };
+static unsigned liblo_bootstrap_chains[5] = { 0, 2, 3, 4, 0 };
-soinfo libdl_info = {
- name: "lo-dummy-libdl.so",
+soinfo liblo_bootstrap_info = {
+ name: "liblo-bootstrap.so",
flags: FLAG_LINKED,
- strtab: ANDROID_LIBDL_STRTAB,
- symtab: libdl_symtab,
+ strtab: LO_LIBLO_BOOTSTRAP_STRTAB,
+ symtab: liblo_bootstrap_symtab,
nbucket: 1,
- nchain: 3,
- bucket: libdl_buckets,
- chain: libdl_chains,
+ nchain: 5,
+ bucket: liblo_bootstrap_buckets,
+ chain: liblo_bootstrap_chains,
};
diff --git a/sal/android/bionic/linker/linker.cxx b/sal/android/bionic/linker/linker.cxx
index d43eedbf9be7..edcbf5e70d21 100644
--- a/sal/android/bionic/linker/linker.cxx
+++ b/sal/android/bionic/linker/linker.cxx
@@ -79,10 +79,10 @@ static int soinfo_link_image(soinfo *si);
static int socount = 0;
static soinfo sopool[SO_MAX];
static soinfo *freelist = NULL;
-static soinfo *solist = &libdl_info;
-static soinfo *sonext = &libdl_info;
+static soinfo *solist = &liblo_bootstrap_info;
+static soinfo *sonext = &liblo_bootstrap_info;
#if ALLOW_SYMBOLS_FROM_MAIN
-static soinfo *somain; /* main process, always the one after libdl_info */
+static soinfo *somain; /* main process, always the one after liblo_bootstrap_info */
#endif
@@ -90,7 +90,7 @@ static char ldpaths_buf[LDPATH_BUFSIZE];
static const char *ldpaths[LDPATH_MAX + 1];
#if LINKER_DEBUG
-int debug_verbosity;
+int debug_verbosity = 2;
#endif
static int pid;
@@ -300,7 +300,7 @@ static void soinfo_free(soinfo* si)
}
/* prev will never be NULL, because the first entry in solist is
- always the static libdl_info.
+ always the static liblo_bootstrap_info.
*/
prev->next = si->next;
if (si == sonext) sonext = prev;
diff --git a/sal/android/bionic/linker/linker.h b/sal/android/bionic/linker/linker.h
index 59c9530d6429..f826746ea027 100644
--- a/sal/android/bionic/linker/linker.h
+++ b/sal/android/bionic/linker/linker.h
@@ -169,7 +169,7 @@ struct soinfo
};
-extern soinfo libdl_info;
+extern soinfo liblo_bootstrap_info;
#include <asm/elf.h>
diff --git a/sal/android/bionic/linker/linker_debug.h b/sal/android/bionic/linker/linker_debug.h
index 48a7abf0d2c1..49919931a37e 100644
--- a/sal/android/bionic/linker/linker_debug.h
+++ b/sal/android/bionic/linker/linker_debug.h
@@ -33,6 +33,9 @@
#ifndef LINKER_DEBUG
#error LINKER_DEBUG should be defined to either 1 or 0 in Android.mk
+#else
+#undef LINKER_DEBUG
+#define LINKER_DEBUG 1
#endif
/* set LINKER_DEBUG_TO_LOG to 1 to send the logs to logcat,
diff --git a/sal/android/lo-bootstrap.c b/sal/android/lo-bootstrap.c
index 4703b900a3f9..02229a153b66 100644
--- a/sal/android/lo-bootstrap.c
+++ b/sal/android/lo-bootstrap.c
@@ -69,6 +69,9 @@
#define MAX(a,b) ((a) > (b) ? (a) : (b))
+/* The functions from our tweaked copy of the run-time linker, in
+ * sal/android/bionic/linker
+ */
extern void *__lo_dlopen(const char *path, int flags);
extern const char *__lo_dlerror(void);
extern void *__lo_dlsym(void *handle, const char *symbol);
@@ -76,12 +79,6 @@ extern int __lo_dlclose(void *handle);
extern int __lo_dladdr(void *addr, Dl_info *info);
extern void __lo_linker_init(void);
-#define dlopen __lo_dlopen
-#define dlerror __lo_dlerror
-#define dlsym __lo_dlsym
-#define dlclose __lo_dlclose
-#define dladdr __lo_dladdr
-
struct engine {
int dummy;
};
@@ -869,6 +866,13 @@ lo_dlopen(const char *library)
struct timeval tv0, tv1, tvdiff;
+ FILE *maps;
+ char line[200];
+
+ /* libdl.so is special */
+ if (strcmp(library, "libdl.so") == 0)
+ return (void *) 42; /* ??? */
+
rover = loaded_libraries;
while (rover != NULL &&
strcmp(rover->name, library) != 0)
@@ -923,16 +927,48 @@ lo_dlopen(const char *library)
}
free_ptrarray((void **) needed);
+ /* Find out if the real system run-time linker has loaded it */
+ maps = fopen("/proc/self/maps", "r");
+ if (maps == NULL) {
+ LOGE("lo_dladdr: Could not open /proc/self/maps: %s", strerror(errno));
+ return NULL;
+ }
+
+ found = 0;
+ while (fgets(line, sizeof(line), maps) != NULL &&
+ line[strlen(line)-1] == '\n') {
+ char file[sizeof(line)];
+ file[0] = '\0';
+ if (sscanf(line, "%*x-%*x %*s %*x %*x:%*x %*d %[^\n]", file) == 1) {
+ if (strcmp(file, full_name) == 0) {
+ found = 1;
+ break;
+ }
+ }
+ }
+ fclose(maps);
+
gettimeofday(&tv0, NULL);
- p = dlopen(full_name, RTLD_LOCAL);
+ if (found) {
+ /* It is already mapped, but it wasn't in our loaded_libraries list,
+ * presumably it's the system run-time linker that has loaded it.
+ */
+ LOGI("lo_dlopen: Using system dlopen()");
+ p = dlopen(full_name, RTLD_LOCAL);
+ } else {
+ /* Call our tweaked copy of the run-time linker to load it. */
+ LOGI("lo_dlopen: Using our tweaked__lo_dlopen()");
+ p = __lo_dlopen(full_name, RTLD_LOCAL);
+ }
gettimeofday(&tv1, NULL);
timersub(&tv1, &tv0, &tvdiff);
- LOGI("dlopen(%s) = %p, %ld.%03lds",
+ LOGI("%s(%s) = %p, %ld.%03lds",
+ (found ? "dlopen" : "__lo_dlopen"),
full_name, p,
(long) tvdiff.tv_sec, (long) tvdiff.tv_usec / 1000);
free(full_name);
if (p == NULL)
- LOGE("lo_dlopen: Error from dlopen(%s): %s", library, dlerror());
+ LOGE("lo_dlopen: Error from __lo_dlopen(%s): %s", library, (found ? dlerror() : __lo_dlerror()));
new_loaded_lib = malloc(sizeof(*new_loaded_lib));
new_loaded_lib->name = strdup(library);
@@ -949,10 +985,20 @@ void *
lo_dlsym(void *handle,
const char *symbol)
{
- void *p = dlsym(handle, symbol);
- /* LOGI("dlsym(%p, %s) = %p", handle, symbol, p); */
+ int used_system_dlsym = 0;
+ void *p;
+
+ p = __lo_dlsym(handle, symbol);
+ LOGI("__lo_dlsym(%p, %s) = %p", handle, symbol, p);
+
+ if (p == NULL) {
+ used_system_dlsym = 1;
+ p = dlsym(handle, symbol);
+ LOGI("dlsym(%p, %s) = %p", handle, symbol, p);
+ }
+
if (p == NULL)
- LOGE("lo_dlsym: %s", dlerror());
+ LOGE("lo_dlsym: %s", (used_system_dlsym ? dlerror() : __lo_dlerror()));
return p;
}
@@ -966,12 +1012,17 @@ lo_dladdr(void *addr,
int result;
int found;
- result = dladdr(addr, info);
+ result = __lo_dladdr(addr, info);
+ LOGI("__lo_dladdr(%p) = 0", addr);
+
if (result == 0) {
- /* LOGI("dladdr(%p) = 0", addr); */
- return 0;
+ result = dladdr(addr, info);
+ LOGI("dladdr(%p) = 0", addr);
}
+ if (result == 0)
+ return 0;
+
maps = fopen("/proc/self/maps", "r");
if (maps == NULL) {
LOGE("lo_dladdr: Could not open /proc/self/maps: %s", strerror(errno));
@@ -1368,13 +1419,21 @@ patch(const char *symbol,
* containing lo_main() already, libgnustl_shared.so will have
* been brought in, too.
*/
- libgnustl_shared = dlopen("libgnustl_shared.so", RTLD_LOCAL);
+ libgnustl_shared = __lo_dlopen("libgnustl_shared.so", RTLD_LOCAL);
+
+ if (libgnustl_shared == NULL)
+ libgnustl_shared = dlopen("libgnustl_shared.so", RTLD_LOCAL);
+
if (libgnustl_shared == NULL) {
LOGF("android_main: libgnustl_shared.so not mapped??");
exit(0);
}
- code = dlsym(libgnustl_shared, symbol);
+ code = __lo_dlsym(libgnustl_shared, symbol);
+
+ if (code == NULL)
+ code = dlsym(libgnustl_shared, symbol);
+
if (code == NULL) {
LOGF("android_main: %s not found!?", plaintext);
exit(0);
@@ -1586,7 +1645,7 @@ Java_org_libreoffice_android_Bootstrap_initVCL(JNIEnv* env,
/* This obviously should be called only after libvcllo.so has been loaded */
- InitVCLWrapper = dlsym(RTLD_DEFAULT, "InitVCLWrapper");
+ InitVCLWrapper = __lo_dlsym(RTLD_DEFAULT, "InitVCLWrapper");
if (InitVCLWrapper == NULL) {
LOGE("InitVCL: InitVCLWrapper not found");
return;
@@ -1626,7 +1685,7 @@ Java_org_libreoffice_android_Bootstrap_setCommandArgs(JNIEnv* env,
c_argv[0] = new_argv0;
}
- osl_setCommandArgs = dlsym(RTLD_DEFAULT, "osl_setCommandArgs");
+ osl_setCommandArgs = __lo_dlsym(RTLD_DEFAULT, "osl_setCommandArgs");
if (osl_setCommandArgs == NULL) {
LOGE("setCommandArgs: osl_setCommandArgs not found");
return;
@@ -1644,7 +1703,7 @@ Java_org_libreoffice_android_Bootstrap_createWindowFoo(JNIEnv* env,
(void) clazz;
lo_dlopen("libvcllo.so");
- createWindowFoo = dlsym(RTLD_DEFAULT, "createWindowFoo");
+ createWindowFoo = __lo_dlsym(RTLD_DEFAULT, "createWindowFoo");
if (createWindowFoo == NULL) {
LOGE("createWindowFoo: createWindowFoo not found");
return 0;