Reworked FPU/MMX regs, added Context and Signal handling (and test13 works)

This commit is contained in:
ptitSeb 2021-03-07 11:44:09 +01:00
parent 395d9eb622
commit 2a514f14c1
19 changed files with 1357 additions and 125 deletions

View File

@ -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"

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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;
}

View File

@ -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)

View File

@ -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);

View File

@ -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 */

View File

@ -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);

View File

@ -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]));
}
}

View File

@ -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_

View File

@ -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
View 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

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,6 @@
#() vFE
#() vFv
#() vFi
#() vFp
#() iFE
#() iFv
@ -72,6 +73,7 @@
#() pFEppp
#() pFppiL
#() pFppuL
#() iFEppiV
#() iFEpppp
#() iFipppi
#() iFEpippppp

View File

@ -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)); }

View File

@ -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);

View File

@ -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

View File

@ -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,