mirror of
https://github.com/ptitSeb/box86.git
synced 2024-11-23 06:39:55 +00:00
Added real support for getcontext / setcontext / makecontext and swapcontext (and now DotT Remastered wboots)
This commit is contained in:
parent
3110ed8df7
commit
577c5ac45b
@ -40,6 +40,11 @@ void PushExit(x86emu_t* emu)
|
||||
Push(emu, (uint32_t)&EndEmuMarker);
|
||||
}
|
||||
|
||||
void* GetExit()
|
||||
{
|
||||
return &EndEmuMarker;
|
||||
}
|
||||
|
||||
x86emu_t *NewX86Emu(box86context_t *context, uintptr_t start, uintptr_t stack, int stacksize, int ownstack)
|
||||
{
|
||||
printf_log(LOG_DEBUG, "Allocate a new X86 Emu, with EIP=%p and Stack=%p/0x%X\n", (void*)start, (void*)stack, stacksize);
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
typedef struct zydis_dec_s zydis_dec_t;
|
||||
typedef struct box86context_s box86context_t;
|
||||
typedef struct i386_ucontext_s i386_ucontext_t;
|
||||
|
||||
#define ERR_UNIMPL 1
|
||||
#define ERR_DIVBY0 2
|
||||
@ -76,6 +77,8 @@ typedef struct x86emu_s {
|
||||
void* init_stack; // initial stack (owned or not)
|
||||
uint32_t size_stack; // stack size (owned or not)
|
||||
|
||||
i386_ucontext_t *uc_link; // to handle setcontext
|
||||
|
||||
} x86emu_t;
|
||||
|
||||
//#define INTR_RAISE_DIV0(emu) {emu->error |= ERR_DIVBY0; emu->quit=1;}
|
||||
|
@ -1351,6 +1351,7 @@ stepout:
|
||||
|
||||
fini:
|
||||
// PackFlags(emu);
|
||||
// fork handling
|
||||
if(emu->fork) {
|
||||
if(step)
|
||||
return 0;
|
||||
@ -1360,5 +1361,11 @@ fini:
|
||||
emu = x86emu_fork(emu, forktype);
|
||||
goto x86emurun;
|
||||
}
|
||||
// setcontext handling
|
||||
else if(emu->uc_link) {
|
||||
emu->quit = 0;
|
||||
my_setcontext(emu, emu->uc_link);
|
||||
goto x86emurun;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -29,6 +29,7 @@ const char* DumpCPURegs(x86emu_t* emu, uintptr_t ip);
|
||||
|
||||
void StopEmu(x86emu_t* emu, const char* reason);
|
||||
void PushExit(x86emu_t* emu);
|
||||
void* GetExit();
|
||||
void EmuCall(x86emu_t* emu, uintptr_t addr);
|
||||
void AddCleanup(x86emu_t *emu, void *p);
|
||||
void AddCleanup1Arg(x86emu_t *emu, void *p, void* a);
|
||||
|
@ -94,10 +94,10 @@ typedef struct
|
||||
|
||||
typedef uint32_t i386_sigset_t;
|
||||
|
||||
typedef struct i386_ucontext_t
|
||||
typedef struct i386_ucontext_s
|
||||
{
|
||||
uint32_t uc_flags;
|
||||
struct i386_ucontext_t *uc_link;
|
||||
struct i386_ucontext_s *uc_link;
|
||||
i386_stack_t uc_stack;
|
||||
i386_mcontext_t uc_mcontext;
|
||||
i386_sigset_t uc_sigmask;
|
||||
@ -203,8 +203,11 @@ __attribute__((alias("my_sigaction")));
|
||||
|
||||
EXPORT int my_getcontext(x86emu_t* emu, void* ucp)
|
||||
{
|
||||
printf_log(LOG_NONE, "Warning: call to partially implemented getcontext\n");
|
||||
struct i386_ucontext_t *u = (struct i386_ucontext_t*)ucp;
|
||||
// printf_log(LOG_NONE, "Warning: call to partially implemented getcontext\n");
|
||||
i386_ucontext_t *u = (i386_ucontext_t*)ucp;
|
||||
// stack traking
|
||||
u->uc_stack.ss_sp = NULL;
|
||||
u->uc_stack.ss_size = 0; // this need to filled
|
||||
// get general register
|
||||
u->uc_mcontext.gregs[REG_EAX] = R_EAX;
|
||||
u->uc_mcontext.gregs[REG_ECX] = R_ECX;
|
||||
@ -226,8 +229,11 @@ EXPORT int my_getcontext(x86emu_t* emu, void* ucp)
|
||||
|
||||
EXPORT int my_setcontext(x86emu_t* emu, void* ucp)
|
||||
{
|
||||
printf_log(LOG_NONE, "Warning: call to partially implemented setcontext\n");
|
||||
struct i386_ucontext_t *u = (struct i386_ucontext_t*)ucp;
|
||||
// printf_log(LOG_NONE, "Warning: call to partially implemented setcontext\n");
|
||||
i386_ucontext_t *u = (i386_ucontext_t*)ucp;
|
||||
// stack tracking
|
||||
emu->init_stack = u->uc_stack.ss_sp;
|
||||
emu->size_stack = u->uc_stack.ss_size;
|
||||
// set general register
|
||||
R_EAX = u->uc_mcontext.gregs[REG_EAX];
|
||||
R_ECX = u->uc_mcontext.gregs[REG_ECX];
|
||||
@ -243,12 +249,41 @@ EXPORT int my_setcontext(x86emu_t* emu, void* ucp)
|
||||
// set FloatPoint status
|
||||
// set signal mask
|
||||
//sigprocmask(SIG_SETMASK, NULL, (sigset_t*)&u->uc_sigmask);
|
||||
// set uc_link
|
||||
emu->uc_link = u->uc_link;
|
||||
|
||||
return R_EAX;
|
||||
}
|
||||
|
||||
EXPORT int my_makecontext(x86emu_t* emu, void* ucp, void* fnc, int32_t argc, void* argv)
|
||||
EXPORT int my_makecontext(x86emu_t* emu, void* ucp, void* fnc, int32_t argc, int32_t* argv)
|
||||
{
|
||||
printf_log(LOG_NONE, "Warning: call to unimplemented makecontext\n");
|
||||
// printf_log(LOG_NONE, "Warning: call to unimplemented makecontext\n");
|
||||
i386_ucontext_t *u = (i386_ucontext_t*)ucp;
|
||||
// setup stack
|
||||
u->uc_mcontext.gregs[REG_ESP] = (uintptr_t)u->uc_stack.ss_sp + u->uc_stack.ss_size - 4;
|
||||
// setup the function
|
||||
u->uc_mcontext.gregs[REG_EIP] = (intptr_t)fnc;
|
||||
// setup args
|
||||
uint32_t* esp = (uint32_t*)u->uc_mcontext.gregs[REG_ESP];
|
||||
for (int i=0; i<argc; ++i) {
|
||||
// push value
|
||||
--esp;
|
||||
*esp = argv[(argc-1)-i];
|
||||
}
|
||||
// push the return value
|
||||
--esp;
|
||||
*esp = (uintptr_t)GetExit();
|
||||
u->uc_mcontext.gregs[REG_ESP] = (uintptr_t)esp;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXPORT int my_swapcontext(x86emu_t* emu, void* ucp1, void* ucp2)
|
||||
{
|
||||
// printf_log(LOG_NONE, "Warning: call to unimplemented swapcontext\n");
|
||||
// grab current context in ucp1
|
||||
my_getcontext(emu, ucp1);
|
||||
// activate ucp2
|
||||
my_setcontext(emu, ucp2);
|
||||
return 0;
|
||||
}
|
@ -517,8 +517,8 @@ typedef int32_t (*iFEippp_t)(x86emu_t*, int32_t, void*, void*, void*);
|
||||
typedef int32_t (*iFEpipp_t)(x86emu_t*, void*, int32_t, void*, void*);
|
||||
typedef int32_t (*iFEpupV_t)(x86emu_t*, void*, uint32_t, void*, void*);
|
||||
typedef int32_t (*iFEppii_t)(x86emu_t*, void*, void*, int32_t, int32_t);
|
||||
typedef int32_t (*iFEppiV_t)(x86emu_t*, void*, void*, int32_t, void*);
|
||||
typedef int32_t (*iFEpppp_t)(x86emu_t*, void*, void*, void*, void*);
|
||||
typedef int32_t (*iFEpppV_t)(x86emu_t*, void*, void*, void*, void*);
|
||||
typedef int32_t (*iFEppVV_t)(x86emu_t*, void*, void*, void*, void*);
|
||||
typedef int32_t (*iFiiipu_t)(int32_t, int32_t, int32_t, void*, uint32_t);
|
||||
typedef int32_t (*iFiiipp_t)(int32_t, int32_t, int32_t, void*, void*);
|
||||
@ -1441,8 +1441,8 @@ void iFEippp(x86emu_t *emu, uintptr_t fcn) { iFEippp_t fn = (iFEippp_t)fcn; R_EA
|
||||
void iFEpipp(x86emu_t *emu, uintptr_t fcn) { iFEpipp_t fn = (iFEpipp_t)fcn; R_EAX=fn(emu, *(void**)(R_ESP + 4), *(int32_t*)(R_ESP + 8), *(void**)(R_ESP + 12), *(void**)(R_ESP + 16)); }
|
||||
void iFEpupV(x86emu_t *emu, uintptr_t fcn) { iFEpupV_t fn = (iFEpupV_t)fcn; R_EAX=fn(emu, *(void**)(R_ESP + 4), *(uint32_t*)(R_ESP + 8), *(void**)(R_ESP + 12), (void*)(R_ESP + 16)); }
|
||||
void iFEppii(x86emu_t *emu, uintptr_t fcn) { iFEppii_t fn = (iFEppii_t)fcn; R_EAX=fn(emu, *(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(int32_t*)(R_ESP + 12), *(int32_t*)(R_ESP + 16)); }
|
||||
void iFEppiV(x86emu_t *emu, uintptr_t fcn) { iFEppiV_t fn = (iFEppiV_t)fcn; R_EAX=fn(emu, *(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(int32_t*)(R_ESP + 12), (void*)(R_ESP + 16)); }
|
||||
void iFEpppp(x86emu_t *emu, uintptr_t fcn) { iFEpppp_t fn = (iFEpppp_t)fcn; R_EAX=fn(emu, *(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(void**)(R_ESP + 12), *(void**)(R_ESP + 16)); }
|
||||
void iFEpppV(x86emu_t *emu, uintptr_t fcn) { iFEpppV_t fn = (iFEpppV_t)fcn; R_EAX=fn(emu, *(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(void**)(R_ESP + 12), (void*)(R_ESP + 16)); }
|
||||
void iFEppVV(x86emu_t *emu, uintptr_t fcn) { iFEppVV_t fn = (iFEppVV_t)fcn; R_EAX=fn(emu, *(void**)(R_ESP + 4), *(void**)(R_ESP + 8), (void*)(R_ESP + 12), (void*)(R_ESP + 12)); }
|
||||
void iFiiipu(x86emu_t *emu, uintptr_t fcn) { iFiiipu_t fn = (iFiiipu_t)fcn; R_EAX=fn(*(int32_t*)(R_ESP + 4), *(int32_t*)(R_ESP + 8), *(int32_t*)(R_ESP + 12), *(void**)(R_ESP + 16), *(uint32_t*)(R_ESP + 20)); }
|
||||
void iFiiipp(x86emu_t *emu, uintptr_t fcn) { iFiiipp_t fn = (iFiiipp_t)fcn; R_EAX=fn(*(int32_t*)(R_ESP + 4), *(int32_t*)(R_ESP + 8), *(int32_t*)(R_ESP + 12), *(void**)(R_ESP + 16), *(void**)(R_ESP + 20)); }
|
||||
|
@ -513,8 +513,8 @@ void iFEippp(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFEpipp(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFEpupV(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFEppii(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFEppiV(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFEpppp(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFEpppV(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFEppVV(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFiiipu(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFiiipp(x86emu_t *emu, uintptr_t fnc);
|
||||
|
@ -139,6 +139,7 @@ int EXPORT my_atexit(x86emu_t* emu, void *p)
|
||||
int my_getcontext(x86emu_t* emu, void* ucp);
|
||||
int my_setcontext(x86emu_t* emu, void* ucp);
|
||||
int my_makecontext(x86emu_t* emu, void* ucp, void* fnc, int32_t argc, void* argv);
|
||||
int my_swapcontext(x86emu_t* emu, void* ucp1, void* ucp2);
|
||||
|
||||
// All signal and context functions defined in signals.c
|
||||
|
||||
|
@ -1046,7 +1046,7 @@ GO(lsetxattr, iFpppui)
|
||||
GO(__lxstat, iFipp)
|
||||
GOM(__lxstat64, iFEipp)
|
||||
GO(madvise, iFpui)
|
||||
GOM(makecontext, iFEpppV)
|
||||
GOM(makecontext, iFEppiV)
|
||||
GOW(mallinfo, pFv)
|
||||
GO(malloc, pFu)
|
||||
// malloc_get_state // Weak
|
||||
@ -1728,7 +1728,7 @@ GO(strxfrm_l, uFppup)
|
||||
// svcunixfd_create
|
||||
// svc_unregister
|
||||
GO(swab, vFppi)
|
||||
GO(swapcontext, iFpp)
|
||||
GOM(swapcontext, iFEpp)
|
||||
// swapoff // Weak
|
||||
// swapon // Weak
|
||||
GOM(swprintf, iFEpupV)
|
||||
|
Loading…
Reference in New Issue
Block a user