mirror of
https://github.com/ptitSeb/box64.git
synced 2024-11-24 06:59:53 +00:00
Reworked FPU/MMX regs, added Context and Signal handling (and test13 works)
This commit is contained in:
parent
395d9eb622
commit
2a514f14c1
@ -127,6 +127,7 @@ set(ELFLOADER_SRC
|
||||
"${BOX64_ROOT}/src/librarian/library.c"
|
||||
"${BOX64_ROOT}/src/libtools/auxval.c"
|
||||
"${BOX64_ROOT}/src/libtools/myalign.c"
|
||||
"${BOX64_ROOT}/src/libtools/signals.c"
|
||||
"${BOX64_ROOT}/src/libtools/threads.c"
|
||||
"${BOX64_ROOT}/src/tools/box64stack.c"
|
||||
"${BOX64_ROOT}/src/tools/bridge.c"
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "library.h"
|
||||
#include "wrapper.h"
|
||||
#include "x64emu.h"
|
||||
#include "signals.h"
|
||||
|
||||
EXPORTDYN
|
||||
void initAllHelpers(box64context_t* context)
|
||||
@ -26,7 +27,7 @@ void initAllHelpers(box64context_t* context)
|
||||
return;
|
||||
my_context = context;
|
||||
init_pthread_helper();
|
||||
//init_signal_helper(context);
|
||||
init_signal_helper(context);
|
||||
inited = 1;
|
||||
}
|
||||
|
||||
@ -37,7 +38,7 @@ void finiAllHelpers(box64context_t* context)
|
||||
if(finied)
|
||||
return;
|
||||
fini_pthread_helper(context);
|
||||
//fini_signal_helper();
|
||||
fini_signal_helper();
|
||||
cleanAlternate();
|
||||
fini_custommem_helper(context);
|
||||
finied = 1;
|
||||
|
@ -205,7 +205,7 @@ void CloneEmu(x64emu_t *newemu, const x64emu_t* emu)
|
||||
newemu->old_ip = emu->old_ip;
|
||||
memcpy(newemu->segs, emu->segs, sizeof(emu->segs));
|
||||
memset(newemu->segs_serial, 0, sizeof(newemu->segs_serial));
|
||||
memcpy(newemu->fpu, emu->fpu, sizeof(emu->fpu));
|
||||
memcpy(newemu->mmx87, emu->mmx87, sizeof(emu->mmx87));
|
||||
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));
|
||||
@ -215,7 +215,6 @@ void CloneEmu(x64emu_t *newemu, const x64emu_t* emu)
|
||||
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;
|
||||
newemu->quit = emu->quit;
|
||||
@ -336,7 +335,7 @@ const char* DumpCPURegs(x64emu_t* emu, uintptr_t ip)
|
||||
if(trace_emm) {
|
||||
// do emm reg is needed
|
||||
for(int i=0; i<8; ++i) {
|
||||
sprintf(tmp, "mm%d:%016lx", i, emu->mmx[i].q);
|
||||
sprintf(tmp, "mm%d:%016lx", i, emu->mmx87[i].q);
|
||||
strcat(buff, tmp);
|
||||
if ((i&3)==3) strcat(buff, "\n"); else strcat(buff, " ");
|
||||
}
|
||||
@ -352,7 +351,7 @@ const char* DumpCPURegs(x64emu_t* emu, uintptr_t ip)
|
||||
// start with FPU regs...
|
||||
if(emu->fpu_stack) {
|
||||
for (int i=0; i<emu->fpu_stack; i++) {
|
||||
sprintf(tmp, "ST%d=%f", i, emu->fpu[(emu->top+i)&7].d);
|
||||
sprintf(tmp, "ST%d=%f", i, emu->mmx87[(emu->top+i)&7].d);
|
||||
strcat(buff, tmp);
|
||||
int c = 10-strlen(tmp);
|
||||
if(c<1) c=1;
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include "regs.h"
|
||||
|
||||
typedef struct box64context_s box64context_t;
|
||||
//typedef struct i386_ucontext_s i386_ucontext_t;
|
||||
typedef struct x64_ucontext_s x64_ucontext_t;
|
||||
|
||||
#define ERR_UNIMPL 1
|
||||
#define ERR_DIVBY0 2
|
||||
@ -29,18 +29,16 @@ typedef struct x64emu_s {
|
||||
x86flags_t eflags;
|
||||
reg64_t ip;
|
||||
uintptr_t old_ip;
|
||||
// fpu
|
||||
fpu_reg_t fpu[9];
|
||||
// fpu / mmx
|
||||
mmx87_regs_t mmx87[8];
|
||||
uint16_t cw,cw_mask_all;
|
||||
x87flags_t sw;
|
||||
uint32_t top; // top is part of sw, but it's faster to have it separatly
|
||||
int fpu_stack;
|
||||
fpu_round_t round;
|
||||
fpu_ld_t fpu_ld[9]; // for long double emulation / 80bits fld fst
|
||||
fpu_ll_t fpu_ll[9]; // for 64bits fild / fist sequence
|
||||
fpu_p_reg_t p_regs[9];
|
||||
// mmx
|
||||
mmx_regs_t mmx[8];
|
||||
fpu_ld_t fpu_ld[8]; // for long double emulation / 80bits fld fst
|
||||
fpu_ll_t fpu_ll[8]; // for 64bits fild / fist sequence
|
||||
fpu_p_reg_t p_regs[8];
|
||||
// sse
|
||||
sse_regs_t xmm[16];
|
||||
uint32_t mxcsr;
|
||||
@ -77,7 +75,7 @@ typedef struct x64emu_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
|
||||
x64_ucontext_t *uc_link; // to handle setcontext
|
||||
|
||||
int type; // EMUTYPE_xxx define
|
||||
|
||||
|
@ -18,9 +18,8 @@
|
||||
#include "x64trace.h"
|
||||
#include "x87emu_private.h"
|
||||
#include "box64context.h"
|
||||
//#include "my_cpuid.h"
|
||||
#include "bridge.h"
|
||||
//#include "signals.h"
|
||||
#include "signals.h"
|
||||
#ifdef DYNAREC
|
||||
#include "../dynarec/arm_lock_helper.h"
|
||||
#endif
|
||||
@ -844,10 +843,10 @@ fini:
|
||||
goto x64emurun;
|
||||
}
|
||||
// setcontext handling
|
||||
// else if(emu->uc_link) {
|
||||
// emu->quit = 0;
|
||||
// my_setcontext(emu, emu->uc_link);
|
||||
// goto x64emurun;
|
||||
// }
|
||||
else if(emu->uc_link) {
|
||||
emu->quit = 0;
|
||||
my_setcontext(emu, emu->uc_link);
|
||||
goto x64emurun;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -1147,12 +1147,12 @@ reg64_t* GetEw16off(x64emu_t *emu, rex_t rex, uint8_t v, uintptr_t offset)
|
||||
}
|
||||
}
|
||||
|
||||
mmx_regs_t* GetEm(x64emu_t *emu, rex_t rex, uint8_t v, uint8_t delta)
|
||||
mmx87_regs_t* GetEm(x64emu_t *emu, rex_t rex, uint8_t v, uint8_t delta)
|
||||
{
|
||||
uint8_t m = v&0xC7; // filter Ed
|
||||
if(m>=0xC0) {
|
||||
return &emu->mmx[m&0x07];
|
||||
} else return (mmx_regs_t*)GetECommon(emu, rex, m, delta);
|
||||
return &emu->mmx87[m&0x07];
|
||||
} else return (mmx87_regs_t*)GetECommon(emu, rex, m, delta);
|
||||
}
|
||||
|
||||
sse_regs_t* GetEx(x64emu_t *emu, rex_t rex, uint8_t v, uint8_t delta)
|
||||
@ -1178,10 +1178,10 @@ reg64_t* GetGb(x64emu_t *emu, rex_t rex, uint8_t v)
|
||||
return (reg64_t*)&emu->regs[m&3].byte[m>>2];
|
||||
}
|
||||
|
||||
mmx_regs_t* GetGm(x64emu_t *emu, rex_t rex, uint8_t v)
|
||||
mmx87_regs_t* GetGm(x64emu_t *emu, rex_t rex, uint8_t v)
|
||||
{
|
||||
uint8_t m = (v&0x38)>>3;
|
||||
return &emu->mmx[m&7];
|
||||
return &emu->mmx87[m&7];
|
||||
}
|
||||
|
||||
sse_regs_t* GetGx(x64emu_t *emu, rex_t rex, uint8_t v)
|
||||
|
@ -82,12 +82,12 @@ reg64_t* GetEdO(x64emu_t *emu, rex_t rex, uint8_t v, uint8_t delta, uintptr_t of
|
||||
#define GetEw GetEd
|
||||
reg64_t* GetEw16(x64emu_t *emu, rex_t rex, uint8_t v);
|
||||
reg64_t* GetEw16off(x64emu_t *emu, rex_t rex, uint8_t v, uintptr_t offset);
|
||||
mmx_regs_t* GetEm(x64emu_t *emu, rex_t rex, uint8_t v, uint8_t delta);
|
||||
mmx87_regs_t* GetEm(x64emu_t *emu, rex_t rex, uint8_t v, uint8_t delta);
|
||||
sse_regs_t* GetEx(x64emu_t *emu, rex_t rex, uint8_t v, uint8_t delta);
|
||||
reg64_t* GetGd(x64emu_t *emu, rex_t rex, uint8_t v);
|
||||
#define GetGw GetGd
|
||||
reg64_t* GetGb(x64emu_t *emu, rex_t rex, uint8_t v);
|
||||
mmx_regs_t* GetGm(x64emu_t *emu, rex_t rex, uint8_t v);
|
||||
mmx87_regs_t* GetGm(x64emu_t *emu, rex_t rex, uint8_t v);
|
||||
sse_regs_t* GetGx(x64emu_t *emu, rex_t rex, uint8_t v);
|
||||
|
||||
void UpdateFlags(x64emu_t *emu);
|
||||
|
@ -45,9 +45,9 @@ int RunD9(x64emu_t *emu, rex_t rex)
|
||||
case 0xC5:
|
||||
case 0xC6:
|
||||
case 0xC7: /* FLD STx */
|
||||
ll = ST(nextop&7).ll;
|
||||
ll = ST(nextop&7).q;
|
||||
fpu_do_push(emu);
|
||||
ST0.ll = ll;
|
||||
ST0.q = ll;
|
||||
break;
|
||||
case 0xC8:
|
||||
case 0xC9:
|
||||
@ -57,9 +57,9 @@ int RunD9(x64emu_t *emu, rex_t rex)
|
||||
case 0xCD:
|
||||
case 0xCE:
|
||||
case 0xCF: /* FXCH STx */
|
||||
ll = ST(nextop&7).ll;
|
||||
ST(nextop&7).ll = ST0.ll;
|
||||
ST0.ll = ll;
|
||||
ll = ST(nextop&7).q;
|
||||
ST(nextop&7).q = ST0.q;
|
||||
ST0.q = ll;
|
||||
break;
|
||||
|
||||
case 0xD0: /* FNOP */
|
||||
|
@ -45,7 +45,7 @@ int RunDB(x64emu_t *emu, rex_t rex)
|
||||
case 0xC7:
|
||||
CHECK_FLAGS(emu);
|
||||
if(!ACCESS_FLAG(F_CF))
|
||||
ST0.ll = ST(nextop&7).ll;
|
||||
ST0.q = ST(nextop&7).q;
|
||||
break;
|
||||
case 0xC8: /* FCMOVNE ST(0), ST(i) */
|
||||
case 0xC9:
|
||||
@ -57,7 +57,7 @@ int RunDB(x64emu_t *emu, rex_t rex)
|
||||
case 0xCF:
|
||||
CHECK_FLAGS(emu);
|
||||
if(!ACCESS_FLAG(F_ZF))
|
||||
ST0.ll = ST(nextop&7).ll;
|
||||
ST0.q = ST(nextop&7).q;
|
||||
break;
|
||||
case 0xD0: /* FCMOVNBE ST(0), ST(i) */
|
||||
case 0xD1:
|
||||
@ -69,7 +69,7 @@ int RunDB(x64emu_t *emu, rex_t rex)
|
||||
case 0xD7:
|
||||
CHECK_FLAGS(emu);
|
||||
if(!(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF)))
|
||||
ST0.ll = ST(nextop&7).ll;
|
||||
ST0.q = ST(nextop&7).q;
|
||||
break;
|
||||
case 0xD8: /* FCMOVNU ST(0), ST(i) */
|
||||
case 0xD9:
|
||||
@ -81,7 +81,7 @@ int RunDB(x64emu_t *emu, rex_t rex)
|
||||
case 0xDF:
|
||||
CHECK_FLAGS(emu);
|
||||
if(!ACCESS_FLAG(F_PF))
|
||||
ST0.ll = ST(nextop&7).ll;
|
||||
ST0.q = ST(nextop&7).q;
|
||||
break;
|
||||
|
||||
case 0xE1: /* FDISI8087_NOP */
|
||||
@ -168,11 +168,11 @@ int RunDB(x64emu_t *emu, rex_t rex)
|
||||
fpu_do_push(emu);
|
||||
memcpy(&STld(0).ld, ED, 10);
|
||||
LD2D(&STld(0), &ST(0).d);
|
||||
STld(0).ref = ST0.ll;
|
||||
STld(0).ref = ST0.q;
|
||||
break;
|
||||
case 7: /* FSTP tbyte */
|
||||
GETED(0);
|
||||
if(ST0.ll!=STld(0).ref)
|
||||
if(ST0.q!=STld(0).ref)
|
||||
D2LD(&ST0.d, ED);
|
||||
else
|
||||
memcpy(ED, &STld(0).ld, 10);
|
||||
|
@ -11,13 +11,13 @@
|
||||
|
||||
void reset_fpu(x64emu_t* emu)
|
||||
{
|
||||
memset(emu->fpu, 0, sizeof(emu->fpu));
|
||||
memset(emu->mmx87, 0, sizeof(emu->mmx87));
|
||||
memset(emu->fpu_ld, 0, sizeof(emu->fpu_ld));
|
||||
emu->cw = 0x37F;
|
||||
emu->sw.x16 = 0x0000;
|
||||
emu->top = 0;
|
||||
emu->fpu_stack = 0;
|
||||
for(int i=0; i<9; ++i)
|
||||
for(int i=0; i<8; ++i)
|
||||
emu->p_regs[i].tag = 0b11; // STx is empty
|
||||
}
|
||||
|
||||
@ -67,7 +67,7 @@ void fpu_fbld(x64emu_t* emu, uint8_t* s) {
|
||||
}
|
||||
|
||||
|
||||
#define FPU_t fpu_reg_t
|
||||
#define FPU_t mmx87_regs_t
|
||||
#define BIAS80 16383
|
||||
#define BIAS64 1023
|
||||
// long double (80bits) -> double (64bits)
|
||||
@ -83,8 +83,8 @@ void LD2D(void* ld, void* d)
|
||||
#if 1
|
||||
memcpy(&val, ld, 10);
|
||||
#else
|
||||
val.f.l.lower = *(uint32_t*)ld;
|
||||
val.f.l.upper = *(uint32_t*)(char*)(ld+4);
|
||||
val.f.ud[0] = *(uint32_t*)ld;
|
||||
val.f.ud[1] = *(uint32_t*)(char*)(ld+4);
|
||||
val.b = *(int16_t*)((char*)ld+8);
|
||||
#endif
|
||||
int32_t exp64 = (((uint32_t)(val.b&0x7fff) - BIAS80) + BIAS64);
|
||||
@ -95,31 +95,31 @@ void LD2D(void* ld, void* d)
|
||||
if((uint32_t)(val.b&0x7fff)==0x7fff) {
|
||||
// infinity and nans
|
||||
int t = 0; //nan
|
||||
switch((val.f.l.upper>>30)) {
|
||||
case 0: if((val.f.l.upper&(1<<29))==0) t = 1;
|
||||
switch((val.f.ud[1]>>30)) {
|
||||
case 0: if((val.f.ud[1]&(1<<29))==0) t = 1;
|
||||
break;
|
||||
case 2: if((val.f.l.upper&(1<<29))==0) t = 1;
|
||||
case 2: if((val.f.ud[1]&(1<<29))==0) t = 1;
|
||||
break;
|
||||
}
|
||||
if(t) { // infinite
|
||||
result.d = HUGE_VAL;
|
||||
} else { // NaN
|
||||
result.l.upper = 0x7ff << 20;
|
||||
result.l.lower = 0;
|
||||
result.ud[1] = 0x7ff << 20;
|
||||
result.ud[0] = 0;
|
||||
}
|
||||
if(val.b&0x8000)
|
||||
result.l.upper |= 0x80000000;
|
||||
*(uint64_t*)d = result.ll;
|
||||
result.ud[1] |= 0x80000000;
|
||||
*(uint64_t*)d = result.q;
|
||||
return;
|
||||
}
|
||||
if(((uint32_t)(val.b&0x7fff)==0) || (exp64<=0)) {
|
||||
//if(val.f.ll==0)
|
||||
//if(val.f.q==0)
|
||||
// zero
|
||||
//if(val.f.ll!=0)
|
||||
//if(val.f.q!=0)
|
||||
// denormal, but that's to small value for double
|
||||
uint64_t r = 0;
|
||||
if(val.b&0x8000)
|
||||
r |= 0x8000000000000000LL;
|
||||
r |= 0x8000000000000000L;
|
||||
*(uint64_t*)d = r;
|
||||
return;
|
||||
}
|
||||
@ -128,17 +128,17 @@ void LD2D(void* ld, void* d)
|
||||
// to big value...
|
||||
result.d = HUGE_VAL;
|
||||
if(val.b&0x8000)
|
||||
result.l.upper |= 0x80000000;
|
||||
*(uint64_t*)d = result.ll;
|
||||
result.ud[1] |= 0x80000000;
|
||||
*(uint64_t*)d = result.q;
|
||||
return;
|
||||
}
|
||||
|
||||
uint64_t mant64 = (val.f.ll >> 11) & 0xfffffffffffffLL;
|
||||
uint64_t mant64 = (val.f.q >> 11) & 0xfffffffffffffL;
|
||||
uint32_t sign = (val.b&0x8000)?1:0;
|
||||
result.ll = mant64;
|
||||
result.l.upper |= (sign <<31)|((exp64final&0x7ff) << 20);
|
||||
result.q = mant64;
|
||||
result.ud[1] |= (sign <<31)|((exp64final&0x7ff) << 20);
|
||||
|
||||
*(uint64_t*)d = result.ll;
|
||||
*(uint64_t*)d = result.q;
|
||||
}
|
||||
|
||||
// double (64bits) -> long double (80bits)
|
||||
@ -151,12 +151,12 @@ void D2LD(void* d, void* ld)
|
||||
} val;
|
||||
#pragma pack(pop)
|
||||
FPU_t s;
|
||||
s.ll = *(uint64_t*)d; // use memcpy to avoid risk of Bus Error?
|
||||
s.q = *(uint64_t*)d; // use memcpy to avoid risk of Bus Error?
|
||||
// do special value first
|
||||
if((s.ll&0x7fffffffffffffffLL)==0) {
|
||||
if((s.q&0x7fffffffffffffffL)==0) {
|
||||
// zero...
|
||||
val.f.ll = 0;
|
||||
if(s.l.upper&0x8000)
|
||||
val.f.q = 0;
|
||||
if(s.ud[1]&0x8000)
|
||||
val.b = 0x8000;
|
||||
else
|
||||
val.b = 0;
|
||||
@ -164,26 +164,26 @@ void D2LD(void* d, void* ld)
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t sign80 = (s.l.upper&0x80000000)?1:0;
|
||||
int32_t exp80 = s.l.upper&0x7ff00000;
|
||||
int32_t sign80 = (s.ud[1]&0x80000000)?1:0;
|
||||
int32_t exp80 = s.ud[1]&0x7ff00000;
|
||||
int32_t exp80final = (exp80>>20);
|
||||
int64_t mant80 = s.ll&0x000fffffffffffffLL;
|
||||
int64_t mant80 = s.q&0x000fffffffffffffL;
|
||||
int64_t mant80final = (mant80 << 11);
|
||||
if(exp80final==0x7ff) {
|
||||
// NaN and Infinite
|
||||
exp80final = 0x7fff;
|
||||
if(mant80==0x0)
|
||||
mant80final = 0x8000000000000000LL; //infinity
|
||||
mant80final = 0x8000000000000000L; //infinity
|
||||
else
|
||||
mant80final = 0xc000000000000000LL; //(quiet)NaN
|
||||
mant80final = 0xc000000000000000L; //(quiet)NaN
|
||||
} else {
|
||||
if(exp80!=0){
|
||||
mant80final |= 0x8000000000000000LL;
|
||||
mant80final |= 0x8000000000000000L;
|
||||
exp80final += (BIAS80 - BIAS64);
|
||||
}
|
||||
}
|
||||
val.b = ((int16_t)(sign80)<<15)| (int16_t)(exp80final);
|
||||
val.f.ll = mant80final;
|
||||
val.f.q = mant80final;
|
||||
memcpy(ld, &val, 10);
|
||||
/*memcpy(ld, &f.ll, 8);
|
||||
memcpy((char*)ld + 8, &val.b, 2);*/
|
||||
@ -231,7 +231,8 @@ void fpu_savenv(x64emu_t* emu, char* p, int b16)
|
||||
// other stuff are not pushed....
|
||||
}
|
||||
|
||||
typedef struct xsave_s {
|
||||
// this is the 64bits version (slightly different than the 32bits!)
|
||||
typedef struct xsave32_s {
|
||||
uint16_t ControlWord; /* 000 */
|
||||
uint16_t StatusWord; /* 002 */
|
||||
uint8_t TagWord; /* 004 */
|
||||
@ -248,11 +249,25 @@ typedef struct xsave_s {
|
||||
sse_regs_t FloatRegisters[8];/* 020 */ // fpu/mmx are store in 128bits here
|
||||
sse_regs_t XmmRegisters[16]; /* 0a0 */
|
||||
uint8_t Reserved4[96]; /* 1a0 */
|
||||
} xsave_t;
|
||||
} xsave32_t;
|
||||
typedef struct xsave64_s {
|
||||
uint16_t ControlWord; /* 000 */
|
||||
uint16_t StatusWord; /* 002 */
|
||||
uint8_t TagWord; /* 004 */
|
||||
uint8_t Reserved1; /* 005 */
|
||||
uint16_t ErrorOpcode; /* 006 */
|
||||
uint64_t ErrorOffset; /* 008 */
|
||||
uint64_t DataOffset; /* 010 */
|
||||
uint32_t MxCsr; /* 018 */
|
||||
uint32_t MxCsr_Mask; /* 01c */
|
||||
sse_regs_t FloatRegisters[8];/* 020 */ // fpu/mmx are store in 128bits here
|
||||
sse_regs_t XmmRegisters[16]; /* 0a0 */
|
||||
uint8_t Reserved4[96]; /* 1a0 */
|
||||
} xsave64_t;
|
||||
|
||||
void fpu_fxsave(x64emu_t* emu, void* ed)
|
||||
void fpu_fxsave32(x64emu_t* emu, void* ed)
|
||||
{
|
||||
xsave_t *p = (xsave_t*)ed;
|
||||
xsave32_t *p = (xsave32_t*)ed;
|
||||
// should save flags & all
|
||||
emu->sw.f.F87_TOP = emu->top&7;
|
||||
p->ControlWord = emu->cw;
|
||||
@ -268,21 +283,39 @@ void fpu_fxsave(x64emu_t* emu, void* ed)
|
||||
p->DataSelector = 0;
|
||||
p->MxCsr = 0;
|
||||
p->MxCsr_Mask = 0;
|
||||
// copy MMX regs...
|
||||
// copy FPU/MMX regs...
|
||||
for(int i=0; i<8; ++i)
|
||||
memcpy(&p->FloatRegisters[i].q[0], &emu->mmx[0], sizeof(emu->mmx[0]));
|
||||
memcpy(&p->FloatRegisters[i].q[0], &emu->mmx87[0], sizeof(emu->mmx87[0]));
|
||||
// copy SSE regs
|
||||
memcpy(&p->XmmRegisters[0], &emu->xmm[0], sizeof(emu->xmm));
|
||||
// put also FPU regs in a reserved area... on XMM 8-15
|
||||
for(int i=0; i<8; ++i)
|
||||
memcpy(&p->XmmRegisters[8+i].q[0], &emu->fpu[0], sizeof(emu->fpu[0]));
|
||||
// put a magic sign in reserved area, box86 specific
|
||||
((unsigned int *)p->Reserved4)[11] = 0x50515253;
|
||||
}
|
||||
|
||||
void fpu_fxrstor(x64emu_t* emu, void* ed)
|
||||
void fpu_fxsave64(x64emu_t* emu, void* ed)
|
||||
{
|
||||
xsave_t *p = (xsave_t*)ed;
|
||||
xsave64_t *p = (xsave64_t*)ed;
|
||||
// should save flags & all
|
||||
emu->sw.f.F87_TOP = emu->top&7;
|
||||
p->ControlWord = emu->cw;
|
||||
p->StatusWord = emu->sw.x16;
|
||||
uint8_t tags = 0;
|
||||
for (int i=0; i<8; ++i)
|
||||
tags |= ((emu->p_regs[i].tag)<<(i*2)==0b11)?0:1;
|
||||
p->TagWord = tags;
|
||||
p->ErrorOpcode = 0;
|
||||
p->ErrorOffset = 0;
|
||||
p->DataOffset = 0;
|
||||
p->MxCsr = 0;
|
||||
p->MxCsr_Mask = 0;
|
||||
// copy FPU/MMX regs...
|
||||
for(int i=0; i<8; ++i)
|
||||
memcpy(&p->FloatRegisters[i].q[0], &emu->mmx87[0], sizeof(emu->mmx87[0]));
|
||||
// copy SSE regs
|
||||
memcpy(&p->XmmRegisters[0], &emu->xmm[0], sizeof(emu->xmm));
|
||||
}
|
||||
|
||||
void fpu_fxrstor32(x64emu_t* emu, void* ed)
|
||||
{
|
||||
xsave32_t *p = (xsave32_t*)ed;
|
||||
emu->cw = p->ControlWord;
|
||||
emu->sw.x16 = p->StatusWord;
|
||||
emu->top = emu->sw.f.F87_TOP;
|
||||
@ -291,17 +324,23 @@ void fpu_fxrstor(x64emu_t* emu, void* ed)
|
||||
emu->p_regs[i].tag = (tags>>(i*2))?0:0b11;
|
||||
// copy back MMX regs...
|
||||
for(int i=0; i<8; ++i)
|
||||
memcpy(&emu->mmx[i], &p->FloatRegisters[i].q[0], sizeof(emu->mmx[0]));
|
||||
memcpy(&emu->mmx87[i], &p->FloatRegisters[i].q[0], sizeof(emu->mmx87[0]));
|
||||
// copy SSE regs
|
||||
memcpy(&emu->xmm[0], &p->XmmRegisters[0], sizeof(emu->xmm));
|
||||
}
|
||||
|
||||
void fpu_fxrstor64(x64emu_t* emu, void* ed)
|
||||
{
|
||||
xsave64_t *p = (xsave64_t*)ed;
|
||||
emu->cw = p->ControlWord;
|
||||
emu->sw.x16 = p->StatusWord;
|
||||
emu->top = emu->sw.f.F87_TOP;
|
||||
uint8_t tags = p->TagWord;
|
||||
for(int i=0; i<8; ++i)
|
||||
emu->p_regs[i].tag = (tags>>(i*2))?0:0b11;
|
||||
// copy back MMX regs...
|
||||
for(int i=0; i<8; ++i)
|
||||
memcpy(&emu->mmx87[i], &p->FloatRegisters[i].q[0], sizeof(emu->mmx87[0]));
|
||||
// copy SSE regs
|
||||
memcpy(&emu->xmm[0], &p->XmmRegisters[0], sizeof(emu->xmm));
|
||||
// check the box86 magic sign in reserved area
|
||||
if(((unsigned int *)p->Reserved4)[11] == 0x50515253) {
|
||||
// also FPU regs where a reserved area... on XMM 8-15?
|
||||
for(int i=0; i<8; ++i)
|
||||
memcpy(&emu->fpu[0], &p->XmmRegisters[8+i].q[0], sizeof(emu->fpu[0]));
|
||||
} else {
|
||||
// copy the mmx to fpu...
|
||||
for(int i=0; i<8; ++i)
|
||||
memcpy(&emu->fpu[0], &emu->mmx[i], sizeof(emu->mmx[0]));
|
||||
}
|
||||
}
|
||||
|
@ -18,9 +18,9 @@ typedef struct x64emu_s x64emu_t;
|
||||
//void Run66DD(x64emu_t *emu);
|
||||
//void RunDF(x64emu_t *emu);
|
||||
|
||||
#define ST0 emu->fpu[emu->top]
|
||||
#define ST1 emu->fpu[(emu->top+1)&7]
|
||||
#define ST(a) emu->fpu[(emu->top+(a))&7]
|
||||
#define ST0 emu->mmx87[emu->top]
|
||||
#define ST1 emu->mmx87[(emu->top+1)&7]
|
||||
#define ST(a) emu->mmx87[(emu->top+(a))&7]
|
||||
|
||||
#define STld(a) emu->fpu_ld[(emu->top+(a))&7]
|
||||
#define STll(a) emu->fpu_ll[(emu->top+(a))&7]
|
||||
@ -133,7 +133,7 @@ static inline double fpu_round(x64emu_t* emu, double d) {
|
||||
}
|
||||
|
||||
static inline void fpu_fxam(x64emu_t* emu) {
|
||||
emu->sw.f.F87_C1 = (ST0.l.upper&0x80000000)?1:0;
|
||||
emu->sw.f.F87_C1 = (ST0.ud[1]&0x80000000)?1:0;
|
||||
if(!emu->fpu_stack) {
|
||||
emu->sw.f.F87_C3 = 1;
|
||||
emu->sw.f.F87_C2 = 0;
|
||||
@ -187,7 +187,7 @@ static inline void fpu_ftst(x64emu_t* emu) {
|
||||
// normal...
|
||||
emu->sw.f.F87_C3 = 0;
|
||||
emu->sw.f.F87_C2 = 0;
|
||||
emu->sw.f.F87_C0 = (ST0.l.upper&0x80000000)?1:0;
|
||||
emu->sw.f.F87_C0 = (ST0.ud[1]&0x80000000)?1:0;
|
||||
}
|
||||
|
||||
void fpu_fbst(x64emu_t* emu, uint8_t* d);
|
||||
@ -195,7 +195,9 @@ void fpu_fbld(x64emu_t* emu, uint8_t* s);
|
||||
|
||||
void fpu_loadenv(x64emu_t* emu, char* p, int b16);
|
||||
void fpu_savenv(x64emu_t* emu, char* p, int b16);
|
||||
void fpu_fxsave(x64emu_t* emu, void* ed);
|
||||
void fpu_fxrstor(x64emu_t* emu, void* ed);
|
||||
void fpu_fxsave32(x64emu_t* emu, void* ed);
|
||||
void fpu_fxrstor32(x64emu_t* emu, void* ed);
|
||||
void fpu_fxsave64(x64emu_t* emu, void* ed);
|
||||
void fpu_fxrstor64(x64emu_t* emu, void* ed);
|
||||
|
||||
#endif //__X87RUN_PRIVATE_H_
|
||||
|
@ -126,19 +126,6 @@ typedef enum {
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
typedef union {
|
||||
double d;
|
||||
struct {
|
||||
uint32_t lower;
|
||||
uint32_t upper;
|
||||
} l;
|
||||
struct {
|
||||
float lower;
|
||||
float upper;
|
||||
} f;
|
||||
int64_t ll;
|
||||
} fpu_reg_t;
|
||||
|
||||
typedef union {
|
||||
//long double ld; // works only if 80bits!
|
||||
struct {
|
||||
@ -237,13 +224,15 @@ typedef union {
|
||||
typedef union {
|
||||
uint64_t q;
|
||||
int64_t sq;
|
||||
double d;
|
||||
float f[2];
|
||||
uint32_t ud[2];
|
||||
int32_t sd[2];
|
||||
uint16_t uw[4];
|
||||
int16_t sw[4];
|
||||
uint8_t ub[8];
|
||||
int8_t sb[8];
|
||||
} mmx_regs_t;
|
||||
} mmx87_regs_t;
|
||||
|
||||
typedef union {
|
||||
uint64_t q[2];
|
||||
|
41
src/include/signals.h
Executable file
41
src/include/signals.h
Executable file
@ -0,0 +1,41 @@
|
||||
#ifndef __SIGNALS_H__
|
||||
#define __SIGNALS_H__
|
||||
#include <signal.h>
|
||||
|
||||
typedef void (*sighandler_t)(int);
|
||||
|
||||
typedef struct x64_sigaction_s {
|
||||
union {
|
||||
__sighandler_t _sa_handler;
|
||||
void (*_sa_sigaction)(int, siginfo_t *, void *);
|
||||
} _u;
|
||||
sigset_t sa_mask;
|
||||
uint32_t sa_flags;
|
||||
void (*sa_restorer)(void);
|
||||
} x64_sigaction_t;
|
||||
|
||||
typedef struct x64_sigaction_restorer_s {
|
||||
union {
|
||||
__sighandler_t _sa_handler;
|
||||
void (*_sa_sigaction)(int, siginfo_t *, void *);
|
||||
} _u;
|
||||
uint32_t sa_flags;
|
||||
void (*sa_restorer)(void);
|
||||
sigset_t sa_mask;
|
||||
} x64_sigaction_restorer_t;
|
||||
|
||||
sighandler_t my_signal(x64emu_t* emu, int signum, sighandler_t handler);
|
||||
sighandler_t my___sysv_signal(x64emu_t* emu, int signum, sighandler_t handler);
|
||||
sighandler_t my_sysv_signal(x64emu_t* emu, int signum, sighandler_t handler);
|
||||
|
||||
int my_sigaction(x64emu_t* emu, int signum, const x64_sigaction_t *act, x64_sigaction_t *oldact);
|
||||
int my___sigaction(x64emu_t* emu, int signum, const x64_sigaction_t *act, x64_sigaction_t *oldact);
|
||||
|
||||
int my_syscall_rt_sigaction(x64emu_t* emu, int signum, const x64_sigaction_restorer_t *act, x64_sigaction_restorer_t *oldact, int sigsetsize);
|
||||
|
||||
void init_signal_helper(box64context_t* context);
|
||||
void fini_signal_helper();
|
||||
|
||||
void emit_signal(x64emu_t* emu, int sig, void* addr, int code);
|
||||
|
||||
#endif //__SIGNALS_H__
|
1156
src/libtools/signals.c
Executable file
1156
src/libtools/signals.c
Executable file
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,6 @@
|
||||
#() vFE
|
||||
#() vFv
|
||||
#() vFi
|
||||
#() vFp
|
||||
#() iFE
|
||||
#() iFv
|
||||
@ -72,6 +73,7 @@
|
||||
#() pFEppp
|
||||
#() pFppiL
|
||||
#() pFppuL
|
||||
#() iFEppiV
|
||||
#() iFEpppp
|
||||
#() iFipppi
|
||||
#() iFEpippppp
|
||||
|
@ -71,6 +71,7 @@ void VulkanTox86(void* src, void* save);
|
||||
int of_convert(int);
|
||||
typedef void (*vFE_t)(x64emu_t*);
|
||||
typedef void (*vFv_t)(void);
|
||||
typedef void (*vFi_t)(int32_t);
|
||||
typedef void (*vFp_t)(void*);
|
||||
typedef int32_t (*iFE_t)(x64emu_t*);
|
||||
typedef int32_t (*iFv_t)(void);
|
||||
@ -143,6 +144,7 @@ typedef void* (*pFEppi_t)(x64emu_t*, void*, void*, int32_t);
|
||||
typedef void* (*pFEppp_t)(x64emu_t*, void*, void*, void*);
|
||||
typedef void* (*pFppiL_t)(void*, void*, int32_t, uintptr_t);
|
||||
typedef void* (*pFppuL_t)(void*, void*, uint32_t, uintptr_t);
|
||||
typedef int32_t (*iFEppiV_t)(x64emu_t*, void*, void*, int32_t, void*);
|
||||
typedef int32_t (*iFEpppp_t)(x64emu_t*, void*, void*, void*, void*);
|
||||
typedef int32_t (*iFipppi_t)(int32_t, void*, void*, void*, int32_t);
|
||||
typedef int32_t (*iFEpippppp_t)(x64emu_t*, void*, int32_t, void*, void*, void*, void*, void*);
|
||||
@ -161,6 +163,7 @@ typedef double (*KFKp_t)(double, void*);
|
||||
|
||||
void vFE(x64emu_t *emu, uintptr_t fcn) { vFE_t fn = (vFE_t)fcn; fn(emu); }
|
||||
void vFv(x64emu_t *emu, uintptr_t fcn) { vFv_t fn = (vFv_t)fcn; fn(); }
|
||||
void vFi(x64emu_t *emu, uintptr_t fcn) { vFi_t fn = (vFi_t)fcn; fn((int32_t)R_RDI); }
|
||||
void vFp(x64emu_t *emu, uintptr_t fcn) { vFp_t fn = (vFp_t)fcn; fn((void*)R_RDI); }
|
||||
void iFE(x64emu_t *emu, uintptr_t fcn) { iFE_t fn = (iFE_t)fcn; R_RAX=fn(emu); }
|
||||
void iFv(x64emu_t *emu, uintptr_t fcn) { iFv_t fn = (iFv_t)fcn; R_RAX=fn(); }
|
||||
@ -233,6 +236,7 @@ void pFEppi(x64emu_t *emu, uintptr_t fcn) { pFEppi_t fn = (pFEppi_t)fcn; R_RAX=(
|
||||
void pFEppp(x64emu_t *emu, uintptr_t fcn) { pFEppp_t fn = (pFEppp_t)fcn; R_RAX=(uintptr_t)fn(emu, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX); }
|
||||
void pFppiL(x64emu_t *emu, uintptr_t fcn) { pFppiL_t fn = (pFppiL_t)fcn; R_RAX=(uintptr_t)fn((void*)R_RDI, (void*)R_RSI, (int32_t)R_RDX, (uintptr_t)R_RCX); }
|
||||
void pFppuL(x64emu_t *emu, uintptr_t fcn) { pFppuL_t fn = (pFppuL_t)fcn; R_RAX=(uintptr_t)fn((void*)R_RDI, (void*)R_RSI, (uint32_t)R_RDX, (uintptr_t)R_RCX); }
|
||||
void iFEppiV(x64emu_t *emu, uintptr_t fcn) { iFEppiV_t fn = (iFEppiV_t)fcn; R_RAX=fn(emu, (void*)R_RDI, (void*)R_RSI, (int32_t)R_RDX, (void*)(R_RSP + 8)); }
|
||||
void iFEpppp(x64emu_t *emu, uintptr_t fcn) { iFEpppp_t fn = (iFEpppp_t)fcn; R_RAX=fn(emu, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (void*)R_RCX); }
|
||||
void iFipppi(x64emu_t *emu, uintptr_t fcn) { iFipppi_t fn = (iFipppi_t)fcn; R_RAX=fn((int32_t)R_RDI, (void*)R_RSI, (void*)R_RDX, (void*)R_RCX, (int32_t)R_R8); }
|
||||
void iFEpippppp(x64emu_t *emu, uintptr_t fcn) { iFEpippppp_t fn = (iFEpippppp_t)fcn; R_RAX=fn(emu, (void*)R_RDI, (int32_t)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8, (void*)R_R9, *(void**)(R_RSP + 8)); }
|
||||
|
@ -32,6 +32,7 @@ typedef void (*wrapper_t)(x64emu_t* emu, uintptr_t fnc);
|
||||
|
||||
void vFE(x64emu_t *emu, uintptr_t fnc);
|
||||
void vFv(x64emu_t *emu, uintptr_t fnc);
|
||||
void vFi(x64emu_t *emu, uintptr_t fnc);
|
||||
void vFp(x64emu_t *emu, uintptr_t fnc);
|
||||
void iFE(x64emu_t *emu, uintptr_t fnc);
|
||||
void iFv(x64emu_t *emu, uintptr_t fnc);
|
||||
@ -104,6 +105,7 @@ void pFEppi(x64emu_t *emu, uintptr_t fnc);
|
||||
void pFEppp(x64emu_t *emu, uintptr_t fnc);
|
||||
void pFppiL(x64emu_t *emu, uintptr_t fnc);
|
||||
void pFppuL(x64emu_t *emu, uintptr_t fnc);
|
||||
void iFEppiV(x64emu_t *emu, uintptr_t fnc);
|
||||
void iFEpppp(x64emu_t *emu, uintptr_t fnc);
|
||||
void iFipppi(x64emu_t *emu, uintptr_t fnc);
|
||||
void iFEpippppp(x64emu_t *emu, uintptr_t fnc);
|
||||
|
@ -413,7 +413,7 @@ int EXPORT my_atexit(x64emu_t* emu, void *p)
|
||||
AddCleanup(emu, p);
|
||||
return 0;
|
||||
}
|
||||
#if 0
|
||||
|
||||
int my_getcontext(x64emu_t* emu, void* ucp);
|
||||
int my_setcontext(x64emu_t* emu, void* ucp);
|
||||
int my_makecontext(x64emu_t* emu, void* ucp, void* fnc, int32_t argc, void* argv);
|
||||
@ -429,7 +429,6 @@ int my_swapcontext(x64emu_t* emu, void* ucp1, void* ucp2);
|
||||
// this one is defined in elfloader.c
|
||||
int my_dl_iterate_phdr(x64emu_t *emu, void* F, void *data);
|
||||
|
||||
#endif
|
||||
pid_t EXPORT my_fork(x64emu_t* emu)
|
||||
{
|
||||
// execute atforks prepare functions, in reverse order
|
||||
|
@ -283,9 +283,9 @@ GOM(__cxa_finalize, vFEp)
|
||||
//GOW(execve,
|
||||
//GO(execvp,
|
||||
//GOW(execvpe,
|
||||
//GO(_exit,
|
||||
//GO(exit,
|
||||
//GOW(_Exit,
|
||||
GO(_exit, vFi)
|
||||
GO(exit, vFi)
|
||||
GOW(_Exit, vFi)
|
||||
//GO(explicit_bzero,
|
||||
//GO(__explicit_bzero_chk,
|
||||
//GO(faccessat,
|
||||
@ -472,7 +472,7 @@ GOW(fwrite, LFpLLp)
|
||||
//GOW(getc,
|
||||
//GO(getchar,
|
||||
//GO(getchar_unlocked,
|
||||
//GOW(getcontext,
|
||||
GOM(getcontext, iFEp) //Weak
|
||||
//GOW(getc_unlocked,
|
||||
//GO(get_current_dir_name,
|
||||
//GOW(getcwd,
|
||||
@ -1086,7 +1086,7 @@ GOM(__libc_start_main, iFEpippppp)
|
||||
//GO(__lxstat64,
|
||||
//GO(__madvise,
|
||||
//GOW(madvise,
|
||||
//GOW(makecontext,
|
||||
GOM(makecontext, iFEppiV) //weak
|
||||
//GOW(mallinfo,
|
||||
GO(malloc, pFL) // need to wrap to clear allocated memory?
|
||||
//GO(malloc_get_state,
|
||||
@ -1869,7 +1869,7 @@ GO(strlen, LFp)
|
||||
//GO(svcunixfd_create,
|
||||
//GO(svc_unregister,
|
||||
//GO(swab,
|
||||
//GOW(swapcontext,
|
||||
GOM(swapcontext, iFEpp) //Weak
|
||||
//GOW(swapoff,
|
||||
//GOW(swapon,
|
||||
//GO(swprintf,
|
||||
|
Loading…
Reference in New Issue
Block a user