summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/linker/linker.c12
-rw-r--r--src/wrapper/wrapper.c22
-rw-r--r--src/wrapper/wrapper.h3
3 files changed, 29 insertions, 8 deletions
diff --git a/src/linker/linker.c b/src/linker/linker.c
index b5b782d..f91316c 100644
--- a/src/linker/linker.c
+++ b/src/linker/linker.c
@@ -1271,10 +1271,16 @@ soinfo *apkenv_find_library(const char *name, const bool try_glibc)
}
TRACE("[ %5d '%s' has not been loaded yet. Locating...]\n", apkenv_pid, name);
- si = apkenv_load_library(name, try_glibc);
- if(si == NULL)
+ if (!(si = apkenv_load_library(name, try_glibc)) || !(si = apkenv_init_library(si)))
return NULL;
- return apkenv_init_library(si);
+
+ if (!strstr(bname, "libstdc++.so")) {
+ Elf32_Sym *sym = apkenv_lookup_in_library(si, "__cxa_demangle");
+ if (sym && ELF32_ST_BIND(sym->st_info) == STB_GLOBAL && sym->st_shndx != 0)
+ wrapper_set_cpp_demangler((void*)(intptr_t)(sym->st_value + si->base));
+ }
+
+ return si;
}
/* TODO:
diff --git a/src/wrapper/wrapper.c b/src/wrapper/wrapper.c
index 2d61519..51d17a6 100644
--- a/src/wrapper/wrapper.c
+++ b/src/wrapper/wrapper.c
@@ -2,11 +2,10 @@
#include <stdio.h>
#include <stdarg.h>
#include <stdbool.h>
-#include <stdint.h>
#include <stddef.h>
+#include <stdint.h>
#include <stdlib.h>
#include <string.h>
-#include <dlfcn.h>
#include <assert.h>
#include <sys/mman.h>
#include "verbose.h"
@@ -61,17 +60,33 @@ trace(const char *const symbol)
char *demangled;
static __thread char *data;
static __thread size_t size;
+ static __thread bool skip_trace;
+
+ // Avoid infinite recursion and tracing calls made by __cxa_demangle.fun
+ if (skip_trace)
+ return;
+
+ skip_trace = true;
if ((demangled = __cxa_demangle.fun(symbol, data, &size, &status))) {
data = (data != demangled ? demangled : data);
verbose("trace: %s", demangled);
return;
}
+ skip_trace = false;
}
verbose("trace: %s", symbol);
}
#endif
+void
+wrapper_set_cpp_demangler(void *function)
+{
+#ifdef WRAPPER_TRACE
+ __cxa_demangle.ptr = function;
+#endif
+}
+
void*
wrapper_create(const char *const symbol, void *function)
{
@@ -83,9 +98,6 @@ wrapper_create(const char *const symbol, void *function)
}
#ifdef WRAPPER_TRACE
- if (!__cxa_demangle.ptr)
- __cxa_demangle.ptr = dlsym(RTLD_DEFAULT, "__cxa_demangle");
-
const size_t sz = &wrapper_end - &wrapper_start;
unsigned char *fun = mmap(NULL, sz, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
assert(fun != MAP_FAILED);
diff --git a/src/wrapper/wrapper.h b/src/wrapper/wrapper.h
index c75ef33..c28c71e 100644
--- a/src/wrapper/wrapper.h
+++ b/src/wrapper/wrapper.h
@@ -2,3 +2,6 @@
void*
wrapper_create(const char *const symbol, void *function);
+
+void
+wrapper_set_cpp_demangler(void *function);