mirror of
https://github.com/ptitSeb/box86.git
synced 2024-11-23 06:39:55 +00:00
Working on fork, with test.
This commit is contained in:
parent
4ff1f366f6
commit
332b2a4106
@ -137,3 +137,8 @@ add_test(test08 ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/box86
|
||||
-D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/test08 -D TEST_OUTPUT=tmpfile.txt
|
||||
-D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests/ref08.txt
|
||||
-P ${CMAKE_SOURCE_DIR}/runTest.cmake )
|
||||
|
||||
add_test(test09 ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/box86
|
||||
-D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/test09 -D TEST_OUTPUT=tmpfile.txt
|
||||
-D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests/ref09.txt
|
||||
-P ${CMAKE_SOURCE_DIR}/runTest.cmake )
|
||||
|
@ -4,7 +4,7 @@ import os
|
||||
import glob
|
||||
import sys
|
||||
|
||||
values = ['E', 'v', 'c', 'w', 'i', 'I', 'C', 'W', 'u', 'U', 'f', 'd', 'D', 'L', 'p', 'V']
|
||||
values = ['E', 'e', 'v', 'c', 'w', 'i', 'I', 'C', 'W', 'u', 'U', 'f', 'd', 'D', 'L', 'p', 'V']
|
||||
def splitchar(s):
|
||||
ret = [len(s)]
|
||||
i = 0
|
||||
@ -105,7 +105,7 @@ typedef void (*wrapper_t)(x86emu_t* emu, uintptr_t fnc);
|
||||
// v = void, i = int32, u = uint32, U/I= (u)int64
|
||||
// p = pointer, P = callback
|
||||
// f = float, d = double, D = long double, L = fake long double
|
||||
// V = vaargs, E = current x86emu struct
|
||||
// V = vaargs, E = current x86emu struct, e = ref to current x86emu struct
|
||||
// 0 = constant 0, 1 = constant 1
|
||||
// o = stdout
|
||||
// C = unsigned byte c = char
|
||||
@ -139,8 +139,8 @@ typedef void (*wrapper_t)(x86emu_t* emu, uintptr_t fnc);
|
||||
|
||||
# First part: typedefs
|
||||
for v in gbl:
|
||||
# E v c w i I C W u U f d D L p V
|
||||
types = ["x86emu_t*", "void", "int8_t", "int16_t", "int32_t", "int64_t", "uint8_t", "uint16_t", "uint32_t", "uint64_t", "float", "double", "long double", "double", "void*", "void*"]
|
||||
# E e v c w i I C W u U f d D L p V
|
||||
types = ["x86emu_t*", "x86emu_t**", "void", "int8_t", "int16_t", "int32_t", "int64_t", "uint8_t", "uint16_t", "uint32_t", "uint64_t", "float", "double", "long double", "double", "void*", "void*"]
|
||||
if len(values) != len(types):
|
||||
raise NotImplementedError("len(values) = {lenval} != len(types) = {lentypes}".format(lenval=len(values), lentypes=len(types)))
|
||||
|
||||
@ -163,6 +163,7 @@ typedef void (*wrapper_t)(x86emu_t* emu, uintptr_t fnc);
|
||||
|
||||
arg = [
|
||||
"emu, ", # E
|
||||
"&emu, ", # e
|
||||
"", # v
|
||||
"*(int8_t*)(R_ESP + {p}), ", # c
|
||||
"*(int16_t*)(R_ESP + {p}), ", # w
|
||||
@ -179,8 +180,8 @@ typedef void (*wrapper_t)(x86emu_t* emu, uintptr_t fnc);
|
||||
"*(void**)(R_ESP + {p}), ", # p
|
||||
"(void*)(R_ESP + {p}), " # V
|
||||
]
|
||||
# E v c w i I C W u U f d D L p V
|
||||
deltas = [0, 4, 4, 4, 4, 8, 4, 4, 4, 8, 4, 8, 12, 12, 4, 0]
|
||||
# E e v c w i I C W u U f d D L p V
|
||||
deltas = [0, 0, 4, 4, 4, 4, 8, 4, 4, 4, 8, 4, 8, 12, 12, 4, 0]
|
||||
if len(values) != len(arg):
|
||||
raise NotImplementedError("len(values) = {lenval} != len(arg) = {lenarg}".format(lenval=len(values), lenarg=len(arg)))
|
||||
if len(values) != len(deltas):
|
||||
@ -191,6 +192,7 @@ typedef void (*wrapper_t)(x86emu_t* emu, uintptr_t fnc);
|
||||
f.write("void {0}(x86emu_t *emu, uintptr_t fcn) {2} {1} fn = ({1})fcn; ".format(N, W, "{"))
|
||||
vals = [
|
||||
"\n#error Invalid return type: emulator\n", # E
|
||||
"\n#error Invalid return type: &emulator\n", # e
|
||||
"fn({0});", # v
|
||||
"R_EAX=fn({0});", # c
|
||||
"R_EAX=fn({0});", # w
|
||||
|
@ -42,6 +42,9 @@ void FreeBox86Context(box86context_t** context)
|
||||
if(!context)
|
||||
return;
|
||||
|
||||
if(--(*context)->forked >= 0)
|
||||
return;
|
||||
|
||||
if((*context)->emu)
|
||||
FreeX86Emu(&(*context)->emu);
|
||||
|
||||
|
@ -60,6 +60,8 @@ typedef struct box86context_s {
|
||||
library_t *sdl2lib; // shortcut to SDL2 library (if loaded)
|
||||
library_t *sdl2mixerlib;
|
||||
library_t *sdl2imagelib;
|
||||
|
||||
int forked; // how many forks... cleanup only when < 0
|
||||
} box86context_t;
|
||||
|
||||
box86context_t *NewBox86Context(int argc);
|
||||
|
@ -169,6 +169,8 @@ int RelocateElfREL(lib_t *maplib, elfheader_t* head, int cnt, Elf32_Rel *rel)
|
||||
printf_log(LOG_DEBUG, "Apply R_386_32 @%p with sym=%s (%p -> %p)\n", p, symname, *(void**)p, (void*)offs);
|
||||
*p = offs;
|
||||
break;
|
||||
//case R_386_TLS_DTPMOD32:
|
||||
// try to use _dl_next_tls_modid() ?
|
||||
case R_386_TLS_DTPOFF32:
|
||||
case R_386_JMP_SLOT:
|
||||
offs = FindGlobalSymbol(maplib, symname);
|
||||
@ -350,6 +352,7 @@ void AddGlobalsSymbols(kh_mapsymbols_t* mapsymbols, elfheader_t* h)
|
||||
if(( (h->SymTab[i].st_info == 18)
|
||||
|| (h->SymTab[i].st_info == 17)
|
||||
|| (h->SymTab[i].st_info == 34)
|
||||
|| (h->SymTab[i].st_info == 22)
|
||||
|| (h->SymTab[i].st_info == 2))
|
||||
&& (h->SymTab[i].st_other==0) && (h->SymTab[i].st_shndx!=0)) {
|
||||
const char * symname = h->StrTab+h->SymTab[i].st_name;
|
||||
@ -365,6 +368,7 @@ void AddGlobalsSymbols(kh_mapsymbols_t* mapsymbols, elfheader_t* h)
|
||||
if(( (h->DynSym[i].st_info == 18)
|
||||
|| (h->DynSym[i].st_info == 17)
|
||||
|| (h->DynSym[i].st_info == 34)
|
||||
|| (h->DynSym[i].st_info == 22)
|
||||
|| (h->DynSym[i].st_info == 2))
|
||||
&& (h->DynSym[i].st_other==0) && (h->DynSym[i].st_shndx!=0 && h->DynSym[i].st_shndx<62521)) {
|
||||
const char * symname = h->DynStr+h->DynSym[i].st_name;
|
||||
|
@ -92,13 +92,17 @@ sighandler_t EXPORT my_signal(x86emu_t* emu, int signum, sighandler_t handler)
|
||||
}
|
||||
sighandler_t EXPORT my___sysv_signal(x86emu_t* emu, int signum, sighandler_t handler) __attribute__((alias("my_signal")));
|
||||
sighandler_t EXPORT my_sysv_signal(x86emu_t* emu, int signum, sighandler_t handler) __attribute__((alias("my_signal")));
|
||||
pid_t EXPORT my_fork()
|
||||
pid_t EXPORT my_fork(x86emu_t* emu)
|
||||
{
|
||||
// should be doable, but the x86emu stack has to be dedup for the child
|
||||
printf_log(LOG_NONE, "Warning, Ignoring fork()\n");
|
||||
return EAGAIN;
|
||||
#if 1
|
||||
emu->quit = 1;
|
||||
emu->fork = 1;
|
||||
return 0;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
pid_t EXPORT my___fork() __attribute__((alias("my_fork")));
|
||||
pid_t EXPORT my___fork(x86emu_t* emu) __attribute__((alias("my_fork")));
|
||||
|
||||
EXPORT void* my__ZGTtnaX (size_t a) { printf("warning _ZGTtnaX called\n"); return NULL; }
|
||||
EXPORT void my__ZGTtdlPv (void* a) { printf("warning _ZGTtdlPv called\n"); }
|
||||
@ -291,6 +295,13 @@ EXPORT void my_qsort_r(x86emu_t* emu, void* base, size_t nmemb, size_t size, voi
|
||||
FreeCallback(cbemu);
|
||||
}
|
||||
|
||||
EXPORT int32_t my_execvp(x86emu_t* emu, void* a, void* b, va_list v)
|
||||
{
|
||||
printf("execvp(%s, %p)\n", (const char*)a, b);
|
||||
return execvp(a, b);
|
||||
}
|
||||
EXPORT int32_t my_execlp(x86emu_t* emu, void* a, void* b, va_list v) __attribute__((alias("my_execvp")));
|
||||
|
||||
#define LIBNAME libc
|
||||
const char* libcName = "libc.so.6";
|
||||
|
||||
|
@ -268,10 +268,10 @@ GO(__errno_location, pFv)
|
||||
// eventfd_write
|
||||
// execl
|
||||
// execle
|
||||
GO2(execlp, iFppV, execvp) // is that correct?
|
||||
GOM(execlp, iFEpVV)
|
||||
GO(execv, iFpp) // maybe need to GOM this one, and check if path is an x86 file...
|
||||
// execve // Weak
|
||||
GO(execvp, iFpp) // same remark as for execv
|
||||
GOM(execvp, iFEpVV)
|
||||
GOM(exit, vFEi)
|
||||
GOM(_exit, vFEi)
|
||||
// _Exit // Weak
|
||||
@ -345,8 +345,8 @@ GO(fileno, iFp)
|
||||
GO(fopen, pFpp)
|
||||
GOW(fopen64, pFpp)
|
||||
// fopencookie
|
||||
GOM(fork, pFE) // Weak
|
||||
GOM(__fork, pFE)
|
||||
GOM(fork, iFEv) // Weak
|
||||
GOM(__fork, iFEv)
|
||||
// __fortify_fail
|
||||
// fpathconf // Weak
|
||||
// __fpending
|
||||
|
@ -24,6 +24,7 @@ typedef void (*vFu_t)(uint32_t);
|
||||
typedef void (*vFf_t)(float);
|
||||
typedef void (*vFd_t)(double);
|
||||
typedef void (*vFp_t)(void*);
|
||||
typedef int32_t (*iFE_t)(x86emu_t*);
|
||||
typedef int32_t (*iFv_t)(void);
|
||||
typedef int32_t (*iFi_t)(int32_t);
|
||||
typedef int32_t (*iFu_t)(uint32_t);
|
||||
@ -622,6 +623,7 @@ void vFu(x86emu_t *emu, uintptr_t fcn) { vFu_t fn = (vFu_t)fcn; fn(*(uint32_t*)(
|
||||
void vFf(x86emu_t *emu, uintptr_t fcn) { vFf_t fn = (vFf_t)fcn; fn(*(float*)(R_ESP + 4)); }
|
||||
void vFd(x86emu_t *emu, uintptr_t fcn) { vFd_t fn = (vFd_t)fcn; fn(*(double*)(R_ESP + 4)); }
|
||||
void vFp(x86emu_t *emu, uintptr_t fcn) { vFp_t fn = (vFp_t)fcn; fn(*(void**)(R_ESP + 4)); }
|
||||
void iFE(x86emu_t *emu, uintptr_t fcn) { iFE_t fn = (iFE_t)fcn; R_EAX=fn(emu); }
|
||||
void iFv(x86emu_t *emu, uintptr_t fcn) { iFv_t fn = (iFv_t)fcn; R_EAX=fn(); }
|
||||
void iFi(x86emu_t *emu, uintptr_t fcn) { iFi_t fn = (iFi_t)fcn; R_EAX=fn(*(int32_t*)(R_ESP + 4)); }
|
||||
void iFu(x86emu_t *emu, uintptr_t fcn) { iFu_t fn = (iFu_t)fcn; R_EAX=fn(*(uint32_t*)(R_ESP + 4)); }
|
||||
@ -1213,8 +1215,9 @@ void vFuffiiffiiffiip(x86emu_t *emu, uintptr_t fcn) { vFuffiiffiiffiip_t fn = (v
|
||||
void vFuddiiddiiddiip(x86emu_t *emu, uintptr_t fcn) { vFuddiiddiiddiip_t fn = (vFuddiiddiiddiip_t)fcn; fn(*(uint32_t*)(R_ESP + 4), *(double*)(R_ESP + 8), *(double*)(R_ESP + 16), *(int32_t*)(R_ESP + 24), *(int32_t*)(R_ESP + 28), *(double*)(R_ESP + 32), *(double*)(R_ESP + 40), *(int32_t*)(R_ESP + 48), *(int32_t*)(R_ESP + 52), *(double*)(R_ESP + 56), *(double*)(R_ESP + 64), *(int32_t*)(R_ESP + 72), *(int32_t*)(R_ESP + 76), *(void**)(R_ESP + 80)); }
|
||||
void vFuuiiiiuuiiiiiii(x86emu_t *emu, uintptr_t fcn) { vFuuiiiiuuiiiiiii_t fn = (vFuuiiiiuuiiiiiii_t)fcn; fn(*(uint32_t*)(R_ESP + 4), *(uint32_t*)(R_ESP + 8), *(int32_t*)(R_ESP + 12), *(int32_t*)(R_ESP + 16), *(int32_t*)(R_ESP + 20), *(int32_t*)(R_ESP + 24), *(uint32_t*)(R_ESP + 28), *(uint32_t*)(R_ESP + 32), *(int32_t*)(R_ESP + 36), *(int32_t*)(R_ESP + 40), *(int32_t*)(R_ESP + 44), *(int32_t*)(R_ESP + 48), *(int32_t*)(R_ESP + 52), *(int32_t*)(R_ESP + 56), *(int32_t*)(R_ESP + 60)); }
|
||||
void vFfffffffffffffff(x86emu_t *emu, uintptr_t fcn) { vFfffffffffffffff_t fn = (vFfffffffffffffff_t)fcn; fn(*(float*)(R_ESP + 4), *(float*)(R_ESP + 8), *(float*)(R_ESP + 12), *(float*)(R_ESP + 16), *(float*)(R_ESP + 20), *(float*)(R_ESP + 24), *(float*)(R_ESP + 28), *(float*)(R_ESP + 32), *(float*)(R_ESP + 36), *(float*)(R_ESP + 40), *(float*)(R_ESP + 44), *(float*)(R_ESP + 48), *(float*)(R_ESP + 52), *(float*)(R_ESP + 56), *(float*)(R_ESP + 60)); }
|
||||
void iFEpvpVV(x86emu_t *emu, uintptr_t fcn) { iFEppVV_t fn = (iFEppVV_t)fcn; R_EAX=fn(emu, *(void**)(R_ESP + 4), *(void**)(R_ESP + 12), (void*)(R_ESP + 16), (void*)(R_ESP + 16)); }
|
||||
void iFEpvvpVV(x86emu_t *emu, uintptr_t fcn) { iFEppVV_t fn = (iFEppVV_t)fcn; R_EAX=fn(emu, *(void**)(R_ESP + 4), *(void**)(R_ESP + 16), (void*)(R_ESP + 20), (void*)(R_ESP + 20)); }
|
||||
void iFEvpVV(x86emu_t *emu, uintptr_t fcn) { iFEpVV_t fn = (iFEpVV_t)fcn; R_EAX=fn(emu, *(void**)(R_ESP + 8), (void*)(R_ESP + 12), (void*)(R_ESP + 12)); }
|
||||
void iFEv(x86emu_t *emu, uintptr_t fcn) { iFE_t fn = (iFE_t)fcn; R_EAX=fn(emu); }
|
||||
void pFEv(x86emu_t *emu, uintptr_t fcn) { pFE_t fn = (pFE_t)fcn; R_EAX=(uintptr_t)fn(emu); }
|
||||
void iFEpuvvpVV(x86emu_t *emu, uintptr_t fcn) { iFEpupVV_t fn = (iFEpupVV_t)fcn; R_EAX=fn(emu, *(void**)(R_ESP + 4), *(uint32_t*)(R_ESP + 8), *(void**)(R_ESP + 20), (void*)(R_ESP + 24), (void*)(R_ESP + 24)); }
|
||||
void iFEpvpVV(x86emu_t *emu, uintptr_t fcn) { iFEppVV_t fn = (iFEppVV_t)fcn; R_EAX=fn(emu, *(void**)(R_ESP + 4), *(void**)(R_ESP + 12), (void*)(R_ESP + 16), (void*)(R_ESP + 16)); }
|
||||
void iFEpvvpVV(x86emu_t *emu, uintptr_t fcn) { iFEppVV_t fn = (iFEppVV_t)fcn; R_EAX=fn(emu, *(void**)(R_ESP + 4), *(void**)(R_ESP + 16), (void*)(R_ESP + 20), (void*)(R_ESP + 20)); }
|
||||
|
@ -14,7 +14,7 @@ typedef void (*wrapper_t)(x86emu_t* emu, uintptr_t fnc);
|
||||
// v = void, i = int32, u = uint32, U/I= (u)int64
|
||||
// p = pointer, P = callback
|
||||
// f = float, d = double, D = long double, L = fake long double
|
||||
// V = vaargs, E = current x86emu struct
|
||||
// V = vaargs, E = current x86emu struct, e = ref to current x86emu struct
|
||||
// 0 = constant 0, 1 = constant 1
|
||||
// o = stdout
|
||||
// C = unsigned byte c = char
|
||||
@ -29,6 +29,7 @@ void vFu(x86emu_t *emu, uintptr_t fnc);
|
||||
void vFf(x86emu_t *emu, uintptr_t fnc);
|
||||
void vFd(x86emu_t *emu, uintptr_t fnc);
|
||||
void vFp(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFE(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFv(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFi(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFu(x86emu_t *emu, uintptr_t fnc);
|
||||
@ -620,10 +621,11 @@ void vFuffiiffiiffiip(x86emu_t *emu, uintptr_t fnc);
|
||||
void vFuddiiddiiddiip(x86emu_t *emu, uintptr_t fnc);
|
||||
void vFuuiiiiuuiiiiiii(x86emu_t *emu, uintptr_t fnc);
|
||||
void vFfffffffffffffff(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFEpvpVV(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFEpvvpVV(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFEvpVV(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFEv(x86emu_t *emu, uintptr_t fnc);
|
||||
void pFEv(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFEpuvvpVV(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFEpvpVV(x86emu_t *emu, uintptr_t fnc);
|
||||
void iFEpvvpVV(x86emu_t *emu, uintptr_t fnc);
|
||||
|
||||
#endif //__WRAPPER_H_
|
||||
|
32
src/x86emu.c
32
src/x86emu.c
@ -125,10 +125,42 @@ void FreeX86Emu(x86emu_t **emu)
|
||||
|
||||
free((*emu)->scratch);
|
||||
|
||||
free((*emu)->stack);
|
||||
|
||||
free(*emu);
|
||||
*emu = NULL;
|
||||
}
|
||||
|
||||
void CloneEmu(x86emu_t *newemu, const x86emu_t* emu)
|
||||
{
|
||||
memcpy(newemu->regs, emu->regs, sizeof(emu->regs));
|
||||
memcpy(&newemu->ip, &emu->ip, sizeof(emu->ip));
|
||||
memcpy(&newemu->eflags, &emu->eflags, sizeof(emu->eflags));
|
||||
newemu->old_ip = emu->old_ip;
|
||||
memcpy(newemu->segs, emu->segs, sizeof(emu->segs));
|
||||
memcpy(newemu->fpu, emu->fpu, sizeof(emu->fpu));
|
||||
memcpy(newemu->fpu_ld, emu->fpu_ld, sizeof(emu->fpu_ld));
|
||||
memcpy(newemu->fpu_ll, emu->fpu_ll, sizeof(emu->fpu_ll));
|
||||
memcpy(newemu->p_regs, emu->p_regs, sizeof(emu->p_regs));
|
||||
newemu->cw = emu->cw;
|
||||
newemu->cw_mask_all = emu->cw_mask_all;
|
||||
memcpy(&newemu->sw, &emu->sw, sizeof(emu->sw));
|
||||
newemu->top = emu->top;
|
||||
newemu->fpu_stack = emu->fpu_stack;
|
||||
memcpy(&newemu->round, &emu->round, sizeof(emu->round));
|
||||
memcpy(newemu->mmx, emu->mmx, sizeof(emu->mmx));
|
||||
memcpy(newemu->xmm, emu->xmm, sizeof(emu->xmm));
|
||||
newemu->mxcsr = emu->mxcsr;
|
||||
memcpy(&newemu->zero, &emu->zero, sizeof(emu->zero));
|
||||
memcpy(newemu->sbiidx, emu->sbiidx, sizeof(emu->sbiidx));
|
||||
newemu->quit = emu->quit;
|
||||
newemu->error = emu->error;
|
||||
// addapt R_ESP to new stack frame
|
||||
uintptr_t oldst = (uintptr_t)((emu->stack)?emu->stack:emu->context->stack);
|
||||
uintptr_t newst = (uintptr_t)((newemu->stack)?newemu->stack:newemu->context->stack);
|
||||
newemu->regs[_SP].dword[0] = emu->regs[_SP].dword[0] + (intptr_t)(newst - oldst);
|
||||
}
|
||||
|
||||
uint32_t GetEAX(x86emu_t *emu)
|
||||
{
|
||||
return R_EAX;
|
||||
|
@ -8,6 +8,7 @@ x86emu_t *NewX86Emu(box86context_t *context, uintptr_t start, uintptr_t stack, i
|
||||
void SetupX86Emu(x86emu_t *emu, int* shared_gloabl, void* globals);
|
||||
void SetTraceEmu(x86emu_t *emu, uintptr_t trace_start, uintptr_t trace_end);
|
||||
void FreeX86Emu(x86emu_t **x86emu);
|
||||
void CloneEmu(x86emu_t *newemu, const x86emu_t* emu);
|
||||
|
||||
uint32_t GetEAX(x86emu_t *emu);
|
||||
void SetEAX(x86emu_t *emu, uint32_t v);
|
||||
|
@ -38,6 +38,7 @@ typedef struct x86emu_s {
|
||||
// emu control
|
||||
int quit;
|
||||
int error;
|
||||
int fork; // quit because need to fork
|
||||
// trace
|
||||
zydis_dec_t *dec;
|
||||
uintptr_t trace_start, trace_end;
|
||||
@ -52,6 +53,8 @@ typedef struct x86emu_s {
|
||||
int clean_cap;
|
||||
// scratch stack, used for alignement of double and 64bits ints on arm
|
||||
uint32_t *scratch;
|
||||
// local stack, do be deleted when emu is freed
|
||||
void* stack;
|
||||
|
||||
} x86emu_t;
|
||||
|
||||
|
@ -2,6 +2,8 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "stack.h"
|
||||
@ -14,6 +16,31 @@
|
||||
#include "wrapper.h"
|
||||
#include "box86context.h"
|
||||
|
||||
x86emu_t* x86emu_fork(x86emu_t* e)
|
||||
{
|
||||
x86emu_t *emu = e;
|
||||
// lets duplicate the emu
|
||||
void* newstack = 0;
|
||||
posix_memalign(&newstack, emu->context->stackalign, emu->context->stacksz);
|
||||
memcpy(newstack, emu->context->stack, emu->context->stacksz);
|
||||
x86emu_t* newemu = NewX86Emu(emu->context, R_EIP, (uintptr_t)newstack, emu->context->stacksz);
|
||||
SetupX86Emu(newemu, emu->shared_global, emu->globals);
|
||||
CloneEmu(newemu, emu);
|
||||
emu->stack = newstack;
|
||||
// ready to fork
|
||||
++emu->context->forked;
|
||||
int v = fork();
|
||||
if(!v) {
|
||||
emu = newemu;
|
||||
}
|
||||
if(v==EAGAIN || v==ENOMEM) {
|
||||
--emu->context->forked;
|
||||
FreeX86Emu(&newemu); // fork failed, free the new emu
|
||||
}
|
||||
R_EAX = v;
|
||||
return emu;
|
||||
}
|
||||
|
||||
void x86Int3(x86emu_t* emu)
|
||||
{
|
||||
if(Peek(emu, 0)=='S' && Peek(emu, 1)=='C') // Signature for "Out of x86 door"
|
||||
|
@ -17,6 +17,7 @@ int Run(x86emu_t *emu)
|
||||
{
|
||||
//ref opcode: http://ref.x86asm.net/geek32.html#xA1
|
||||
printf_log(LOG_DEBUG, "Run X86, EIP=%p, Stack=%p\n", (void*)R_EIP, emu->context->stack);
|
||||
x86emurun:
|
||||
emu->quit = 0;
|
||||
while (!emu->quit)
|
||||
{
|
||||
@ -1057,4 +1058,9 @@ int Run(x86emu_t *emu)
|
||||
UnimpOpcode(emu);
|
||||
}
|
||||
}
|
||||
if(emu->fork) {
|
||||
emu->fork = 0;
|
||||
emu = x86emu_fork(emu);
|
||||
goto x86emurun;
|
||||
}
|
||||
}
|
||||
|
@ -34,6 +34,7 @@ void RunF30F(x86emu_t *emu);
|
||||
|
||||
void x86Syscall(x86emu_t *emu);
|
||||
void x86Int3(x86emu_t* emu);
|
||||
x86emu_t* x86emu_fork(x86emu_t* e);
|
||||
|
||||
const char* GetNativeName(void* p);
|
||||
|
||||
|
30
src/x87run.c
30
src/x87run.c
@ -316,29 +316,47 @@ void RunD9(x86emu_t *emu)
|
||||
ST0.d = 0.0;
|
||||
break;
|
||||
|
||||
case 0xF2: /* FTAN */
|
||||
ST0.d = tan(ST0.d);
|
||||
fpu_do_push(emu);
|
||||
ST0.d = 1.0;
|
||||
break;
|
||||
case 0xF3: /* FPATAN */
|
||||
ST(1).d = atan2(ST(1).d, ST0.d);
|
||||
fpu_do_pop(emu);
|
||||
break;
|
||||
|
||||
case 0xFA: /* FSQRT */
|
||||
ST0.d = sqrt(ST0.d);
|
||||
break;
|
||||
|
||||
case 0xFB: /* FSINCOS */
|
||||
d = ST0.d;
|
||||
ST0.d = sin(d);
|
||||
fpu_do_push(emu);
|
||||
ST0.d = cos(d);
|
||||
break;
|
||||
case 0xFC: /* FRNDINT */
|
||||
ST0.d = fpu_round(emu, ST0.d);
|
||||
break;
|
||||
|
||||
case 0xFE: /* FSIN */
|
||||
ST0.d = sin(ST0.d);
|
||||
break;
|
||||
case 0xFF: /* FCOS */
|
||||
ST0.d = cos(ST0.d);
|
||||
break;
|
||||
|
||||
|
||||
case 0xE4:
|
||||
case 0xF0:
|
||||
case 0xF1:
|
||||
case 0xF2:
|
||||
case 0xF3:
|
||||
case 0xF4:
|
||||
case 0xF5:
|
||||
case 0xF6:
|
||||
case 0xF7:
|
||||
case 0xF8:
|
||||
case 0xF9:
|
||||
case 0xFB:
|
||||
case 0xFD:
|
||||
case 0xFE:
|
||||
case 0xFF:
|
||||
UnimpOpcode(emu);
|
||||
break;
|
||||
default:
|
||||
|
2
tests/ref09.txt
Normal file
2
tests/ref09.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Child has x = 2
|
||||
Parent has x = 0
|
BIN
tests/test09
Executable file
BIN
tests/test09
Executable file
Binary file not shown.
20
tests/test09.c
Executable file
20
tests/test09.c
Executable file
@ -0,0 +1,20 @@
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
void forkexample()
|
||||
{
|
||||
int x = 1;
|
||||
|
||||
if (fork() == 0)
|
||||
printf("Child has x = %d\n", ++x);
|
||||
else {
|
||||
usleep(20000);
|
||||
printf("Parent has x = %d\n", --x);
|
||||
}
|
||||
}
|
||||
int main()
|
||||
{
|
||||
forkexample();
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user