about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/dynablock.c11
-rw-r--r--src/dynarec/dynarec.c11
-rw-r--r--src/elfs/elfloader.c9
-rw-r--r--src/emu/x64emu_private.h9
-rw-r--r--src/emu/x64run_private.c21
-rw-r--r--src/include/debug.h3
-rw-r--r--src/librarian/library.c2
-rw-r--r--src/library_list.h51
-rw-r--r--src/libtools/signals.c12
-rw-r--r--src/libtools/threads.c21
-rw-r--r--src/mallochook.c10
-rw-r--r--src/tools/bridge.c1
-rw-r--r--src/tools/rcfile.c9
-rw-r--r--src/wrapped/generated/functions_list.txt2
-rw-r--r--src/wrapped/generated/wrappedlibctypes.h2
-rwxr-xr-xsrc/wrapped/wrappedandroidshmem.c18
-rwxr-xr-xsrc/wrapped/wrappedandroidshmem_private.h8
-rw-r--r--src/wrapped/wrappedfreetype.c8
-rw-r--r--src/wrapped/wrappedgnutls.c8
-rw-r--r--src/wrapped/wrappedlibc.c119
-rw-r--r--src/wrapped/wrappedlibc_private.h13
-rw-r--r--src/wrapped/wrappedlibcups.c9
-rw-r--r--src/wrapped/wrappedlibdl.c9
-rw-r--r--src/wrapped/wrappedlibm.c9
-rw-r--r--src/wrapped/wrappedmpg123.c8
25 files changed, 340 insertions, 43 deletions
diff --git a/src/dynarec/dynablock.c b/src/dynarec/dynablock.c
index 114479bc..d95fb829 100644
--- a/src/dynarec/dynablock.c
+++ b/src/dynarec/dynablock.c
@@ -171,11 +171,16 @@ dynablock_t *AddNewDynablock(uintptr_t addr)
 }
 
 //TODO: move this to dynrec_arm.c and track allocated structure to avoid memory leak
-static __thread struct __jmp_buf_tag dynarec_jmpbuf;
+static __thread JUMPBUFF dynarec_jmpbuf;
+#ifdef ANDROID
+#define DYN_JMPBUF dynarec_jmpbuf
+#else
+#define DYN_JMPBUF &dynarec_jmpbuf
+#endif
 
 void cancelFillBlock()
 {
-    longjmp(&dynarec_jmpbuf, 1);
+    longjmp(DYN_JMPBUF, 1);
 }
 
 /* 
@@ -208,7 +213,7 @@ static dynablock_t* internalDBGetBlock(x64emu_t* emu, uintptr_t addr, uintptr_t
 
     // fill the block
     block->x64_addr = (void*)addr;
-    if(sigsetjmp(&dynarec_jmpbuf, 1)) {
+    if(sigsetjmp(DYN_JMPBUF, 1)) {
         printf_log(LOG_INFO, "FillBlock at %p triggered a segfault, canceling\n", (void*)addr);
         FreeDynablock(block, 0);
         if(need_lock)
diff --git a/src/dynarec/dynarec.c b/src/dynarec/dynarec.c
index 77ca980c..b832b1e5 100644
--- a/src/dynarec/dynarec.c
+++ b/src/dynarec/dynarec.c
@@ -103,16 +103,21 @@ void DynaCall(x64emu_t* emu, uintptr_t addr)
 void DynaRun(x64emu_t* emu)
 {
     // prepare setjump for signal handling
-    struct __jmp_buf_tag jmpbuf[1] = {0};
+    JUMPBUFF jmpbuf[1] = {0};
     int skip = 0;
-    struct __jmp_buf_tag *old_jmpbuf = emu->jmpbuf;
+    JUMPBUFF *old_jmpbuf = emu->jmpbuf;
     emu->flags.jmpbuf_ready = 0;
 
     while(!(emu->quit)) {
         if(!emu->jmpbuf || (emu->flags.need_jmpbuf && emu->jmpbuf!=jmpbuf)) {
             emu->jmpbuf = jmpbuf;
             emu->flags.jmpbuf_ready = 1;
-            if((skip=sigsetjmp(emu->jmpbuf, 1))) {
+            #ifdef ANDROID
+            if((skip=sigsetjmp(*(JUMPBUFF*)emu->jmpbuf, 1))) 
+            #else
+            if((skip=sigsetjmp(emu->jmpbuf, 1))) 
+            #endif
+            {
                 printf_log(LOG_DEBUG, "Setjmp DynaRun, fs=0x%x\n", emu->segs[_FS]);
                 #ifdef DYNAREC
                 if(box64_dynarec_test) {
diff --git a/src/elfs/elfloader.c b/src/elfs/elfloader.c
index 1f6f6c65..eb571325 100644
--- a/src/elfs/elfloader.c
+++ b/src/elfs/elfloader.c
@@ -1060,6 +1060,10 @@ uintptr_t GetLastByte(elfheader_t* h)
     return (uintptr_t)h->memory/* + h->delta*/ + h->memsz;
 }
 
+#ifndef STB_GNU_UNIQUE
+#define STB_GNU_UNIQUE	10
+#endif
+
 void checkHookedSymbols(elfheader_t* h); // in mallochook.c
 void AddSymbols(lib_t *maplib, kh_mapsymbols_t* mapsymbols, kh_mapsymbols_t* weaksymbols, kh_mapsymbols_t* localsymbols, elfheader_t* h)
 {
@@ -1391,6 +1395,10 @@ void RunElfFini(elfheader_t* h, x64emu_t *emu)
     if(!h || h->fini_done || !h->init_done)
         return;
     h->fini_done = 1;
+#ifdef ANDROID
+    // TODO: Fix .fini_array on Android
+    printf_log(LOG_DEBUG, "Android does not support Fini for %s\n", ElfName(h));
+#else
     // first check fini array
     Elf64_Addr *addr = (Elf64_Addr*)(h->finiarray + h->delta);
     for (int i=h->finiarray_sz-1; i>=0; --i) {
@@ -1405,6 +1413,7 @@ void RunElfFini(elfheader_t* h, x64emu_t *emu)
     }
     h->init_done = 0;   // can be re-inited again...
     return;
+#endif
 }
 
 uintptr_t GetElfInit(elfheader_t* h)
diff --git a/src/emu/x64emu_private.h b/src/emu/x64emu_private.h
index 8076049d..25601105 100644
--- a/src/emu/x64emu_private.h
+++ b/src/emu/x64emu_private.h
@@ -44,6 +44,13 @@ typedef struct emu_flags_s {
     uint32_t    jmpbuf_ready:1;   // the jmpbuf in the emu is ok and don't need refresh
 } emu_flags_t;
 
+#ifdef ANDROID
+#include <setjmp.h>
+#define JUMPBUFF sigjmp_buf
+#else
+#define JUMPBUFF struct __jmp_buf_tag
+#endif
+
 typedef struct x64emu_s {
     // cpu
 	reg64_t     regs[16];
@@ -104,7 +111,7 @@ typedef struct x64emu_s {
     void*       stack2free; // this is the stack to free (can be NULL)
     void*       init_stack; // initial stack (owned or not)
     uint32_t    size_stack; // stack size (owned or not)
-    struct __jmp_buf_tag *jmpbuf;
+    JUMPBUFF*   jmpbuf;
 
     x64_ucontext_t *uc_link; // to handle setcontext
 
diff --git a/src/emu/x64run_private.c b/src/emu/x64run_private.c
index ffddd73a..5056ff90 100644
--- a/src/emu/x64run_private.c
+++ b/src/emu/x64run_private.c
@@ -28,6 +28,26 @@
 #define PARITY(x)   (((emu->x64emu_parity_tab[(x) / 32] >> ((x) % 32)) & 1) == 0)
 #define XOR2(x) 	(((x) ^ ((x)>>1)) & 0x1)
 
+#ifdef ANDROID
+void EXPORT my___libc_init(x64emu_t* emu, void* raw_args __unused, void (*onexit)(void) __unused, int (*main)(int, char**, char**), void const * const structors __unused)
+{
+    //TODO: register fini
+    // let's cheat and set all args...
+    SetRDX(emu, (uintptr_t)my_context->envv);
+    SetRSI(emu, (uintptr_t)my_context->argv);
+    SetRDI(emu, (uintptr_t)my_context->argc);
+
+    printf_log(LOG_DEBUG, "Transfert to main(%d, %p, %p)=>%p from __libc_init\n", my_context->argc, my_context->argv, my_context->envv, main);
+    // should call structors->preinit_array and structors->init_array!
+    // call main and finish
+    PushExit(emu);
+    R_RIP=(uintptr_t)main;
+
+    DynaRun(emu);
+
+    emu->quit = 1; // finished!
+}
+#else
 int32_t EXPORT my___libc_start_main(x64emu_t* emu, int *(main) (int, char * *, char * *), int argc, char * * ubp_av, void (*init) (void), void (*fini) (void), void (*rtld_fini) (void), void (* stack_end))
 {
     (void)argc; (void)ubp_av; (void)fini; (void)rtld_fini; (void)stack_end;
@@ -80,6 +100,7 @@ int32_t EXPORT my___libc_start_main(x64emu_t* emu, int *(main) (int, char * *, c
     }
     return (int)GetEAX(emu);
 }
+#endif
 
 const char* GetNativeName(void* p)
 {
diff --git a/src/include/debug.h b/src/include/debug.h
index 8397d6c5..9bfc5c89 100644
--- a/src/include/debug.h
+++ b/src/include/debug.h
@@ -104,14 +104,15 @@ void printf_ftrace(const char* fmt, ...);
 #endif
 
 void init_malloc_hook(void);
-extern size_t(*box_malloc_usable_size)(void*);
 #ifdef ANDROID
+extern size_t(*box_malloc_usable_size)(const void*);
 extern void*(*__libc_malloc)(size_t);
 extern void*(*__libc_realloc)(void*, size_t);
 extern void*(*__libc_calloc)(size_t, size_t);
 extern void (*__libc_free)(void*);
 extern void*(*__libc_memalign)(size_t, size_t);
 #else
+extern size_t(*box_malloc_usable_size)(void*);
 extern void* __libc_malloc(size_t);
 extern void* __libc_realloc(void*, size_t);
 extern void* __libc_calloc(size_t, size_t);
diff --git a/src/librarian/library.c b/src/librarian/library.c
index a6c355d1..c8438f1b 100644
--- a/src/librarian/library.c
+++ b/src/librarian/library.c
@@ -229,9 +229,11 @@ static void initWrappedLib(library_t *lib, box64context_t* context) {
                 break;
             }
             struct link_map real_lm;
+            #ifndef ANDROID
             if(dlinfo(lib->w.lib, RTLD_DI_LINKMAP, &real_lm)) {
                 printf_dump(LOG_DEBUG, "Failed to dlinfo lib %s\n", lib->name);
             }
+            #endif
             lm->l_addr = real_lm.l_addr;
             lm->l_name = real_lm.l_name;
             lm->l_ld = real_lm.l_ld;
diff --git a/src/library_list.h b/src/library_list.h
index 9713469e..3ff62eac 100644
--- a/src/library_list.h
+++ b/src/library_list.h
@@ -2,7 +2,6 @@
 #error Nope
 #endif
 
-GO("libc.so.6", libc)
 GO("libc.musl-x86_64.so.1", libcmusl)
 GO("libpthread.so.0", libpthread)
 GO("librt.so.1", librt)
@@ -16,8 +15,6 @@ GO("libGLX.so", libglx)
 GO("libX11.so.6", libx11)
 GO("libasound.so.2", libasound)
 GO("libasound.so", libasound)
-GO("libdl.so.2", libdl)
-GO("libm.so.6", libm)
 GO("libSDL2-2.0.so.0", sdl2)
 GO("libSDL2-2.0.so.1", sdl2)
 GO("libSDL2.so", sdl2)
@@ -41,7 +38,6 @@ GO("libvorbis.so.0", libvorbis)
 GO("libogg.so.0", libogg)
 GO("libFLAC.so.8", flac)
 //GO("libpng12.so.0", png12)
-GO("libpng16.so.16", png16)
 GO("libXxf86vm.so.1", libxxf86vm)
 GO("libXinerama.so.1", xinerama)
 GO("libXrandr.so.2", libxrandr)
@@ -152,7 +148,6 @@ GO("libpango-1.0.so", pango)
 //GO("libnm-util.so.2", libnm)
 GO("libibus-1.0.so.5", libibus)
 GO("libfontconfig.so.1", fontconfig)
-GO("libfreetype.so.6", freetype)
 GO("libharfbuzz.so.0", libharfbuzz)
 GO("libbz2.so.1", bz2)
 GO("liblzma.so.5", lzma)
@@ -174,26 +169,17 @@ GO("libtbbmalloc_proxy.so.2", tbbmallocproxy)
 GO("libtbbbind_2_5.so", tbbbind)
 GO("libtcmalloc_minimal.so.0", tcmallocminimal)
 GO("libtcmalloc_minimal.so.4", tcmallocminimal)
-GO("libmpg123.so.0", mpg123)
-GO("libgnutls.so.30", gnutls)
 GO("libpcre.so.3", libpcre)
-GO("libcups.so.2", libcups)
 GO("libvulkan.so.1", vulkan)
 GO("libvulkan.so", vulkan)
 //GO("libwayland-client.so.0", waylandclient)
 GO("libgbm.so.1", gbm)
-GO("libxml2.so.2", xml2)
-GO("libxslt.so.1", xslt)
 GO("libgomp.so.1", gomp)
 GO("libcap.so.2", cap)
-GO("libldap_r-2.4.so.2", ldapr)
-GO("liblber-2.4.so.2", lber)
 //GO("libnsl.so.1", nsl)
-//GO("liblcms2.so.2", lcms2)
 GO("libkrb5.so.3", krb5)
 GO("libgssapi_krb5.so.2", gssapikrb5)
 GO("libgssapi.so.3", gssapi)
-//GO("libtiff.so.5", libtiff)
 GO("libfuse.so.2", libfuse)
 GO("libnss3.so", nss3)
 GO("libnssutil3.so", nssutil3)
@@ -235,6 +221,43 @@ GO("libicui18n.so.67", icui18n67)
 GO("libicuuc.so.72", icuuc72)
 GO("libicui18n.so.72", icui18n72)
 
+#ifdef ANDROID
+GO("libc.so", libc)
+GO("libm.so", libm)
+GO("libdl.so", libdl)
+GO("libcups.so", libcups)
+GO("liblber-2.4.so", lber)
+GO("libldap_r-2.4.so", ldapr)
+GO("libpng16.so", png16)
+GO("libxslt.so", xslt)
+GO("libfreetype.so", freetype)
+GO("libgnutls.so", gnutls)
+//GO("liblcms2.so", lcms2)
+GO("libmpg123.so", mpg123)
+//GO("libtiff.so", libtiff)
+GO("libxml2.so", xml2)
+GO("libX11.so", libx11)
+GO("libXext.so", libxext)
+GO("libxcb.so", libxcb)
+GO("libXau.so", libxau)
+GO("libandroid-shmem.so", androidshmem)
+#else
+GO("libc.so.6", libc)
+GO("libm.so.6", libm)
+GO("libdl.so.2", libdl)
+GO("libcups.so.2", libcups)
+GO("liblber-2.4.so.2", lber)
+GO("libldap_r-2.4.so.2", ldapr)
+GO("libpng16.so.16", png16)
+GO("libxslt.so.1", xslt)
+GO("libfreetype.so.6", freetype)
+GO("libgnutls.so.30", gnutls)
+//GO("liblcms2.so.2", lcms2)
+GO("libmpg123.so.0", mpg123)
+//GO("libtiff.so.5", libtiff)
+GO("libxml2.so.2", xml2)
+#endif
+
 GO("ld-linux-x86-64.so.2", ldlinux)
 
 GO("libunwind.so.8", unwind)
diff --git a/src/libtools/signals.c b/src/libtools/signals.c
index b20c04f3..1c3c117a 100644
--- a/src/libtools/signals.c
+++ b/src/libtools/signals.c
@@ -13,7 +13,9 @@
 #include <setjmp.h>
 #include <sys/mman.h>
 #include <pthread.h>
+#ifndef ANDROID
 #include <execinfo.h>
+#endif
 
 #include "box64context.h"
 #include "debug.h"
@@ -858,7 +860,11 @@ void my_sigactionhandler_oldcode(int32_t sig, int simple, siginfo_t* info, void
             if(Locks & is_dyndump_locked)
                 CancelBlock64(1);
             #endif
+            #ifdef ANDROID
+            siglongjmp(*emu->jmpbuf, 1);
+            #else
             siglongjmp(emu->jmpbuf, 1);
+            #endif
         }
         printf_log(LOG_INFO, "Warning, context has been changed in Sigactionhanlder%s\n", (sigcontext->uc_mcontext.gregs[X64_RIP]!=sigcontext_copy.uc_mcontext.gregs[X64_RIP])?" (EIP changed)":"");
     }
@@ -1041,7 +1047,11 @@ void my_box64signalhandler(int32_t sig, siginfo_t* info, void * ucntx)
                 if(Locks & is_dyndump_locked)
                     CancelBlock64(1);
                 emu->test.clean = 0;
+                #ifdef ANDROID
+                siglongjmp(*(JUMPBUFF*)emu->jmpbuf, 2);
+                #else
                 siglongjmp(emu->jmpbuf, 2);
+                #endif
             }
             dynarec_log(LOG_INFO, "Warning, Auto-SMC (%p for db %p/%p) detected, but jmpbuffer not ready!\n", (void*)addr, db, (void*)db->x64_addr);
         }
@@ -1206,6 +1216,7 @@ exit(-1);
             }
         }
         print_cycle_log(log_minimum);
+#ifndef ANDROID
         if((box64_showbt || sig==SIGABRT) && log_minimum<=box64_log) {
             // show native bt
             #define BT_BUF_SIZE 100
@@ -1274,6 +1285,7 @@ exit(-1);
             GO(RIP);
             #undef GO
         }
+#endif
         if(log_minimum<=box64_log) {
             static const char* reg_name[] = {"RAX", "RCX", "RDX", "RBX", "RSP", "RBP", "RSI", "RDI", " R8", " R9","R10","R11", "R12","R13","R14","R15"};
             static const char* seg_name[] = {"ES", "CS", "SS", "DS", "FS", "GS"};
diff --git a/src/libtools/threads.c b/src/libtools/threads.c
index 90c665e2..c9d788e5 100644
--- a/src/libtools/threads.c
+++ b/src/libtools/threads.c
@@ -61,7 +61,11 @@ typedef struct jump_buff_x64_s {
 typedef struct __jmp_buf_tag_s {
     jump_buff_x64_t  __jmpbuf;
     int              __mask_was_saved;
+	#ifdef ANDROID
+	sigset_t       	 __saved_mask;
+	#else
     __sigset_t       __saved_mask;
+	#endif
 } __jmp_buf_tag_t;
 
 typedef struct x64_unwind_buff_s {
@@ -75,7 +79,9 @@ typedef struct x64_unwind_buff_s {
 typedef void(*vFv_t)();
 
 KHASH_MAP_INIT_INT64(threadstack, threadstack_t*)
+#ifndef ANDROID
 KHASH_MAP_INIT_INT64(cancelthread, __pthread_unwind_buf_t*)
+#endif
 
 void CleanStackSize(box64context_t* context)
 {
@@ -142,6 +148,8 @@ static void FreeCancelThread(box64context_t* context)
 	if(!context)
 		return;
 }
+
+#ifndef ANDROID
 static __pthread_unwind_buf_t* AddCancelThread(x64_unwind_buff_t* buff)
 {
 	__pthread_unwind_buf_t* r = (__pthread_unwind_buf_t*)box_calloc(1, sizeof(__pthread_unwind_buf_t));
@@ -160,6 +168,7 @@ static void DelCancelThread(x64_unwind_buff_t* buff)
 	box_free(r);
 	buff->__pad[3] = NULL;
 }
+#endif
 
 typedef struct emuthread_s {
 	uintptr_t 	fnc;
@@ -388,11 +397,13 @@ EXPORT int my_pthread_attr_init(x64emu_t* emu, pthread_attr_t* attr)
 	(void)emu;
 	return pthread_attr_init(getAlignedAttrWithInit(attr, 0));
 }
+#ifndef ANDROID
 EXPORT int my_pthread_attr_setaffinity_np(x64emu_t* emu, pthread_attr_t* attr, size_t cpusize, void* cpuset)
 {
 	(void)emu;
 	return pthread_attr_setaffinity_np(getAlignedAttr(attr), cpusize, cpuset);
 }
+#endif
 EXPORT int my_pthread_attr_setdetachstate(x64emu_t* emu, pthread_attr_t* attr, int state)
 {
 	(void)emu;
@@ -430,6 +441,7 @@ EXPORT int my_pthread_attr_setstackaddr(x64emu_t* emu, pthread_attr_t* attr, voi
 	return pthread_attr_setstack(getAlignedAttr(attr), addr, size);
 	//return pthread_attr_setstackaddr(getAlignedAttr(attr), addr);
 }
+#ifndef ANDROID
 EXPORT int my_pthread_getattr_np(x64emu_t* emu, pthread_t thread_id, pthread_attr_t* attr)
 {
 	(void)emu;
@@ -462,6 +474,7 @@ EXPORT int my_pthread_setattr_default_np(x64emu_t* emu, pthread_attr_t* attr)
 	(void)emu;
 	return pthread_setattr_default_np(getAlignedAttr(attr));
 }
+#endif	//!ANDROID
 #endif
 
 EXPORT int my_pthread_create(x64emu_t *emu, void* t, void* attr, void* start_routine, void* arg)
@@ -526,6 +539,7 @@ void* my_prepare_thread(x64emu_t *emu, void* f, void* arg, int ssize, void** pet
 
 void my_longjmp(x64emu_t* emu, /*struct __jmp_buf_tag __env[1]*/void *p, int32_t __val);
 
+#ifndef ANDROID
 #define CANCEL_MAX 8
 static __thread x64emu_t* cancel_emu[CANCEL_MAX] = {0};
 static __thread x64_unwind_buff_t* cancel_buff[CANCEL_MAX] = {0};
@@ -578,6 +592,7 @@ EXPORT void my___pthread_unwind_next(x64emu_t* emu, x64_unwind_buff_t* buff)
 	// just in case it does return
 	emu->quit = 1;
 }
+#endif
 
 KHASH_MAP_INIT_INT(once, int)
 
@@ -724,6 +739,7 @@ EXPORT int my_pthread_cond_clockwait(x64emu_t *emu, pthread_cond_t* cond, void*
 	return ret;
 }
 
+#ifndef ANDROID
 EXPORT void my__pthread_cleanup_push_defer(x64emu_t* emu, void* buffer, void* routine, void* arg)
 {
     (void)emu;
@@ -769,6 +785,7 @@ EXPORT int my_pthread_setaffinity_np(x64emu_t* emu, pthread_t thread, size_t cpu
 
     return ret;
 }
+#endif
 
 //EXPORT int my_pthread_attr_setaffinity_np(x64emu_t* emu, void* attr, uint32_t cpusetsize, void* cpuset)
 //{
@@ -845,6 +862,7 @@ EXPORT int my_pthread_mutexattr_gettype(x64emu_t* emu, my_mutexattr_t *attr, voi
 	attr->x86 = mattr.x86;
 	return ret;
 }
+#ifndef ANDROID
 EXPORT int my_pthread_mutexattr_getrobust(x64emu_t* emu, my_mutexattr_t *attr, void* p)
 {
 	my_mutexattr_t mattr = {0};
@@ -853,6 +871,7 @@ EXPORT int my_pthread_mutexattr_getrobust(x64emu_t* emu, my_mutexattr_t *attr, v
 	attr->x86 = mattr.x86;
 	return ret;
 }
+#endif
 EXPORT int my_pthread_mutexattr_init(x64emu_t* emu, my_mutexattr_t *attr)
 {
 	my_mutexattr_t mattr = {0};
@@ -896,6 +915,7 @@ EXPORT int my_pthread_mutexattr_settype(x64emu_t* emu, my_mutexattr_t *attr, int
 	return ret;
 }
 EXPORT int my___pthread_mutexattr_settype(x64emu_t* emu, my_mutexattr_t *attr, int t) __attribute__((alias("my_pthread_mutexattr_settype")));
+#ifndef ANDROID
 EXPORT int my_pthread_mutexattr_setrobust(x64emu_t* emu, my_mutexattr_t *attr, int t)
 {
 	my_mutexattr_t mattr = {0};
@@ -904,6 +924,7 @@ EXPORT int my_pthread_mutexattr_setrobust(x64emu_t* emu, my_mutexattr_t *attr, i
 	attr->x86 = mattr.x86;
 	return ret;
 }
+#endif
 
 #ifdef __SIZEOF_PTHREAD_MUTEX_T
 #if __SIZEOF_PTHREAD_MUTEX_T == 48
diff --git a/src/mallochook.c b/src/mallochook.c
index 885e38c4..1559c4be 100644
--- a/src/mallochook.c
+++ b/src/mallochook.c
@@ -133,12 +133,14 @@ typedef void* (*pFpLLp_t)(void*, size_t, size_t, void*);
 
 #ifdef ANDROID
 void*(*__libc_malloc)(size_t) = NULL;
-void*(*__libc_realloc)(size_t, void*) = NULL;
+void*(*__libc_realloc)(void*, size_t) = NULL;
 void*(*__libc_calloc)(size_t, size_t) = NULL;
 void (*__libc_free)(void*) = NULL;
 void*(*__libc_memalign)(size_t, size_t) = NULL;
-#endif
+size_t(*box_malloc_usable_size)(const void*) = NULL;
+#else
 size_t(*box_malloc_usable_size)(void*) = NULL;
+#endif
 
 int GetTID();
 uint32_t getProtection(uintptr_t addr);
@@ -303,7 +305,11 @@ EXPORT void cfree(void* p)
     box_free(p);
 }
 
+#ifdef ANDROID
+EXPORT size_t malloc_usable_size(const void* p)
+#else
 EXPORT size_t malloc_usable_size(void* p)
+#endif
 {
     if(malloc_hack_2 && real_malloc_usable_size) {
         if(getMmapped((uintptr_t)p))
diff --git a/src/tools/bridge.c b/src/tools/bridge.c
index 220e06a1..fc3055bb 100644
--- a/src/tools/bridge.c
+++ b/src/tools/bridge.c
@@ -6,7 +6,6 @@
 #include <pthread.h>
 #include <sys/mman.h>
 #include <errno.h>
-#include <execinfo.h>
 
 #include <wrappedlibs.h>
 #include "custommem.h"
diff --git a/src/tools/rcfile.c b/src/tools/rcfile.c
index e41980c0..8db7b0a6 100644
--- a/src/tools/rcfile.c
+++ b/src/tools/rcfile.c
@@ -277,6 +277,15 @@ static void trimString(char* s)
         memmove(s, s+1, strlen(s));
 }
 
+#ifdef ANDROID
+static int shm_open(const char *name, int oflag, mode_t mode) {
+    return -1;
+}
+static int shm_unlink(const char *name) {
+    return -1;
+}
+#endif
+
 void LoadRCFile(const char* filename)
 {
     FILE *f = NULL;
diff --git a/src/wrapped/generated/functions_list.txt b/src/wrapped/generated/functions_list.txt
index 8f8dc38b..2716c3a6 100644
--- a/src/wrapped/generated/functions_list.txt
+++ b/src/wrapped/generated/functions_list.txt
@@ -3897,6 +3897,8 @@ wrappedlibc:
   - __vsyslog_chk
 - vFpLLp:
   - qsort
+- vFpppp:
+  - __libc_init
 - iFiiip:
   - epoll_ctl
 - iFiiiN:
diff --git a/src/wrapped/generated/wrappedlibctypes.h b/src/wrapped/generated/wrappedlibctypes.h
index 508a16f6..e7a08c3e 100644
--- a/src/wrapped/generated/wrappedlibctypes.h
+++ b/src/wrapped/generated/wrappedlibctypes.h
@@ -58,6 +58,7 @@ typedef void* (*pFppV_t)(void*, void*, ...);
 typedef void (*vFiipV_t)(int32_t, int32_t, void*, ...);
 typedef void (*vFiipA_t)(int32_t, int32_t, void*, va_list);
 typedef void (*vFpLLp_t)(void*, uintptr_t, uintptr_t, void*);
+typedef void (*vFpppp_t)(void*, void*, void*, void*);
 typedef int32_t (*iFiiip_t)(int32_t, int32_t, int32_t, void*);
 typedef int32_t (*iFiiiN_t)(int32_t, int32_t, int32_t, ...);
 typedef int32_t (*iFiipV_t)(int32_t, int32_t, void*, ...);
@@ -228,6 +229,7 @@ typedef int32_t (*iFppipppp_t)(void*, void*, int32_t, void*, void*, void*, void*
 	GO(__syslog_chk, vFiipV_t) \
 	GO(__vsyslog_chk, vFiipA_t) \
 	GO(qsort, vFpLLp_t) \
+	GO(__libc_init, vFpppp_t) \
 	GO(epoll_ctl, iFiiip_t) \
 	GO(semctl, iFiiiN_t) \
 	GO(__dprintf_chk, iFiipV_t) \
diff --git a/src/wrapped/wrappedandroidshmem.c b/src/wrapped/wrappedandroidshmem.c
new file mode 100755
index 00000000..ac4c874e
--- /dev/null
+++ b/src/wrapped/wrappedandroidshmem.c
@@ -0,0 +1,18 @@
+#define _GNU_SOURCE         /* See feature_test_macros(7) */

+#include <stdio.h>

+#include <stdlib.h>

+#include <string.h>

+#include <dlfcn.h>

+

+#include "wrappedlibs.h"

+

+#include "wrapper.h"

+#include "bridge.h"

+#include "librarian/library_private.h"

+#include "x64emu.h"

+

+const char* androidshmemName = "libandroid-shmem.so";

+#define LIBNAME androidshmem

+

+#include "wrappedlib_init.h"

+

diff --git a/src/wrapped/wrappedandroidshmem_private.h b/src/wrapped/wrappedandroidshmem_private.h
new file mode 100755
index 00000000..84f29a81
--- /dev/null
+++ b/src/wrapped/wrappedandroidshmem_private.h
@@ -0,0 +1,8 @@
+#if !(defined(GO) && defined(GOM) && defined(GO2) && defined(DATA))

+#error Meh....

+#endif

+

+GO(shmctl, iFiip)

+GO(shmget, iFiLi)

+GO(shmat, pFipi)

+GO(shmdt, iFp)

diff --git a/src/wrapped/wrappedfreetype.c b/src/wrapped/wrappedfreetype.c
index 4ced9be3..86706b45 100644
--- a/src/wrapped/wrappedfreetype.c
+++ b/src/wrapped/wrappedfreetype.c
@@ -18,7 +18,13 @@
 #include "emu/x64emu_private.h"
 #include "myalign.h"
 
-const char* freetypeName = "libfreetype.so.6";
+const char* freetypeName = 
+#ifdef ANDROID
+	"libfreetype.so"
+#else
+    "libfreetype.so.6"
+#endif
+    ;
 #define LIBNAME freetype
 
 typedef void  (*vFp_t)(void*);
diff --git a/src/wrapped/wrappedgnutls.c b/src/wrapped/wrappedgnutls.c
index dd4cde20..1edf28de 100644
--- a/src/wrapped/wrappedgnutls.c
+++ b/src/wrapped/wrappedgnutls.c
@@ -18,7 +18,13 @@
 #include "emu/x64emu_private.h"
 #include "callback.h"
 
-const char* gnutlsName = "libgnutls.so.30";
+const char* gnutlsName = 
+#if ANDROID
+    "libgnutls.so"
+#else
+    "libgnutls.so.30"
+#endif
+    ;
 #define LIBNAME gnutls
 
 #include "generated/wrappedgnutlstypes.h"
diff --git a/src/wrapped/wrappedlibc.c b/src/wrapped/wrappedlibc.c
index b0241375..acfc2618 100644
--- a/src/wrapped/wrappedlibc.c
+++ b/src/wrapped/wrappedlibc.c
@@ -65,7 +65,13 @@
 #include "rcfile.h"
 
 #define LIBNAME libc
-const char* libcName = "libc.so.6";
+const char* libcName = 
+#ifdef ANDROID
+    "libc.so"
+#else
+    "libc.so.6"
+#endif
+    ;
 
 typedef int (*iFi_t)(int);
 typedef int (*iFp_t)(void*);
@@ -1271,6 +1277,50 @@ EXPORT int my_statfs64(const char* path, void* buf)
 }
 #endif
 
+#ifdef ANDROID
+typedef int (*__compar_d_fn_t)(const void*, const void*, void*);
+
+static size_t qsort_r_partition(void* base, size_t size, __compar_d_fn_t compar, void* arg, size_t lo, size_t hi)
+{
+    void* tmp = alloca(size);
+    void* pivot = ((char*)base) + lo * size;
+    size_t i = lo;
+    for (size_t j = lo; j <= hi; j++)
+    {
+        void* base_i = ((char*)base) + i * size;
+        void* base_j = ((char*)base) + j * size;
+        if (compar(base_j, pivot, arg) < 0)
+        {
+            memcpy(tmp, base_i, size);
+            memcpy(base_i, base_j, size);
+            memcpy(base_j, tmp, size);
+            i++;
+        }
+    }
+    void* base_i = ((char *)base) + i * size;
+    void* base_hi = ((char *)base) + hi * size;
+    memcpy(tmp, base_i, size);
+    memcpy(base_i, base_hi, size);
+    memcpy(base_hi, tmp, size);
+    return i;
+}
+
+static void qsort_r_helper(void* base, size_t size, __compar_d_fn_t compar, void* arg, ssize_t lo, ssize_t hi)
+{
+    if (lo < hi)
+    {
+        size_t p = qsort_r_partition(base, size, compar, arg, lo, hi);
+        qsort_r_helper(base, size, compar, arg, lo, p - 1);
+        qsort_r_helper(base, size, compar, arg, p + 1, hi);
+    }
+}
+
+static void qsort_r(void* base, size_t nmemb, size_t size, __compar_d_fn_t compar, void* arg)
+{
+    return qsort_r_helper(base, size, compar, arg, 0, nmemb - 1);
+}
+#endif
+
 typedef struct compare_r_s {
     x64emu_t* emu;
     uintptr_t f;
@@ -1601,6 +1651,15 @@ void CreateCPUInfoFile(int fd)
     #undef P
 }
 
+#ifdef ANDROID
+static int shm_open(const char *name, int oflag, mode_t mode) {
+    return -1;
+}
+static int shm_unlink(const char *name) {
+    return -1;
+}
+#endif
+
 #define TMP_CPUINFO "box64_tmpcpuinfo"
 #define TMP_CPUTOPO "box64_tmpcputopo%d"
 #endif
@@ -1843,12 +1902,14 @@ EXPORT int32_t my_epoll_pwait(x64emu_t* emu, int32_t epfd, void* events, int32_t
 }
 #endif
 
+#ifndef ANDROID
 EXPORT int32_t my_glob64(x64emu_t *emu, void* pat, int32_t flags, void* errfnc, void* pglob)
 {
     (void)emu;
     return glob64(pat, flags, findgloberrFct(errfnc), pglob);
 }
 EXPORT int32_t my_glob(x64emu_t *emu, void* pat, int32_t flags, void* errfnc, void* pglob) __attribute__((alias("my_glob64")));
+#endif
 
 EXPORT int my_scandir64(x64emu_t *emu, void* dir, void* namelist, void* sel, void* comp)
 {
@@ -2439,6 +2500,11 @@ void InitCpuModel()
 }
 #endif
 
+#ifdef ANDROID
+void ctSetup()
+{
+}
+#else
 EXPORT const unsigned short int *my___ctype_b;
 EXPORT const int32_t *my___ctype_tolower;
 EXPORT const int32_t *my___ctype_toupper;
@@ -2449,6 +2515,7 @@ void ctSetup()
     my___ctype_toupper = *(__ctype_toupper_loc());
     my___ctype_tolower = *(__ctype_tolower_loc());
 }
+#endif
 
 EXPORT void my___register_frame_info(void* a, void* b)
 {
@@ -2478,7 +2545,11 @@ typedef struct jump_buff_x64_s {
 typedef struct __jmp_buf_tag_s {
     jump_buff_x64_t __jmpbuf;
     int              __mask_was_saved;
+    #ifdef ANDROID
+    sigset_t         __saved_mask;
+    #else
     __sigset_t       __saved_mask;
+    #endif
 } __jmp_buf_tag_t;
 
 void EXPORT my_longjmp(x64emu_t* emu, /*struct __jmp_buf_tag __env[1]*/void *p, int32_t __val)
@@ -2759,6 +2830,7 @@ EXPORT int my_getopt_long_only(int argc, char* const argv[], const char* optstri
     return ret;
 }
 
+#ifndef ANDROID
 typedef struct {
    void  *read;
    void *write;
@@ -2806,6 +2878,7 @@ EXPORT void* my_fopencookie(x64emu_t* emu, void* cookie, void* mode, my_cookie_i
     cb->cookie = cookie;
     return fopencookie(cb, mode, io_funcs);
 }
+#endif
 
 #if 0
 
@@ -2869,8 +2942,13 @@ EXPORT int my_nanosleep(const struct timespec *req, struct timespec *rem)
 }
 #endif
 
+#ifdef ANDROID
+void obstackSetup() {
+}
+#else
 // all obstack function defined in obstack.c file
 void obstackSetup();
+#endif
 
 EXPORT void* my_malloc(unsigned long size)
 {
@@ -2959,6 +3037,7 @@ EXPORT void my_mcount(void* frompc, void* selfpc)
 }
 #endif
 
+#ifndef ANDROID
 union semun {
   int              val;    /* Value for SETVAL */
   struct semid_ds *buf;    /* Buffer for IPC_STAT, IPC_SET */
@@ -2966,6 +3045,7 @@ union semun {
   struct seminfo  *__buf;  /* Buffer for IPC_INFO
                               (Linux-specific) */
 };
+#endif
 #ifndef SEM_STAT_ANY
 #define SEM_STAT_ANY 20
 #endif
@@ -3002,6 +3082,7 @@ EXPORT int my_ptrace(x64emu_t* emu, int request, pid_t pid, void* addr, void* da
 
 // Backtrace stuff
 
+#ifndef ANDROID
 #include "elfs/elfdwarf_private.h"
 EXPORT int my_backtrace(x64emu_t* emu, void** buffer, int size)
 {
@@ -3127,6 +3208,7 @@ EXPORT void my_backtrace_symbols_fd(x64emu_t* emu, uintptr_t* buffer, int size,
         (void)dummy;
     }
 }
+#endif
 
 EXPORT int my_iopl(x64emu_t* emu, int level)
 {
@@ -3320,6 +3402,27 @@ EXPORT char my___libc_single_threaded = 0;
         lib->w.lib = dlopen(NULL, RTLD_LAZY | RTLD_GLOBAL);    \
     else
 
+#ifdef ANDROID
+#define NEEDED_LIBS   0
+#define NEEDED_LIBS_234 3,  \
+    "libpthread.so.0",      \
+    "libdl.so.2" ,          \
+    "libm.so"
+#else
+#define NEEDED_LIBS   4,\
+    "ld-linux-x86-64.so.2", \
+    "libpthread.so.0",      \
+    "libutil.so.1",         \
+    "librt.so.1"
+#define NEEDED_LIBS_234 6,  \
+    "ld-linux-x86-64.so.2", \
+    "libpthread.so.0",      \
+    "libdl.so.2",           \
+    "libutil.so.1",         \
+    "libresolv.so.2",       \
+    "librt.so.1"
+#endif
+
 #define CUSTOM_INIT         \
     box64->libclib = lib;   \
     /*InitCpuModel();*/         \
@@ -3331,19 +3434,9 @@ EXPORT char my___libc_single_threaded = 0;
         strrchr(box64->argv[0], '/') + 1;                                       \
     getMy(lib);                                                                 \
     if(box64_isglibc234)                                                        \
-        setNeededLibs(lib, 6,                                                   \
-            "ld-linux-x86-64.so.2",                                             \
-            "libpthread.so.0",                                                  \
-            "libdl.so.2",                                                       \
-            "libutil.so.1",                                                     \
-            "libresolv.so.2",                                                   \
-            "librt.so.1");                                                      \
+        setNeededLibs(lib, NEEDED_LIBS_234);                                    \
     else                                                                        \
-        setNeededLibs(lib, 4,                                                   \
-            "ld-linux-x86-64.so.2",                                             \
-            "libpthread.so.0",                                                  \
-            "libutil.so.1",                                                     \
-            "librt.so.1");
+        setNeededLibs(lib, NEEDED_LIBS);
 
 #define CUSTOM_FINI \
     freeMy();
diff --git a/src/wrapped/wrappedlibc_private.h b/src/wrapped/wrappedlibc_private.h
index 933178e5..efd5705b 100644
--- a/src/wrapped/wrappedlibc_private.h
+++ b/src/wrapped/wrappedlibc_private.h
@@ -2326,3 +2326,16 @@ DATAM(__libc_single_threaded, 1)
 
 GO(iconvctl, iFlip)
 GO(dummy__ZnwmSt11align_val_tRKSt9nothrow_t, pFLLp) // for mallochook.c
+
+#ifdef ANDROID
+GOM(__libc_init, vFEpppp)
+GO(__errno, pFv)
+GO(setprogname, vFp)
+GO(getprogname, pFv)
+#else
+// Those symbols don't exist in non-Android builds
+//GOM(__libc_init,
+//GO(__errno,
+//GO(setprogname,
+//GO(getprogname,
+#endif
diff --git a/src/wrapped/wrappedlibcups.c b/src/wrapped/wrappedlibcups.c
index 16ea4725..dc846868 100644
--- a/src/wrapped/wrappedlibcups.c
+++ b/src/wrapped/wrappedlibcups.c
@@ -18,7 +18,14 @@
 #include "emu/x64emu_private.h"
 #include "myalign.h"
 
-const char* libcupsName = "libcups.so.2";
+const char* libcupsName = 
+#ifdef ANDROID
+    "libcups.so"
+#else
+    "libcups.so.2"
+#endif
+    ;
+
 #define LIBNAME libcups
 
 #define ADDED_FUNCTIONS()                   \
diff --git a/src/wrapped/wrappedlibdl.c b/src/wrapped/wrappedlibdl.c
index 47c47c6b..29ce81ab 100644
--- a/src/wrapped/wrappedlibdl.c
+++ b/src/wrapped/wrappedlibdl.c
@@ -393,6 +393,15 @@ int my_dlclose(x64emu_t* emu, void *handle)
     DecRefCount(&dl->dllibs[nlib].lib, emu);
     return 0;
 }
+#ifdef ANDROID
+#ifndef RTLD_DL_SYMENT
+#define RTLD_DL_SYMENT 1
+#endif
+#ifndef RTLD_DL_LINKMAP
+#define RTLD_DL_LINKMAP 2
+#endif
+#endif
+
 int my_dladdr1(x64emu_t* emu, void *addr, void *i, void** extra_info, int flags)
 {
     //int dladdr(void *addr, Dl_info *info);
diff --git a/src/wrapped/wrappedlibm.c b/src/wrapped/wrappedlibm.c
index 43bdf5cc..0e4f4cf9 100644
--- a/src/wrapped/wrappedlibm.c
+++ b/src/wrapped/wrappedlibm.c
@@ -14,7 +14,14 @@
 #include "x64emu.h"
 #include "debug.h"
 
-const char* libmName = "libm.so.6";
+const char* libmName = 
+#ifdef ANDROID
+    "libm.so"
+#else
+    "libm.so.6"
+#endif
+    ;
+
 #define LIBNAME libm
 
 static library_t* my_lib = NULL;
diff --git a/src/wrapped/wrappedmpg123.c b/src/wrapped/wrappedmpg123.c
index 5b95749e..dc538abf 100644
--- a/src/wrapped/wrappedmpg123.c
+++ b/src/wrapped/wrappedmpg123.c
@@ -17,7 +17,13 @@
 #include "box64context.h"
 #include "emu/x64emu_private.h"
 
-const char* mpg123Name = "libmpg123.so.0";
+const char* mpg123Name = 
+#ifdef ANDROID
+    "libmpg123.so"
+#else
+    "libmpg123.so.0"
+#endif
+    ;
 #define LIBNAME mpg123
 
 #define ADDED_FUNCTIONS()           \