Added FSGSBASE cpu extension

This commit is contained in:
ptitSeb committed 2025-11-03 07:44:04 +01:00
1 parent 8b72b3bf70
commit 2b070086d1
32 files changed
+186 -105

No files matched your search

+1 -1
View File
@@ -20,7 +20,7 @@ arm64_epilog:
stp x26, x27, [x0, (8 * 16)] // put back reg value in emu, including EIP (so x27 must be EIP now)
//restore all used register
#ifdef _WIN32
ldr x18, [x0, 3104]
ldr x18, [x0, 3088]
#endif
add sp, x28, 0
//vpop {d8-d15}
+1 -1
View File
@@ -23,7 +23,7 @@ arm64_next:
stp x18, x27, [sp, (8 * 10)] // also save x27(rip) to allow change in LinkNext
#ifdef _WIN32
ldr x18, [x0, 3104]
ldr x18, [x0, 3088]
#endif
mov x1, x27 // xRIP, should not be needed most of the time
mov x2, x30 // "from" is in lr, so put in x2
+6
View File
@@ -1689,6 +1689,12 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
ed = x1;
}
STRH_U12(ed, xEmu, offsetof(x64emu_t, segs[u8]));
if((u8==_FS) || (u8==_GS)) {
// refresh offset if needed
CBZw_NEXT(ed);
MOV32w(x1, u8);
CALL(const_getsegmentbase, -1);
}
}
break;
case 0x8F:
+6
View File
@@ -1774,6 +1774,9 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
INST_NAME("POP FS");
POP1z(x2);
STRH_U12(x2, xEmu, offsetof(x64emu_t, segs[_FS]));
CBZw_NEXT(x2);
MOV32w(x1, _FS);
CALL(const_getsegmentbase, -1);
break;
case 0xA2:
INST_NAME("CPUID");
@@ -1857,6 +1860,9 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
INST_NAME("POP GS");
POP1z(x2);
STRH_U12(x2, xEmu, offsetof(x64emu_t, segs[_GS]));
CBZw_NEXT(x2);
MOV32w(x1, _GS);
CALL(const_getsegmentbase, -1);
break;
case 0xAB:
+6
View File
@@ -1006,6 +1006,12 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
ed = x1;
}
STRH_U12(ed, xEmu, offsetof(x64emu_t, segs[u8]));
if((u8==_FS) || (u8==_GS)) {
// refresh offset if needed
CBZw_NEXT(ed);
MOV32w(x1, u8);
CALL(const_getsegmentbase, -1);
}
}
break;
case 0x8F:
+6
View File
@@ -730,6 +730,12 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
ed = x1;
}
STRH_U12(ed, xEmu, offsetof(x64emu_t, segs[u8]));
if((u8==_FS) || (u8==_GS)) {
// refresh offset if needed
CBZw_NEXT(ed);
MOV32w(x1, u8);
CALL(const_getsegmentbase, -1);
}
}
break;
case 0x8F:
+24 -7
View File
@@ -503,15 +503,32 @@ uintptr_t dynarec64_F30F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
case 0xAE:
nextop = F8;
switch((nextop>>3)&7) {
case 0:
case 1:
if(rex.is32bits || !MODREG) {
INST_NAME("Illegal AE");
FAKEED;
UDF(0);
} else {
if(((nextop>>3)&7)==1) {INST_NAME("RDGSBASE");} else {INST_NAME("RDFSBASE");}
ed = TO_NAT((nextop & 7) + (rex.b << 3));
int seg = _FS + ((nextop>>3)&7);
grab_segdata(dyn, addr, ninst, x4, seg, (MODREG));
MOVxw_REG(ed, x4);
}
break;
case 2:
INST_NAME("(unsupported) WRFSBASE Ed");
FAKEED;
UDF(0);
break;
case 3:
INST_NAME("(unsupported) WRGSBASE Ed");
FAKEED;
UDF(0);
if(rex.is32bits || !MODREG) {
INST_NAME("Illegal AE");
FAKEED;
UDF(0);
} else {
if(((nextop>>3)&7)==3) {INST_NAME("WRGSBASE");} else {INST_NAME("WRFSBASE");}
ed = TO_NAT((nextop & 7) + (rex.b << 3));
int seg = _FS + ((nextop>>3)&7)-2;
STRx_U12(ed, xEmu, offsetof(x64emu_t, segs_offs[seg]));
}
break;
case 5:
INST_NAME("(unsupported) INCSSPD/INCSSPQ Ed");
-13
View File
@@ -935,20 +935,7 @@ void grab_segdata(dynarec_arm_t* dyn, uintptr_t addr, int ninst, int reg, int se
MAYUSE(j64);
if (modreg) return;
MESSAGE(LOG_DUMP, "Get %s Offset\n", (segment==_FS)?"FS":"GS");
int t2 = x4;
if(reg==t2) ++t2;
#ifdef _WIN32
LDRx_U12(reg, xEmu, offsetof(x64emu_t, segs_offs[segment]));
#else
LDRH_U12(t2, xEmu, offsetof(x64emu_t, segs_old[segment]));
LDRH_U12(reg, xEmu, offsetof(x64emu_t, segs[segment]));
SUBw_REG(t2, reg, t2);
LDRx_U12(reg, xEmu, offsetof(x64emu_t, segs_offs[segment]));
CBZw_MARKSEG(t2);
MOVZw(x1, segment);
call_c(dyn, ninst, const_getsegmentbase, t2, reg, 1, 0);
MARKSEG;
#endif
MESSAGE(LOG_DUMP, "----%s Offset\n", (segment==_FS)?"FS":"GS");
}
+6
View File
@@ -1282,6 +1282,12 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
ed = x1;
}
ST_H(ed, xEmu, offsetof(x64emu_t, segs[u8]));
if((u8==_FS) || (u8==_GS)) {
// refresh offset if needed
CBZ_NEXT(ed);
MOV32w(x1, u8);
CALL(const_getsegmentbase, -1, x1, x2);
}
break;
case 0x8F:
INST_NAME("POP Ed");
+6
View File
@@ -739,6 +739,12 @@ uintptr_t dynarec64_64(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
ed = x1;
}
ST_H(ed, xEmu, offsetof(x64emu_t, segs[u8]));
if((u8==_FS) || (u8==_GS)) {
// refresh offset if needed
CBZ_NEXT(ed);
MOV32w(x1, u8);
CALL(const_getsegmentbase, -1, x1, x2);
}
break;
case 0xA1:
INST_NAME("MOV EAX, FS:Od");
+6
View File
@@ -511,6 +511,12 @@ uintptr_t dynarec64_66(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
ed = x1;
}
ST_H(ed, xEmu, offsetof(x64emu_t, segs[u8]));
if((u8==_FS) || (u8==_GS)) {
// refresh offset if needed
CBZ_NEXT(ed);
MOV32w(x1, u8);
CALL(const_getsegmentbase, -1, x1, x2);
}
break;
case 0x90:
case 0x91:
-10
View File
@@ -764,17 +764,7 @@ void grab_segdata(dynarec_la64_t* dyn, uintptr_t addr, int ninst, int reg, int s
MAYUSE(j64);
if (modreg) return;
MESSAGE(LOG_DUMP, "Get %s Offset\n", (segment == _FS) ? "FS" : "GS");
int t1 = x1, t2 = x4;
if (reg == t1) ++t1;
if (reg == t2) ++t2;
LD_H(t2, xEmu, offsetof(x64emu_t, segs_old[segment]));
LD_D(reg, xEmu, offsetof(x64emu_t, segs_offs[segment]));
LD_H(t1, xEmu, offsetof(x64emu_t, segs[segment]));
SUB_W(t1, t1, t2);
CBZ_MARKSEG(t1);
MOV64x(x1, segment);
call_c(dyn, ninst, const_getsegmentbase, t2, reg, 0, xFlags, x1, 0, 0, 0, 0, 0);
MARKSEG;
MESSAGE(LOG_DUMP, "----%s Offset\n", (segment == _FS) ? "FS" : "GS");
}
+6
View File
@@ -514,6 +514,12 @@ uintptr_t dynarec64_00_2(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
ed = x1;
}
SH(ed, xEmu, offsetof(x64emu_t, segs[(nextop & 0x38) >> 3]));
if((u8==_FS) || (u8==_GS)) {
// refresh offset if needed
CBZ_NEXT(ed);
MOV32w(x1, u8);
CALL(const_getsegmentbase, -1, x1, x2);
}
break;
case 0x8F:
INST_NAME("POP Ed");
+6
View File
@@ -471,6 +471,12 @@ uintptr_t dynarec64_64(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
ed = x1;
}
SH(ed, xEmu, offsetof(x64emu_t, segs[u8]));
if((u8==_FS) || (u8==_GS)) {
// refresh offset if needed
CBZ_NEXT(ed);
MOV32w(x1, u8);
CALL(const_getsegmentbase, -1, x1, x2);
}
break;
case 0x8F:
INST_NAME("POP FS:Ed");
+6
View File
@@ -727,6 +727,12 @@ uintptr_t dynarec64_66(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
ed = x1;
}
SH(ed, xEmu, offsetof(x64emu_t, segs[u8]));
if((u8==_FS) || (u8==_GS)) {
// refresh offset if needed
CBZ_NEXT(ed);
MOV32w(x1, u8);
CALL(const_getsegmentbase, -1, x1, x2);
}
break;
case 0x90:
case 0x91:
-10
View File
@@ -881,17 +881,7 @@ void grab_segdata(dynarec_rv64_t* dyn, uintptr_t addr, int ninst, int reg, int s
MAYUSE(j64);
if (modreg) return;
MESSAGE(LOG_DUMP, "Get %s Offset\n", (segment == _FS) ? "FS" : "GS");
int t1 = x1, t2 = x4;
if (reg == t1) ++t1;
if (reg == t2) ++t2;
LH(t2, xEmu, offsetof(x64emu_t, segs_old[segment]));
LD(reg, xEmu, offsetof(x64emu_t, segs_offs[segment]));
LH(t1, xEmu, offsetof(x64emu_t, segs[segment]));
SUBW(t1, t1, t2);
CBZ_MARKSEG(t1);
MOV64x(x1, segment);
call_c(dyn, ninst, const_getsegmentbase, t2, reg, 0, xFlags, x1, 0, 0, 0, 0, 0);
MARKSEG;
MESSAGE(LOG_DUMP, "----%s Offset\n", (segment == _FS) ? "FS" : "GS");
}
+9 -13
View File
@@ -77,8 +77,8 @@ static void internalX64Setup(x64emu_t* emu, box64context_t *context, uintptr_t s
} else {
emu->segs[_CS] = 0x33;
emu->segs[_DS] = emu->segs[_ES] = emu->segs[_SS] = 0x2b;
emu->segs[_FS] = 0x43;
emu->segs[_GS] = default_gs;
emu->segs[_FS] = 0;
emu->segs[_GS] = 0;
}
// init segments
for(int i=0; i<16; i++) {
@@ -196,7 +196,6 @@ void CloneEmu(x64emu_t *newemu, const x64emu_t* emu)
newemu->old_ip = emu->old_ip;
memcpy(newemu->segs, emu->segs, sizeof(emu->segs));
memcpy(newemu->segs_offs, emu->segs_offs, sizeof(emu->segs_offs));
memcpy(newemu->segs_old, emu->segs_old, sizeof(emu->segs_old));
memcpy(newemu->seggdt, emu->seggdt, sizeof(newemu->seggdt));
memcpy(newemu->segldt, emu->segldt, sizeof(newemu->segldt));
memcpy(newemu->x87, emu->x87, sizeof(emu->x87));
@@ -228,7 +227,6 @@ void CopyEmu(x64emu_t *newemu, const x64emu_t* emu)
newemu->old_ip = emu->old_ip;
memcpy(newemu->segs, emu->segs, sizeof(emu->segs));
memcpy(newemu->segs_offs, emu->segs_offs, sizeof(emu->segs_offs));
memcpy(newemu->segs_old, emu->segs_old, sizeof(emu->segs_old));
memcpy(newemu->x87, emu->x87, sizeof(emu->x87));
memcpy(newemu->mmx, emu->mmx, sizeof(emu->mmx));
memcpy(newemu->xmm, emu->xmm, sizeof(emu->xmm));
@@ -425,6 +423,10 @@ const char* DumpCPURegs(x64emu_t* emu, uintptr_t ip, int is32bits)
if(i!=_GS)
strcat(buff, " ");
}
sprintf(tmp, " FSBASE=%zu", emu->segs_offs[_FS]);
strcat(buff, tmp);
sprintf(tmp, " GSBASE=%zu", emu->segs_offs[_GS]);
strcat(buff, tmp);
strcat(buff, "\n");
if(is32bits)
for (int i=_AX; i<=_RDI; ++i) {
@@ -595,13 +597,6 @@ void EmuCall(x64emu_t* emu, uintptr_t addr)
}
}
void ResetSegmentsCache(x64emu_t *emu)
{
if(!emu)
return;
memset(emu->segs_old, 0, sizeof(emu->segs_old));
}
void applyFlushTo0(x64emu_t* emu)
{
#ifdef __x86_64__
@@ -1608,9 +1603,10 @@ void free_tlsdatasize(void* p)
uintptr_t GetSegmentBaseEmu(x64emu_t* emu, int seg)
{
if (emu->segs_old[seg] != emu->segs[seg]) {
if(emu->segs[seg]) {
emu->segs_offs[seg] = (uintptr_t)GetSegmentBase(emu, emu->segs[seg]);
emu->segs_old[seg] = emu->segs[seg];
//printf_log(LOG_DEBUG, "%04d|GetSegmentBaseEmu seg=%d(%x), offs=%p\n", GetTID(), seg, emu->segs[seg], (void*)emu->segs_offs[seg]);
}
return emu->segs_offs[seg];
}
-2
View File
@@ -90,8 +90,6 @@ typedef struct x64emu_s {
uint16_t segs[6]; // only 32bits value?
uint16_t dummy_seg6, dummy_seg7; // to stay aligned
uintptr_t segs_offs[6]; // computed offset associate with segment
uint16_t segs_old[6]; // seg needs to refresh the offset if value changed
uint16_t dummy2_seg6, dummy2_seg7; // to stay aligned
// parent context
box64context_t *context;
// cpu helpers
-1
View File
@@ -67,7 +67,6 @@ x64emu_t* x64emu_fork(x64emu_t* emu, int forktype)
waitpid(v, NULL, WEXITED);
}
} else if(v==0) {
ResetSegmentsCache(emu);
// execute atforks child functions
for (int i=0; i<my_context->atfork_sz; --i)
if(my_context->atforks[i].child)
+2
View File
@@ -783,6 +783,8 @@ x64emurun:
goto fini;
}
emu->segs[tmp8u] = ED->word[0];
if(((tmp8u==_FS) || (tmp8u==_GS)) && emu->segs[tmp8u])
GetSegmentBaseEmu(emu, tmp8u); // refresh segs_offs
if(tmp8u==_SS && tf) // disable trace when SS is accessed
no_tf = 1;
break;
+4
View File
@@ -1178,6 +1178,8 @@ uintptr_t Run0F(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step)
emu->segs[_FS] = Pop32(emu);
else
emu->segs[_FS] = Pop64(emu);
if(emu->segs[_FS])
GetSegmentBaseEmu(emu, _FS); // refresh segs_offs
break;
case 0xA2: /* CPUID */
tmp32u = R_EAX;
@@ -1255,6 +1257,8 @@ uintptr_t Run0F(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step)
emu->segs[_GS] = Pop32(emu);
else
emu->segs[_GS] = Pop64(emu);
if(emu->segs[_GS])
GetSegmentBaseEmu(emu, _GS); // refresh segs_offs
break;
case 0xAB: /* BTS Ed,Gd */
+9 -1
View File
@@ -397,7 +397,15 @@ uintptr_t Run66(x64emu_t *emu, rex_t rex, uintptr_t addr)
case 0x8E: /* MOV Seg,Ew */
nextop = F8;
GETEW(0);
emu->segs[((nextop&0x38)>>3)] = EW->word[0];
tmp8u = (nextop&0x38)>>3;
if((tmp8u>5) || (tmp8u==1)) {
return 0;
}
emu->segs[tmp8u] = ED->word[0];
if(((tmp8u==_FS) || (tmp8u==_GS)) && emu->segs[tmp8u])
GetSegmentBaseEmu(emu, tmp8u); // refresh segs_offs
/*if(tmp8u==_SS && tf) // disable trace when SS is accessed
no_tf = 1;*/ //TODO?
break;
case 0x8F: /* POP Ew */
nextop = F8;
+35
View File
@@ -19,6 +19,7 @@
#include "x64trace.h"
#include "x87emu_private.h"
#include "box64context.h"
#include "emit_signals.h"
#include "bridge.h"
#include "modrm.h"
@@ -351,6 +352,40 @@ uintptr_t RunF30F(x64emu_t *emu, rex_t rex, uintptr_t addr)
memcpy(EX, GX, 16); // unaligned...
break;
case 0xAE:
nextop = F8;
switch((nextop>>3)&7) {
case 0: /* RDFSBASE */
case 1: /* RDGSBASE */
if(!rex.is32bits && MODREG) {
GETED(0);
int seg = _FS+((nextop>>3)&7);
uintptr_t addr = emu->segs_offs[seg];
if(rex.w)
ED->q[0] = addr;
else {
ED->dword[0] = addr;
ED->dword[1] = 0;
}
} else {
return 0;
}
break;
case 2: /* WRFSBASE */
case 3: /* WRGSBASE */
if(!rex.is32bits && MODREG) {
GETED(0);
int seg = _FS+((nextop>>3)&7)-2;
uintptr_t base = rex.w?ED->q[0]:ED->dword[0];
emu->segs_offs[seg] = base;
} else {
return 0;
}
break;
default: return 0;
}
break;
case 0xB8: /* POPCNT Gd,Ed */
nextop = F8;
GETED(0);
+10 -12
View File
@@ -94,8 +94,6 @@ uint32_t my_set_thread_area_32(x64emu_t* emu, thread_area_32_t* td)
emu->seggdt[idx].is32bits = 1;
}
ResetSegmentsCache(emu);
return 0;
}
@@ -132,8 +130,6 @@ uint32_t my_modify_ldt(x64emu_t* emu, int op, thread_area_t* td, int size)
emu->segs_offs[_GS] =emu->segldt[idx].base;
}
ResetSegmentsCache(emu);
return 0;
}
@@ -169,15 +165,21 @@ int my_arch_prctl(x64emu_t *emu, int code, void* addr)
errno = 0;
switch(code) {
case ARCH_GET_GS:
*(void**)addr = GetSegmentBase(emu, emu->segs[_GS]);
*(uintptr_t*)addr = GetSegmentBaseEmu(emu, _GS);
return 0;
case ARCH_GET_FS:
*(void**)addr = GetSegmentBase(emu, emu->segs[_FS]);
*(uintptr_t*)addr = GetSegmentBaseEmu(emu, _FS);
return 0;
case ARCH_SET_FS:
case ARCH_SET_GS:
seg=(code==ARCH_SET_FS)?_FS:_GS;
int idx = -1;
if(emu->segs[_CS]!=0x23) {
// 64bits version, simply using FSGSBASE....
emu->segs[seg] = 0;
emu->segs_offs[seg] = (uintptr_t)addr;
return 0;
}
// search if it's a TLS base
if(GetSeg43Base(emu)==addr)
idx = 0x43>>3;
@@ -209,7 +211,6 @@ int my_arch_prctl(x64emu_t *emu, int code, void* addr)
emu->seggdt[idx].present = 1;
}
emu->segs_offs[seg] = (uintptr_t)addr;
emu->segs_old[seg] = emu->segs[seg];
return 0;
case ARCH_GET_XCOMP_SUPP:
case ARCH_GET_XCOMP_PERM:
@@ -382,13 +383,10 @@ void refreshTLSData(x64emu_t* emu)
if(box64_is32bits) {
if(emu->segs[_GS]==0x33) {
emu->segs_offs[_GS] = new_offs;
emu->segs_old[_GS] = 0x33;
}
} else {
if(emu->segs[_FS]==0x43) {
emu->segs_offs[_FS] = new_offs;
emu->segs_old[_FS] = 0x43;
}
emu->segs_offs[_FS] = new_offs;
emu->segs[_FS] = 0;
}
}
}
-1
View File
@@ -20,7 +20,6 @@ void print_wrapper_name(int level, x64emu_t* emu);
box64context_t* GetEmuContext(x64emu_t* emu);
void ResetFlags(x64emu_t *emu);
void ResetSegmentsCache(x64emu_t *emu);
const char* DumpCPURegs(x64emu_t* emu, uintptr_t ip, int is32bits);
void UnimpOpcode(x64emu_t* emu, int is32bits);
-6
View File
@@ -368,10 +368,6 @@ uint32_t RunFunctionHandler32(int* exit, int dynarec, i386_ucontext_t* sigcontex
emu->test.test = 0;
#endif
/*SetFS(emu, default_fs);*/
for (int i=0; i<6; ++i)
emu->segs_old[i] = 0;
int align = nargs&1;
R_ESP -= nargs * sizeof(ptr_t);
@@ -740,8 +736,6 @@ void my_sigactionhandler_oldcode_32(x64emu_t* emu, int32_t sig, int simple, sigi
GO(GS);
GO(FS);
#undef GO
for(int i=0; i<6; ++i)
emu->segs_old[i] = 0;
printf_log((sig==10)?LOG_DEBUG:log_minimum, "Context has been changed in Sigactionhanlder, doing siglongjmp to resume emu at %p, RSP=%p (resume with %s)\n", (void*)R_RIP, (void*)R_RSP, (skip==3)?"Dynarec":"Interp");
if(old_code)
*old_code = -1; // re-init the value to allow another segfault at the same place
+12 -8
View File
@@ -123,10 +123,6 @@ uint64_t RunFunctionHandler(x64emu_t* emu, int* exit, int dynarec, x64_ucontext_
emu->test.test = 0;
#endif
/*SetFS(emu, default_fs);*/
for (int i=0; i<6; ++i)
emu->segs_old[i] = 0;
int align = nargs&1;
if(nargs>6)
@@ -1229,8 +1225,6 @@ void my_sigactionhandler_oldcode_64(x64emu_t* emu, int32_t sig, int simple, sigi
seg = (sigcontext->uc_mcontext.gregs[X64_CSGSFS] >> 32)&0xffff;
GO(FS);
#undef GO
for(int i=0; i<6; ++i)
emu->segs_old[i] = 0;
printf_log((sig==10)?LOG_DEBUG:log_minimum, "Context has been changed in Sigactionhanlder, doing siglongjmp to resume emu at %p, RSP=%p (resume with %s)\n", (void*)R_RIP, (void*)R_RSP, (skip==3)?"Dynarec":"Interp");
if(old_code)
*old_code = -1; // re-init the value to allow another segfault at the same place
@@ -1273,7 +1267,7 @@ void my_sigactionhandler_oldcode_64(x64emu_t* emu, int32_t sig, int simple, sigi
emu->eflags.x64=sigcontext->uc_mcontext.gregs[X64_EFL];
uint16_t seg;
seg = (sigcontext->uc_mcontext.gregs[X64_CSGSFS] >> 0)&0xffff;
#define GO(S) emu->segs[_##S]=seg; emu->segs_old[_##S] = 0;
#define GO(S) emu->segs[_##S]=seg;
GO(CS);
seg = (sigcontext->uc_mcontext.gregs[X64_CSGSFS] >> 16)&0xffff;
GO(GS);
@@ -1326,10 +1320,14 @@ void my_sigactionhandler_oldcode(x64emu_t* emu, int32_t sig, int simple, siginfo
mmx87_regs_t old_mmx[8];
mmx87_regs_t old_x87[8];
uint32_t old_top = emu->top;
uint16_t old_segs[6];
uintptr_t old_segs_offs[6];
memcpy(old_xmm, emu->xmm, sizeof(old_xmm));
memcpy(old_ymm, emu->ymm, sizeof(old_ymm));
memcpy(old_mmx, emu->mmx, sizeof(old_mmx));
memcpy(old_x87, emu->x87, sizeof(old_x87));
memcpy(old_segs, emu->segs, sizeof(old_segs));
memcpy(old_segs_offs, emu->segs_offs, sizeof(old_segs_offs));
#define GO(A) old_##A = emu->A
GO(eflags);
GO(df);
@@ -1383,6 +1381,8 @@ void my_sigactionhandler_oldcode(x64emu_t* emu, int32_t sig, int simple, siginfo
memcpy(emu->ymm, old_ymm, sizeof(old_ymm));
memcpy(emu->mmx, old_mmx, sizeof(old_mmx));
memcpy(emu->x87, old_x87, sizeof(old_x87));
memcpy(emu->segs, old_segs, sizeof(old_segs));
memcpy(emu->segs_offs, old_segs_offs, sizeof(old_segs_offs));
emu->top = old_top;
}
@@ -1882,6 +1882,8 @@ dynarec_log(/*LOG_DEBUG*/LOG_INFO, "%04d|Repeated SIGSEGV with Access error on %
printf_log_prefix(0, log_minimum, "\n");
for (int i=0; i<6; ++i)
printf_log_prefix(0, log_minimum, "%s:0x%04x ", seg_name[i], emu->segs[i]);
printf_log_prefix(0, log_minimum, "FSBASE=%p ", emu->segs_offs[_FS]);
printf_log_prefix(0, log_minimum, "GSBASE=%p", emu->segs_offs[_GS]);
}
if(rsp!=addr && getProtection((uintptr_t)rsp-4*8) && getProtection((uintptr_t)rsp+4*8))
for (int i=-4; i<4; ++i) {
@@ -1895,9 +1897,11 @@ dynarec_log(/*LOG_DEBUG*/LOG_INFO, "%04d|Repeated SIGSEGV with Access error on %
if(!(i%4)) printf_log_prefix(0, log_minimum, "\n");
printf_log_prefix(0, log_minimum, "%s:0x%016llx ", reg_name[i], emu->regs[i].q[0]);
}
printf_log_prefix(0, log_minimum, "\n");
for (int i=0; i<6; ++i)
printf_log_prefix(0, log_minimum, "%s:0x%04x ", seg_name[i], emu->segs[i]);
printf_log_prefix(0, log_minimum, "FSBASE=%p ", emu->segs_offs[_FS]);
printf_log_prefix(0, log_minimum, "GSBASE=%p", emu->segs_offs[_GS]);
printf_log_prefix(0, log_minimum, "\n");
}
zydis_dec_t* dec = emu->segs[_CS] == 0x23 ? my_context->dec32 : my_context->dec;
if(sig==X64_SIGILL) {
-1
View File
@@ -313,7 +313,6 @@ static void* pthread_routine(void* p)
add_thread((void*)et->self, et);
#endif
refreshTLSData(emu);
ResetSegmentsCache(emu);
Push64(emu, 0); // PUSH 0 (backtrace marker: return address is 0)
Push64(emu, 0); // PUSH BP
R_RBP = R_RSP; // MOV BP, SP
+15 -15
View File
@@ -193,21 +193,21 @@ void my_cpuid(x64emu_t* emu, uint32_t tmp32u)
// extended bits...
if(R_ECX==0) {
R_EAX = 0;
R_EBX =
BOX64ENV(avx)<<3 | // BMI1
BOX64ENV(avx2)<<5 | //AVX2
(BOX64ENV(cputype)?0:1)<<6 | // FDP_EXCPTN_ONLY
1<<7 | // SMEP
BOX64ENV(avx2)<<8 | //BMI2
(BOX64ENV(cputype)?0:1)<<9 | // Enhanced REP MOVSB // is it a good idea?
1<<10 | //INVPCID (priviledge instruction
(BOX64ENV(cputype)?0:1)<<13 | // Deprecates FPU CS and FPU DS
0<<18 | // RDSEED
BOX64ENV(avx2)<<19 | //ADX
1<<23 | // CLFLUSHOPT
1<<24 | // CLWB
BOX64ENV(shaext)<<29| // SHA extension
0;
R_EBX = 1<<0 // FSGSBASE
| BOX64ENV(avx)<<3 // BMI1
| BOX64ENV(avx2)<<5 //AVX2
| (BOX64ENV(cputype)?0:1)<<6 // FDP_EXCPTN_ONLY
| 1<<7 // SMEP
| BOX64ENV(avx2)<<8 //BMI2
| (BOX64ENV(cputype)?0:1)<<9 // Enhanced REP MOVSB // is it a good idea?
| 1<<10 //INVPCID (priviledge instruction
| (BOX64ENV(cputype)?0:1)<<13 // Deprecates FPU CS and FPU DS
| 0<<18 // RDSEED
| BOX64ENV(avx2)<<19 //ADX
| 1<<23 // CLFLUSHOPT
| 1<<24 // CLWB
| BOX64ENV(shaext)<<29 // SHA extension
;
R_RCX =
(BOX64ENV(avx)&&BOX64ENV(aes))<<9 | //VAES
(BOX64ENV(avx2)&&BOX64ENV(pclmulqdq))<<10 | //VPCLMULQDQ.
+3 -1
View File
@@ -148,7 +148,9 @@ void SetupInitialStack(x64emu_t *emu)
//Push64(emu, sysconf(_SC_CLK_TCK)); Push64(emu, 17); //AT_CLKTCK(17)=times() frequency
Push64(emu, real_getauxval(23)); Push64(emu, 23); //AT_SECURE(23)
Push64(emu, p_random); Push64(emu, 25); //AT_RANDOM(25)=p_random
Push64(emu, 0); Push64(emu, 26); //AT_HWCAP2(26)=0
Push64(emu, 0
| 1<<1 // FSGSBASE
); Push64(emu, 26); //AT_HWCAP2(26)=...
Push64(emu, p_arg0); Push64(emu, 31); //AT_EXECFN(31)=p_arg0
Push64(emu, emu->context->vsyscall); Push64(emu, 32); //AT_SYSINFO(32)=vsyscall
//Push64(emu, 0); Push64(emu, 33); //AT_SYSINFO_EHDR(33)=address of vDSO
-1
View File
@@ -3763,7 +3763,6 @@ static int clone_fn(void* p)
thread_set_emu(emu);
if(arg->flags&CLONE_NEWUSER) {
init_mutexes(my_context);
ResetSegmentsCache(emu);
}
int ret = RunFunctionWithEmu(emu, 0, arg->fnc, 1, arg->args);
int exited = (emu->flags.quitonexit==2);
+1 -1
View File
@@ -233,7 +233,7 @@ NTSTATUS WINAPI BTCpuProcessInit(void)
#define STATIC_ASSERT(COND, MSG) typedef char static_assertion_##MSG[(!!(COND)) * 2 - 1]
/* otherwise adjust arm64_epilog.S and arm64_next.S */
STATIC_ASSERT(offsetof(x64emu_t, win64_teb) == 3104, offset_of_b_must_be_4);
STATIC_ASSERT(offsetof(x64emu_t, win64_teb) == 3088, offset_of_b_must_be_4);
#undef STATIC_ASSERT
LoadEnvVariables();