about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/box64context.c6
-rw-r--r--src/include/myalign.h22
-rw-r--r--src/include/threads.h1
-rw-r--r--src/libtools/threads.c220
-rw-r--r--src/main.c6
-rw-r--r--src/wrapped/generated/functions_list.txt5
-rw-r--r--src/wrapped/generated/wrappedlibctypes.h2
-rw-r--r--src/wrapped/generated/wrappedlibpthreadtypes.h2
-rw-r--r--src/wrapped/generated/wrapper.c2
-rw-r--r--src/wrapped/generated/wrapper.h1
-rw-r--r--src/wrapped/wrappedlibc.c98
-rw-r--r--src/wrapped/wrappedlibc_private.h2
-rw-r--r--src/wrapped/wrappedlibpthread_private.h2
13 files changed, 187 insertions, 182 deletions
diff --git a/src/box64context.c b/src/box64context.c
index 234657ca..e38d0d33 100644
--- a/src/box64context.c
+++ b/src/box64context.c
@@ -68,6 +68,8 @@ void free_tlsdatasize(void* p)
     tlsdatasize_t *data = (tlsdatasize_t*)p;
     box_free(data->ptr);
     box_free(p);
+    if(my_context)
+        pthread_setspecific(my_context->tlskey, NULL);
 }
 
 void x64Syscall(x64emu_t *emu);
@@ -236,7 +238,7 @@ box64context_t *NewBox64Context(int argc)
     init_mutexes(context);
     pthread_atfork(NULL, NULL, atfork_child_box64context);
 
-    pthread_key_create(&context->tlskey, free_tlsdatasize);
+    pthread_key_create(&context->tlskey, NULL/*free_tlsdatasize*/);
 
 
     for (int i=0; i<8; ++i) context->canary[i] = 1 +  getrand(255);
@@ -278,6 +280,7 @@ void FreeBox64Context(box64context_t** context)
 
     box64context_t* ctx = *context;   // local copy to do the cleanning
 
+    //clean_current_emuthread();    // cleaning main thread seems a bad idea
     if(ctx->local_maplib)
         FreeLibrarian(&ctx->local_maplib, NULL);
     if(ctx->maplib)
@@ -342,7 +345,6 @@ void FreeBox64Context(box64context_t** context)
     void* ptr;
     if ((ptr = pthread_getspecific(ctx->tlskey)) != NULL) {
         free_tlsdatasize(ptr);
-        pthread_setspecific(ctx->tlskey, NULL);
     }
     pthread_key_delete(ctx->tlskey);
 
diff --git a/src/include/myalign.h b/src/include/myalign.h
index 247ea1b9..9293139a 100644
--- a/src/include/myalign.h
+++ b/src/include/myalign.h
@@ -214,4 +214,26 @@ void AlignSemidDs(void *dest, const void* source);
 
 uintptr_t getVArgs(x64emu_t* emu, int pos, uintptr_t* b, int N);
 
+// longjmp / setjmp
+typedef struct jump_buff_x64_s {
+    uint64_t save_rbx;
+    uint64_t save_rbp;
+    uint64_t save_r12;
+    uint64_t save_r13;
+    uint64_t save_r14;
+    uint64_t save_r15;
+    uint64_t save_rsp;
+    uint64_t save_rip;
+} jump_buff_x64_t;
+
+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;
+
 #endif  //__MY_ALIGN__H_
diff --git a/src/include/threads.h b/src/include/threads.h
index af58046b..8ed0e4c1 100644
--- a/src/include/threads.h
+++ b/src/include/threads.h
@@ -8,6 +8,7 @@ void CleanStackSize(box64context_t* context);
 
 void init_pthread_helper(void);
 void fini_pthread_helper(box64context_t* context);
+void clean_current_emuthread(void);
 
 // prepare an "emuthread structure" in pet and return address of function pointer for a "thread creation routine"
 void* my_prepare_thread(x64emu_t *emu, void* f, void* arg, int ssize, void** pet);
diff --git a/src/libtools/threads.c b/src/libtools/threads.c
index c9d788e5..ed0d2b0b 100644
--- a/src/libtools/threads.c
+++ b/src/libtools/threads.c
@@ -24,6 +24,7 @@
 #include "x64trace.h"
 #include "dynarec.h"
 #include "bridge.h"
+#include "myalign.h"
 #ifdef DYNAREC
 #include "dynablock.h"
 #include "dynarec/native_lock.h"
@@ -53,21 +54,6 @@ typedef struct threadstack_s {
 	size_t 	stacksize;
 } threadstack_t;
 
-// longjmp / setjmp
-typedef struct jump_buff_x64_s {
-	uint64_t save_reg[8];
-} jump_buff_x64_t;
-
-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 {
 	struct {
 		jump_buff_x64_t		__cancel_jmp_buf;	
@@ -76,6 +62,15 @@ typedef struct x64_unwind_buff_s {
 	void *__pad[4];
 } x64_unwind_buff_t __attribute__((__aligned__));
 
+typedef struct my_tls_keys_s {
+	pthread_key_t	key;
+	uintptr_t		f;
+} my_tls_keys_t;
+
+static int keys_cap = 0;
+static int keys_size = 0;
+static my_tls_keys_t *keys = NULL;
+
 typedef void(*vFv_t)();
 
 KHASH_MAP_INIT_INT64(threadstack, threadstack_t*)
@@ -139,52 +134,61 @@ int GetStackSize(x64emu_t* emu, uintptr_t attr, void** stack, size_t* stacksize)
 	return 0;
 }
 
-static void InitCancelThread()
-{
-}
-
-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));
-	buff->__pad[3] = r;
-	return r;
-}
-
-static __pthread_unwind_buf_t* GetCancelThread(x64_unwind_buff_t* buff)
-{
-	return (__pthread_unwind_buf_t*)buff->__pad[3];
-}
-
-static void DelCancelThread(x64_unwind_buff_t* buff)
-{
-	__pthread_unwind_buf_t* r = (__pthread_unwind_buf_t*)buff->__pad[3];
-	box_free(r);
-	buff->__pad[3] = NULL;
-}
-#endif
+void my_longjmp(x64emu_t* emu, /*struct __jmp_buf_tag __env[1]*/void *p, int32_t __val);
 
 typedef struct emuthread_s {
 	uintptr_t 	fnc;
 	void*		arg;
 	x64emu_t*	emu;
+	int			cancel_cap, cancel_size;
+	x64_unwind_buff_t **cancels;
 } emuthread_t;
 
 static void emuthread_destroy(void* p)
 {
 	emuthread_t *et = (emuthread_t*)p;
+	if(!et)
+		return;
+	void* ptr;
+	// check all tls keys
+	int end = 4;
+	while(end) {
+		int still = 0;
+		for(int i=0; i<keys_size; ++i) {
+			ptr = pthread_getspecific(keys[i].key);
+			if(ptr) {
+				still = 1;
+				RunFunctionWithEmu(et->emu, 0, keys[i].f, 1, ptr);
+			}
+		}
+		/*if(still) --end; else*/ end=0;
+	}
+	// check tlsdata
+	if (my_context && (ptr = pthread_getspecific(my_context->tlskey)) != NULL)
+        free_tlsdatasize(ptr);
+	// free x64emu
 	if(et) {
 		FreeX64Emu(&et->emu);
 		box_free(et);
 	}
 }
 
+static void emuthread_cancel(void* p)
+{
+	emuthread_t *et = (emuthread_t*)p;
+	if(!et)
+		return;
+	// check cancels threads
+	for(int i=et->cancel_size-1; i>=0; --i) {
+		et->emu->flags.quitonlongjmp = 0;
+		my_longjmp(et->emu, et->cancels[i]->__cancel_jmp_buf, 1);
+		DynaRun(et->emu);	// will return after a __pthread_unwind_next()
+	}
+	box_free(et->cancels);
+	et->cancels=NULL;
+	et->cancel_size = et->cancel_cap = 0;
+}
+
 static pthread_key_t thread_key;
 
 void thread_set_emu(x64emu_t* emu)
@@ -257,7 +261,9 @@ static void* pthread_routine(void* p)
 	PushExit(emu);
 	R_RIP = et->fnc;
 	R_RDI = (uintptr_t)et->arg;
+	pthread_cleanup_push(emuthread_cancel, p);
 	DynaRun(emu);
+	pthread_cleanup_pop(0);
 	void* ret = (void*)R_RAX;
 	//void* ret = (void*)RunFunctionWithEmu(et->emu, 0, et->fnc, 1, et->arg);
 	return ret;
@@ -537,62 +543,32 @@ void* my_prepare_thread(x64emu_t *emu, void* f, void* arg, int ssize, void** pet
 	return pthread_routine;
 }
 
-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};
-static __thread int cancel_deep = 0;
-EXPORT void my___pthread_register_cancel(void* E, void* B)
-{
-	// get a stack local copy of the args, as may be live in some register depending the architecture (like ARM)
-	if(cancel_deep<0) {
-		printf_log(LOG_NONE/*LOG_INFO*/, "BOX64: Warning, inconsistent value in __pthread_register_cancel (%d)\n", cancel_deep);
-		cancel_deep = 0;
-	}
-	if(cancel_deep!=CANCEL_MAX-1) 
-		++cancel_deep;
-	else
-		{printf_log(LOG_NONE/*LOG_INFO*/, "BOX64: Warning, calling __pthread_register_cancel(...) too many time\n");}
-		
-	cancel_emu[cancel_deep] = (x64emu_t*)E;
-
-	x64_unwind_buff_t* buff = cancel_buff[cancel_deep] = (x64_unwind_buff_t*)B;
-	__pthread_unwind_buf_t * pbuff = AddCancelThread(buff);
-	if(__sigsetjmp((struct __jmp_buf_tag*)(void*)pbuff->__cancel_jmp_buf, 0)) {
-		//DelCancelThread(cancel_buff);	// no del here, it will be delete by unwind_next...
-		int i = cancel_deep--;
-		x64emu_t* emu = cancel_emu[i];
-		my_longjmp(emu, cancel_buff[i]->__cancel_jmp_buf, 1);
-		DynaRun(emu);	// resume execution // TODO: Use ejb instead?
-		return;
+EXPORT void my___pthread_register_cancel(x64emu_t* emu, x64_unwind_buff_t* buff)
+{
+	emuthread_t *et = (emuthread_t*)pthread_getspecific(thread_key);
+	if(et->cancel_cap == et->cancel_size) {
+		et->cancel_cap+=8;
+		et->cancels = box_realloc(et->cancels, sizeof(x64_unwind_buff_t*)*et->cancel_cap);
 	}
-
-	__pthread_register_cancel(pbuff);
+	et->cancels[et->cancel_size++] = buff;
 }
 
 EXPORT void my___pthread_unregister_cancel(x64emu_t* emu, x64_unwind_buff_t* buff)
 {
-	(void)emu;
-	__pthread_unwind_buf_t * pbuff = GetCancelThread(buff);
-	__pthread_unregister_cancel(pbuff);
-
-	--cancel_deep;
-	DelCancelThread(buff);
+	emuthread_t *et = (emuthread_t*)pthread_getspecific(thread_key);
+	for (int i=et->cancel_size-1; i>=0; --i) {
+		if(et->cancels[i] == buff) {
+			if(i!=et->cancel_size-1)
+				memmove(et->cancels+i, et->cancels+i+1, sizeof(x64_unwind_buff_t*)*(et->cancel_size-i-1));
+			et->cancel_size--;
+		}
+	}
 }
 
 EXPORT void my___pthread_unwind_next(x64emu_t* emu, x64_unwind_buff_t* buff)
 {
-	(void)emu;
-	__pthread_unwind_buf_t pbuff = *GetCancelThread(buff);
-	DelCancelThread(buff);
-	// function is noreturn, putting stuff on the stack to have it auto-free (is that correct?)
-	__pthread_unwind_next(&pbuff);
-	// just in case it does return
 	emu->quit = 1;
 }
-#endif
 
 KHASH_MAP_INIT_INT(once, int)
 
@@ -628,28 +604,6 @@ GO(27)			\
 GO(28)			\
 GO(29)			
 
-// key_destructor
-#define GO(A)   \
-static uintptr_t my_key_destructor_fct_##A = 0;  \
-static void my_key_destructor_##A(void* a)    			\
-{                                       		\
-    RunFunction(my_key_destructor_fct_##A, 1, a);\
-}
-SUPER()
-#undef GO
-static void* findkey_destructorFct(void* fct)
-{
-    if(!fct) return fct;
-    if(GetNativeFnc((uintptr_t)fct))  return GetNativeFnc((uintptr_t)fct);
-    #define GO(A) if(my_key_destructor_fct_##A == (uintptr_t)fct) return my_key_destructor_##A;
-    SUPER()
-    #undef GO
-    #define GO(A) if(my_key_destructor_fct_##A == 0) {my_key_destructor_fct_##A = (uintptr_t)fct; return my_key_destructor_##A; }
-    SUPER()
-    #undef GO
-    printf_log(LOG_NONE, "Warning, no more slot for pthread key_destructor callback\n");
-    return NULL;
-}
 // cleanup_routine
 #define GO(A)   \
 static uintptr_t my_cleanup_routine_fct_##A = 0;  \
@@ -698,12 +652,35 @@ int EXPORT my_pthread_once(x64emu_t* emu, int* once, void* cb)
 }
 EXPORT int my___pthread_once(x64emu_t* emu, void* once, void* cb) __attribute__((alias("my_pthread_once")));
 
-EXPORT int my_pthread_key_create(x64emu_t* emu, void* key, void* dtor)
+EXPORT int my_pthread_key_create(x64emu_t* emu, pthread_key_t* key, void* dtor)
 {
 	(void)emu;
-	return pthread_key_create(key, findkey_destructorFct(dtor));
+	int ret = pthread_key_create(key, NULL/*findkey_destructorFct(dtor)*/);
+	if(!ret && dtor) {
+		if(keys_cap==keys_size) {
+			keys_cap += 8;
+			keys = box_realloc(keys, sizeof(my_tls_keys_t)*keys_cap);
+		}
+		keys[keys_size].f = (uintptr_t)dtor;
+		keys[keys_size++].key = *key;
+	}
+	return ret;
+}
+EXPORT int my___pthread_key_create(x64emu_t* emu, pthread_key_t* key, void* dtor) __attribute__((alias("my_pthread_key_create")));
+
+EXPORT int my_pthread_key_delete(x64emu_t* emu, pthread_key_t key)
+{
+	int ret = pthread_key_delete(key);
+	if(ret) {
+		for(int i=keys_size-1; i>=0; --i)
+			if(keys[i].key == key) {
+				if(i!=keys_size-1)
+					memmove(keys+i, keys+i+1, sizeof(my_tls_keys_t)*(keys_size-(i+1)));
+				--keys_size;
+			}
+	}
+	return ret;
 }
-EXPORT int my___pthread_key_create(x64emu_t* emu, void* key, void* dtor) __attribute__((alias("my_pthread_key_create")));
 
 pthread_cond_t* alignCond(pthread_cond_t* pc)
 {
@@ -1106,15 +1083,12 @@ void init_pthread_helper()
 		real_phtread_kill_old = (iFli_t)pthread_kill;
 	}
 
-	InitCancelThread();
 	pthread_key_create(&thread_key, emuthread_destroy);
 	pthread_setspecific(thread_key, NULL);
 }
 
-void fini_pthread_helper(box64context_t* context)
+void clean_current_emuthread()
 {
-	FreeCancelThread(context);
-	CleanStackSize(context);
 	emuthread_t *et = (emuthread_t*)pthread_getspecific(thread_key);
 	if(et) {
 		pthread_setspecific(thread_key, NULL);
@@ -1122,6 +1096,14 @@ void fini_pthread_helper(box64context_t* context)
 	}
 }
 
+void fini_pthread_helper(box64context_t* context)
+{
+	box_free(keys);
+	keys_size = keys_cap = 0;
+	CleanStackSize(context);
+	clean_current_emuthread();
+}
+
 int checkUnlockMutex(void* m)
 {
 	pthread_mutex_t* mutex = (pthread_mutex_t*)m;
diff --git a/src/main.c b/src/main.c
index 47cff957..a66e743b 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1234,13 +1234,13 @@ void endBox64()
     if(!my_context || box64_quit)
         return;
 
+    // then call all the fini
+    box64_quit = 1;
     endMallocHook();
     x64emu_t* emu = thread_get_emu();
     // atexit first
     printf_log(LOG_DEBUG, "Calling atexit registered functions (exiting box64)\n");
     CallAllCleanup(emu);
-    // then call all the fini
-    box64_quit = 1;
     printf_log(LOG_DEBUG, "Calling fini for all loaded elfs and unload native libs\n");
     RunElfFini(my_context->elfs[0], emu);
     FreeLibrarian(&my_context->local_maplib, emu);    // unload all libs
@@ -1861,7 +1861,7 @@ int main(int argc, const char **argv, char **env) {
     // Get EAX
     int ret = GetEAX(emu);
     printf_log(LOG_DEBUG, "Emulation finished, EAX=%d\n", ret);
-
+    endBox64();
 #ifdef HAVE_TRACE
     if(trace_func)  {
         box_free(trace_func);
diff --git a/src/wrapped/generated/functions_list.txt b/src/wrapped/generated/functions_list.txt
index be3f70e4..6c2ca8d8 100644
--- a/src/wrapped/generated/functions_list.txt
+++ b/src/wrapped/generated/functions_list.txt
@@ -164,6 +164,7 @@
 #() cFpp
 #() wFpi
 #() iFEi
+#() iFEL
 #() iFEp
 #() iFwp
 #() iFii
@@ -3944,6 +3945,8 @@ wrappedlibc:
 - iFip:
   - fstat
   - fstat64
+- iFup:
+  - setrlimit
 - iFLp:
   - pthread_getattr_np
 - iFpi:
@@ -4459,6 +4462,8 @@ wrappedlibpthread:
   - __pthread_register_cancel
   - __pthread_unregister_cancel
   - __pthread_unwind_next
+- iFL:
+  - pthread_key_delete
 - iFp:
   - __pthread_mutexattr_destroy
   - __pthread_mutexattr_init
diff --git a/src/wrapped/generated/wrappedlibctypes.h b/src/wrapped/generated/wrappedlibctypes.h
index bd36a4b3..ff0c659e 100644
--- a/src/wrapped/generated/wrappedlibctypes.h
+++ b/src/wrapped/generated/wrappedlibctypes.h
@@ -25,6 +25,7 @@ typedef void (*vFpu_t)(void*, uint32_t);
 typedef void (*vFpp_t)(void*, void*);
 typedef void (*vFpV_t)(void*, ...);
 typedef int32_t (*iFip_t)(int32_t, void*);
+typedef int32_t (*iFup_t)(uint32_t, void*);
 typedef int32_t (*iFLp_t)(uintptr_t, void*);
 typedef int32_t (*iFpi_t)(void*, int32_t);
 typedef int32_t (*iFpL_t)(void*, uintptr_t);
@@ -147,6 +148,7 @@ typedef int32_t (*iFppipppp_t)(void*, void*, int32_t, void*, void*, void*, void*
 	GO(warnx, vFpV_t) \
 	GO(fstat, iFip_t) \
 	GO(fstat64, iFip_t) \
+	GO(setrlimit, iFup_t) \
 	GO(pthread_getattr_np, iFLp_t) \
 	GO(__sigsetjmp, iFpi_t) \
 	GO(backtrace, iFpi_t) \
diff --git a/src/wrapped/generated/wrappedlibpthreadtypes.h b/src/wrapped/generated/wrappedlibpthreadtypes.h
index 95c1c73e..ad0ad8e2 100644
--- a/src/wrapped/generated/wrappedlibpthreadtypes.h
+++ b/src/wrapped/generated/wrappedlibpthreadtypes.h
@@ -12,6 +12,7 @@
 #endif
 
 typedef void (*vFp_t)(void*);
+typedef int32_t (*iFL_t)(uintptr_t);
 typedef int32_t (*iFp_t)(void*);
 typedef void (*vFpi_t)(void*, int32_t);
 typedef int32_t (*iFLp_t)(uintptr_t, void*);
@@ -30,6 +31,7 @@ typedef int32_t (*iFpppp_t)(void*, void*, void*, void*);
 	GO(__pthread_register_cancel, vFp_t) \
 	GO(__pthread_unregister_cancel, vFp_t) \
 	GO(__pthread_unwind_next, vFp_t) \
+	GO(pthread_key_delete, iFL_t) \
 	GO(__pthread_mutexattr_destroy, iFp_t) \
 	GO(__pthread_mutexattr_init, iFp_t) \
 	GO(pthread_attr_destroy, iFp_t) \
diff --git a/src/wrapped/generated/wrapper.c b/src/wrapped/generated/wrapper.c
index 7253c4cd..57056891 100644
--- a/src/wrapped/generated/wrapper.c
+++ b/src/wrapped/generated/wrapper.c
@@ -200,6 +200,7 @@ typedef int8_t (*cFpi_t)(void*, int32_t);
 typedef int8_t (*cFpp_t)(void*, void*);
 typedef int16_t (*wFpi_t)(void*, int32_t);
 typedef int32_t (*iFEi_t)(x64emu_t*, int32_t);
+typedef int32_t (*iFEL_t)(x64emu_t*, uintptr_t);
 typedef int32_t (*iFEp_t)(x64emu_t*, void*);
 typedef int32_t (*iFwp_t)(int16_t, void*);
 typedef int32_t (*iFii_t)(int32_t, int32_t);
@@ -3151,6 +3152,7 @@ void cFpi(x64emu_t *emu, uintptr_t fcn) { cFpi_t fn = (cFpi_t)fcn; R_RAX=fn((voi
 void cFpp(x64emu_t *emu, uintptr_t fcn) { cFpp_t fn = (cFpp_t)fcn; R_RAX=fn((void*)R_RDI, (void*)R_RSI); }
 void wFpi(x64emu_t *emu, uintptr_t fcn) { wFpi_t fn = (wFpi_t)fcn; R_RAX=fn((void*)R_RDI, (int32_t)R_RSI); }
 void iFEi(x64emu_t *emu, uintptr_t fcn) { iFEi_t fn = (iFEi_t)fcn; R_RAX=(int32_t)fn(emu, (int32_t)R_RDI); }
+void iFEL(x64emu_t *emu, uintptr_t fcn) { iFEL_t fn = (iFEL_t)fcn; R_RAX=(int32_t)fn(emu, (uintptr_t)R_RDI); }
 void iFEp(x64emu_t *emu, uintptr_t fcn) { iFEp_t fn = (iFEp_t)fcn; R_RAX=(int32_t)fn(emu, (void*)R_RDI); }
 void iFwp(x64emu_t *emu, uintptr_t fcn) { iFwp_t fn = (iFwp_t)fcn; R_RAX=(int32_t)fn((int16_t)R_RDI, (void*)R_RSI); }
 void iFii(x64emu_t *emu, uintptr_t fcn) { iFii_t fn = (iFii_t)fcn; R_RAX=(int32_t)fn((int32_t)R_RDI, (int32_t)R_RSI); }
diff --git a/src/wrapped/generated/wrapper.h b/src/wrapped/generated/wrapper.h
index ba0ca026..20b01f0b 100644
--- a/src/wrapped/generated/wrapper.h
+++ b/src/wrapped/generated/wrapper.h
@@ -201,6 +201,7 @@ void cFpi(x64emu_t *emu, uintptr_t fnc);
 void cFpp(x64emu_t *emu, uintptr_t fnc);
 void wFpi(x64emu_t *emu, uintptr_t fnc);
 void iFEi(x64emu_t *emu, uintptr_t fnc);
+void iFEL(x64emu_t *emu, uintptr_t fnc);
 void iFEp(x64emu_t *emu, uintptr_t fnc);
 void iFwp(x64emu_t *emu, uintptr_t fnc);
 void iFii(x64emu_t *emu, uintptr_t fnc);
diff --git a/src/wrapped/wrappedlibc.c b/src/wrapped/wrappedlibc.c
index 625ec087..06e68715 100644
--- a/src/wrapped/wrappedlibc.c
+++ b/src/wrapped/wrappedlibc.c
@@ -38,6 +38,7 @@
 #include <syslog.h>
 #include <malloc.h>
 #include <getopt.h>
+#include <sys/resource.h>
 #include <sys/prctl.h>
 #include <sys/ptrace.h>
 #undef LOG_INFO
@@ -2454,28 +2455,6 @@ EXPORT void* my___deregister_frame_info(void* a)
 
 EXPORT void* my____brk_addr = NULL;
 
-// longjmp / setjmp
-typedef struct jump_buff_x64_s {
-    uint64_t save_rbx;
-    uint64_t save_rbp;
-    uint64_t save_r12;
-    uint64_t save_r13;
-    uint64_t save_r14;
-    uint64_t save_r15;
-    uint64_t save_rsp;
-    uint64_t save_rip;
-} jump_buff_x64_t;
-
-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)
 {
     jump_buff_x64_t *jpbuff = &((__jmp_buf_tag_t*)p)->__jmpbuf;
@@ -2627,46 +2606,46 @@ EXPORT void* my_mremap(x64emu_t* emu, void* old_addr, size_t old_size, size_t ne
     dynarec_log(LOG_DEBUG, "mremap(%p, %lu, %lu, %d, %p)=>", old_addr, old_size, new_size, flags, new_addr);
     void* ret = mremap(old_addr, old_size, new_size, flags, new_addr);
     dynarec_log(LOG_DEBUG, "%p\n", ret);
-    if(ret==(void*)-1)
-        return ret; // failed...
-    uint32_t prot = getProtection((uintptr_t)old_addr)&~PROT_CUSTOM;
-    if(ret==old_addr) {
-        if(old_size && old_size<new_size) {
-            setProtection_mmap((uintptr_t)ret+old_size, new_size-old_size, prot);
-            #ifdef DYNAREC
-            if(box64_dynarec)
-                addDBFromAddressRange((uintptr_t)ret+old_size, new_size-old_size);
-            #endif
-        } else if(old_size && new_size<old_size) {
-            freeProtection((uintptr_t)ret+new_size, old_size-new_size);
-            #ifdef DYNAREC
-            if(box64_dynarec)
-                cleanDBFromAddressRange((uintptr_t)ret+new_size, old_size-new_size, 1);
+    if(ret!=(void*)-1) {
+        uint32_t prot = getProtection((uintptr_t)old_addr)&~PROT_CUSTOM;
+        if(ret==old_addr) {
+            if(old_size && old_size<new_size) {
+                setProtection_mmap((uintptr_t)ret+old_size, new_size-old_size, prot);
+                #ifdef DYNAREC
+                if(box64_dynarec)
+                    addDBFromAddressRange((uintptr_t)ret+old_size, new_size-old_size);
+                #endif
+            } else if(old_size && new_size<old_size) {
+                freeProtection((uintptr_t)ret+new_size, old_size-new_size);
+                #ifdef DYNAREC
+                if(box64_dynarec)
+                    cleanDBFromAddressRange((uintptr_t)ret+new_size, old_size-new_size, 1);
+                #endif
+            } else if(!old_size) {
+                setProtection_mmap((uintptr_t)ret, new_size, prot);
+                #ifdef DYNAREC
+                if(box64_dynarec)
+                    addDBFromAddressRange((uintptr_t)ret, new_size);
+                #endif
+            }
+        } else {
+            if(old_size
+            #ifdef MREMAP_DONTUNMAP
+            && ((flags&MREMAP_DONTUNMAP)==0)
             #endif
-        } else if(!old_size) {
-            setProtection_mmap((uintptr_t)ret, new_size, prot);
+            ) {
+                freeProtection((uintptr_t)old_addr, old_size);
+                #ifdef DYNAREC
+                if(box64_dynarec)
+                    cleanDBFromAddressRange((uintptr_t)old_addr, old_size, 1);
+                #endif
+            }
+            setProtection_mmap((uintptr_t)ret, new_size, prot); // should copy the protection from old block
             #ifdef DYNAREC
             if(box64_dynarec)
                 addDBFromAddressRange((uintptr_t)ret, new_size);
             #endif
         }
-    } else {
-        if(old_size
-        #ifdef MREMAP_DONTUNMAP
-        && ((flags&MREMAP_DONTUNMAP)==0)
-        #endif
-        ) {
-            freeProtection((uintptr_t)old_addr, old_size);
-            #ifdef DYNAREC
-            if(box64_dynarec)
-                cleanDBFromAddressRange((uintptr_t)old_addr, old_size, 1);
-            #endif
-        }
-        setProtection_mmap((uintptr_t)ret, new_size, prot); // should copy the protection from old block
-        #ifdef DYNAREC
-        if(box64_dynarec)
-            addDBFromAddressRange((uintptr_t)ret, new_size);
-        #endif
     }
     return ret;
 }
@@ -2879,6 +2858,13 @@ EXPORT void* my_malloc(unsigned long size)
     return calloc(1, size);
 }
 
+EXPORT int my_setrlimit(x64emu_t* emu, int ressource, const struct rlimit *rlim)
+{
+    int ret = (ressource==RLIMIT_AS)?0:setrlimit(ressource, rlim);
+    if(ressource==RLIMIT_AS) printf_log(LOG_DEBUG, " (ignored) RLIMIT_AS, cur=0x%lx, max=0x%lx ", rlim->rlim_cur, rlim->rlim_max);
+    return ret;
+}
+
 #if 0
 #ifdef PANDORA
 #define RENAME_NOREPLACE	(1 << 0)
diff --git a/src/wrapped/wrappedlibc_private.h b/src/wrapped/wrappedlibc_private.h
index ee855e42..f3568219 100644
--- a/src/wrapped/wrappedlibc_private.h
+++ b/src/wrapped/wrappedlibc_private.h
@@ -1748,7 +1748,7 @@ GOW(setregid, iFuu)
 GOW(setresgid, iFuuu)
 GOW(setresuid, iFuuu)
 GOW(setreuid, iFuu)
-GOW(setrlimit, iFup)
+GOWM(setrlimit, iFEup)
 GOW(setrlimit64, iFup)
 GO(setrpcent, vFi)
 GO(setservent, vFi)
diff --git a/src/wrapped/wrappedlibpthread_private.h b/src/wrapped/wrappedlibpthread_private.h
index c0fd0557..ca356e39 100644
--- a/src/wrapped/wrappedlibpthread_private.h
+++ b/src/wrapped/wrappedlibpthread_private.h
@@ -135,7 +135,7 @@ GO(pthread_getname_np, iFppL)
 GO(pthread_join, iFLp)
 GOM(__pthread_key_create, iFEpp)
 GOM(pthread_key_create, iFEpp)
-GO(pthread_key_delete, iFL)
+GOM(pthread_key_delete, iFEL)
 GO2(pthread_kill@GLIBC_2.2.5, iFEpi, my_pthread_kill_old)
 GOM(pthread_kill, iFEpi)
 GO(pthread_kill_other_threads_np, vFv)