diff options
Diffstat (limited to 'src/wrapper')
-rw-r--r-- | src/wrapper/wrapper.c | 112 |
1 files changed, 59 insertions, 53 deletions
diff --git a/src/wrapper/wrapper.c b/src/wrapper/wrapper.c index 51d17a6..d78f1a4 100644 --- a/src/wrapper/wrapper.c +++ b/src/wrapper/wrapper.c @@ -11,9 +11,14 @@ #include "verbose.h" #include <pthread.h> +static __thread bool skip_trace; + void verbose_log(const char *fmt, ...) { + if (skip_trace) + return; + static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_lock(&mutex); fprintf(stderr, "%lu: ", pthread_self()); @@ -26,56 +31,57 @@ verbose_log(const char *fmt, ...) } #ifdef VERBOSE_FUNCTIONS -# ifdef ANDROID_X86_LINKER +# ifdef ANDROID_X86_LINKER __asm__( - "wrapper_start: nop\n" - "wrapper_symbol: pushl $0xFAFBFCFD\n" - "wrapper_trace: movl $0xFAFBFCFD, %eax\ncall *%eax\npop %eax\n" - "wrapper_call: movl $0xFAFBFCFD, %eax\njmp *%eax\n" - "wrapper_end: nop\n" + "wrapper_start: nop\n" + "wrapper_symbol: pushl $0xFAFBFCFD\n" + "wrapper_trace: movl $0xFAFBFCFD, %eax\ncall *%eax\npop %eax\n" + "wrapper_call: movl $0xFAFBFCFD, %eax\njmp *%eax\n" + "wrapper_end: nop\n" ); -# define WRAPPER_TRACE -# else -# warning "no wrapper asm for this platform, function tracing is not available" -# endif +# define WRAPPER_TRACE +# else +# warning "no wrapper asm for this platform, function tracing is not available" +# endif #endif #ifdef WRAPPER_TRACE extern char wrapper_start, wrapper_symbol, wrapper_trace, wrapper_call, wrapper_end; static union { - void *ptr; - char* (*fun)(const char *mangled_name, char *output_buffer, size_t *length, int *status); + void *ptr; + char* (*fun)(const char *mangled_name, char *output_buffer, size_t *length, int *status); } __cxa_demangle; static void trace(const char *const symbol) { - assert(symbol); - - if (__cxa_demangle.ptr) { - // >If output_buffer is not long enough, it is expanded using realloc - // Holy fuck gcc what the fuck? Guess we don't use stack then, thanks - int status; - 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); + assert(symbol); + + if (__cxa_demangle.ptr) { + // >If output_buffer is not long enough, it is expanded using realloc + // Holy fuck gcc what the fuck? Guess we don't use stack then, thanks + int status; + char *demangled; + static __thread char *data; + static __thread size_t size; + + // Avoid infinite recursion and tracing calls made by __cxa_demangle.fun + if (skip_trace) + return; + + skip_trace = true; + demangled = __cxa_demangle.fun(symbol, data, &size, &status); + skip_trace = false; + + if (demangled) { + data = (data != demangled ? demangled : data); + verbose("trace: %s", demangled); + return; + } + } + + verbose("trace: %s", symbol); } #endif @@ -83,35 +89,35 @@ void wrapper_set_cpp_demangler(void *function) { #ifdef WRAPPER_TRACE - __cxa_demangle.ptr = function; + __cxa_demangle.ptr = function; #endif } void* wrapper_create(const char *const symbol, void *function) { - assert(symbol); + assert(symbol); - if (!function) { - verbose_log("FIXME: unimplemented symbol: %s", symbol); - return NULL; - } + if (!function) { + verbose_log("FIXME: unimplemented symbol: %s", symbol); + return NULL; + } #ifdef WRAPPER_TRACE - 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); - memcpy(fun, &wrapper_start, sz); + 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); + memcpy(fun, &wrapper_start, sz); #ifdef ANDROID_X86_LINKER - memcpy(fun + (&wrapper_symbol - &wrapper_start) + 1, &symbol, sizeof(symbol)); - memcpy(fun + (&wrapper_trace - &wrapper_start) + 1, (uintptr_t[]){ (uintptr_t)trace }, sizeof(uintptr_t)); - memcpy(fun + (&wrapper_call - &wrapper_start) + 1, &function, sizeof(function)); + memcpy(fun + (&wrapper_symbol - &wrapper_start) + 1, &symbol, sizeof(symbol)); + memcpy(fun + (&wrapper_trace - &wrapper_start) + 1, (uintptr_t[]){ (uintptr_t)trace }, sizeof(uintptr_t)); + memcpy(fun + (&wrapper_call - &wrapper_start) + 1, &function, sizeof(function)); #else # error "you forgot to implement the pointer setups for your asm platform" #endif - mprotect(fun, sz, PROT_READ | PROT_EXEC); - return fun; + mprotect(fun, sz, PROT_READ | PROT_EXEC); + return fun; #else - return function; + return function; #endif } |