Improved callbacks, with shared and small variant

This commit is contained in:
ptitSeb 2019-02-24 16:45:58 +01:00
parent b63ec10cf7
commit 18fa4d2134
6 changed files with 74 additions and 16 deletions

View File

@ -37,6 +37,7 @@ box86context_t *NewBox86Context(int argc)
context->argv = (char**)calloc(context->argc, sizeof(char*));
pthread_mutex_init(&context->mutex_once, NULL);
pthread_mutex_init(&context->mutex_once2, NULL);
return context;
}
@ -93,6 +94,7 @@ void FreeBox86Context(box86context_t** context)
FreeCallbackList(&(*context)->callbacks);
pthread_mutex_destroy(&(*context)->mutex_once);
pthread_mutex_destroy(&(*context)->mutex_once2);
free(*context);
*context = NULL;

View File

@ -58,6 +58,7 @@ typedef struct box86context_s {
callbacklist_t *callbacks; // all callbacks
pthread_mutex_t mutex_once;
pthread_mutex_t mutex_once2;
library_t *libclib; // shortcut to libc library (if loaded, so probably yes)
library_t *sdl1lib; // shortcut to SDL1 library (if loaded)

View File

@ -17,6 +17,7 @@ typedef struct onecallback_s {
uintptr_t fnc;
int nb_args;
void* arg[10];
int shared;
} onecallback_t;
KHASH_MAP_INIT_INT(callbacks, onecallback_t*)
@ -32,6 +33,7 @@ x86emu_t* AddCallback(x86emu_t* emu, uintptr_t fnc, int nb_args, void* arg1, voi
callbacklist_t *callbacks = emu->context->callbacks;
int stsize = 2*1024*1024; // 2MB stack (1MB is not enough for Xenonauts)
void* stack = malloc(stsize);
if(!stack) {printf_log(LOG_NONE, "BOX86: Error, cannot allocate 2MB Stack for callback\n");}
x86emu_t * newemu = NewX86Emu(emu->context, fnc, (uintptr_t)stack, stsize);
SetupX86Emu(newemu, emu->shared_global, emu->globals);
newemu->trace_start = emu->trace_start;
@ -50,12 +52,42 @@ x86emu_t* AddCallback(x86emu_t* emu, uintptr_t fnc, int nb_args, void* arg1, voi
cb->arg[2] = arg3;
cb->arg[3] = arg4;
cb->shared = 0;
return newemu;
}
x86emu_t* AddSharedCallback(x86emu_t* emu, uintptr_t fnc, int nb_args, void* arg1, void* arg2, void* arg3, void* arg4) __attribute__((alias("AddCallback")));
/*{
// doesn't work for now
x86emu_t* AddSmallCallback(x86emu_t* emu, uintptr_t fnc, int nb_args, void* arg1, void* arg2, void* arg3, void* arg4)
{
callbacklist_t *callbacks = emu->context->callbacks;
int stsize = 64*1024; // 64KB stack
void* stack = malloc(stsize);
if(!stack) {printf_log(LOG_NONE, "BOX86: Error, cannot allocate 64KB Stack for small callback\n");}
x86emu_t * newemu = NewX86Emu(emu->context, fnc, (uintptr_t)stack, stsize);
SetupX86Emu(newemu, emu->shared_global, emu->globals);
newemu->trace_start = emu->trace_start;
newemu->trace_end = emu->trace_end;
onecallback_t * cb;
int ret;
khint_t k = kh_put(callbacks, callbacks->list, (uintptr_t)newemu, &ret);
cb = kh_value(callbacks->list, k) = (onecallback_t*)calloc(1, sizeof(onecallback_t));
cb->emu = newemu;
cb->fnc = fnc;
cb->nb_args = nb_args;
cb->arg[0] = arg1;
cb->arg[1] = arg2;
cb->arg[2] = arg3;
cb->arg[3] = arg4;
cb->shared = 0;
return newemu;
}
x86emu_t* AddSharedCallback(x86emu_t* emu, uintptr_t fnc, int nb_args, void* arg1, void* arg2, void* arg3, void* arg4) //__attribute__((alias("AddCallback")));
{
callbacklist_t *callbacks = emu->context->callbacks;
x86emu_t * newemu = emu;
@ -71,9 +103,10 @@ x86emu_t* AddSharedCallback(x86emu_t* emu, uintptr_t fnc, int nb_args, void* arg
cb->arg[1] = arg2;
cb->arg[2] = arg3;
cb->arg[3] = arg4;
cb->shared = 1;
return newemu;
}*/
}
onecallback_t* FindCallback(x86emu_t* emu)
{
@ -93,7 +126,8 @@ void FreeCallback(x86emu_t* emu)
if(k==kh_end(callbacks->list))
return;
onecallback_t* cb = kh_value(callbacks->list, k);
FreeX86Emu(&cb->emu);
if(!cb->shared)
FreeX86Emu(&cb->emu);
free(cb);
kh_del(callbacks, callbacks->list, k);
}
@ -105,6 +139,7 @@ uint32_t RunCallback(x86emu_t* emu)
for (int i=cb->nb_args-1; i>=0; --i) // reverse order
Push(emu, (uint32_t)cb->arg[i]);
EmuCall(emu, cb->fnc);
R_ESP+=(cb->nb_args*4);
return R_EAX;
}
printf_log(LOG_INFO, "Warning, Callback not found?!\n");

View File

@ -10,6 +10,7 @@ callbacklist_t* NewCallbackList();
void FreeCallbackList(callbacklist_t** callbacks);
x86emu_t* AddCallback(x86emu_t* emu, uintptr_t fnc, int nb_args, void* arg1, void* arg2, void* arg3, void* arg4);
x86emu_t* AddSmallCallback(x86emu_t* emu, uintptr_t fnc, int nb_args, void* arg1, void* arg2, void* arg3, void* arg4);
x86emu_t* AddSharedCallback(x86emu_t* emu, uintptr_t fnc, int nb_args, void* arg1, void* arg2, void* arg3, void* arg4);
void FreeCallback(x86emu_t* emu);
uint32_t RunCallback(x86emu_t* emu);

View File

@ -1,6 +1,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <errno.h>
#include "debug.h"
#include "box86context.h"
@ -107,18 +108,36 @@ static void my_thread_once_callback()
return;
EmuCall(once_emu, once_fnc);
}
static x86emu_t *once2_emu = NULL;
static uintptr_t once2_fnc = 0;
static void my_thread_once2_callback()
{
if(!once2_emu)
return;
EmuCall(once2_emu, once2_fnc);
}
int EXPORT my_pthread_once(x86emu_t* emu, void* once, void* cb)
{
pthread_mutex_lock(&emu->context->mutex_once); // what if it deadlock here?
if(pthread_mutex_trylock(&emu->context->mutex_once)==EBUSY)
{
// 2nd level...
pthread_mutex_lock(&emu->context->mutex_once2);
once2_emu = emu;
once2_fnc = (uintptr_t)cb;
int ret = pthread_once(once, my_thread_once2_callback);
once_emu = NULL;
pthread_mutex_unlock(&emu->context->mutex_once2);
return ret;
} else {
once_emu = emu;
once_fnc = (uintptr_t)cb;
int ret = pthread_once(once, my_thread_once_callback);
once_emu = NULL;
once_emu = emu;
once_fnc = (uintptr_t)cb;
int ret = pthread_once(once, my_thread_once_callback);
once_emu = NULL;
pthread_mutex_unlock(&emu->context->mutex_once);
return ret;
pthread_mutex_unlock(&emu->context->mutex_once);
return ret;
}
}
EXPORT int my_pthread_key_create(x86emu_t* emu, void* key, void* dtor)
@ -129,7 +148,7 @@ EXPORT int my_pthread_key_create(x86emu_t* emu, void* key, void* dtor)
while (n<nb_dtor) {
if(!dtor_emu[n] || GetCallbackAddress(dtor_emu[n])==((uintptr_t)dtor)) {
if(!dtor_emu[n])
dtor_emu[n] = AddCallback(emu, (uintptr_t)dtor, 1, NULL, NULL, NULL, NULL);
dtor_emu[n] = AddSmallCallback(emu, (uintptr_t)dtor, 1, NULL, NULL, NULL, NULL);
return pthread_key_create((pthread_key_t*)key, dtor_cb[n]);
}
++n;

View File

@ -381,7 +381,7 @@ static int qsort_cmp(const void* a, const void* b, void* e)
EXPORT void my_qsort(x86emu_t* emu, void* base, size_t nmemb, size_t size, void* fnc)
{
// use a temporary callback
x86emu_t *cbemu = AddCallback(emu, (uintptr_t)fnc, 3, NULL, NULL, NULL, NULL);
x86emu_t *cbemu = AddSharedCallback(emu, (uintptr_t)fnc, 2, NULL, NULL, NULL, NULL);
qsort_r(base, nmemb, size, qsort_cmp, cbemu);
FreeCallback(cbemu);
}
@ -449,7 +449,7 @@ static int glob_errfnccallback(const char* epath, int no)
EXPORT int32_t my_glob(x86emu_t *emu, void* pat, int32_t flags, void* errfnc, void* pblog)
{
if(errfnc)
globemu = AddCallback(emu, (uintptr_t)errfnc, 2, NULL, NULL, NULL, NULL);
globemu = AddSharedCallback(emu, (uintptr_t)errfnc, 2, NULL, NULL, NULL, NULL);
int32_t r = glob((const char*)pat, flags, globemu?glob_errfnccallback:NULL, (glob_t*)pblog);
if(globemu) {
FreeCallback(globemu);