mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-10-06 07:55:42 +00:00
fix x87 register layout
This commit is contained in:
@@ -1038,10 +1038,10 @@ dmn_lnx_thread_read_reg_block(DMN_LNX_Entity *thread)
|
||||
// copy x87 registers
|
||||
dst->fcw.u16 = src->fcw;
|
||||
dst->fsw.u16 = src->fsw;
|
||||
dst->ftw.u16 = x64_xsave_tag_word_from_real_tag_word(src->ftw);
|
||||
dst->ftw = src->ftw;
|
||||
dst->fop.u16 = src->fop;
|
||||
dst->fip.u64 = src->b64.fip;
|
||||
dst->fdp.u64 = src->b64.fdp;
|
||||
dst->fip.u64 = src->fip;
|
||||
dst->fdp.u64 = src->fdp;
|
||||
dst->mxcsr.u32 = src->mxcsr;
|
||||
dst->mxcsr_mask.u32 = src->mxcsr_mask;
|
||||
for EachIndex(i, 8)
|
||||
@@ -1063,6 +1063,9 @@ dmn_lnx_thread_read_reg_block(DMN_LNX_Entity *thread)
|
||||
// copy xsave registers
|
||||
if(xsave)
|
||||
{
|
||||
// compact register layout is not supported
|
||||
AssertAlways(xsave->header.xcomp_bv == 0);
|
||||
|
||||
if(xsave->header.xstate_bv & X64_XStateComponentFlag_AVX)
|
||||
{
|
||||
AssertAlways(process->xsave_layout.avx_offset + 16*sizeof(REGS_Reg128) <= process->xsave_size);
|
||||
@@ -1219,14 +1222,14 @@ dmn_lnx_thread_write_reg_block(DMN_LNX_Entity *thread)
|
||||
|
||||
X64_FXSave dst_fxsave = {0};
|
||||
{
|
||||
dst_fxsave.fcw = src->fcw.u16;
|
||||
dst_fxsave.fsw = src->fsw.u16;
|
||||
dst_fxsave.ftw = src->ftw.u16;
|
||||
dst_fxsave.fop = src->fop.u16;
|
||||
dst_fxsave.b64.fip = src->fip.u64;
|
||||
dst_fxsave.b64.fdp = src->fdp.u64;
|
||||
dst_fxsave.mxcsr = src->mxcsr.u32;
|
||||
dst_fxsave.mxcsr_mask = src->mxcsr_mask.u32;
|
||||
dst_fxsave.fcw = src->fcw.u16;
|
||||
dst_fxsave.fsw = src->fsw.u16;
|
||||
dst_fxsave.ftw = src->ftw;
|
||||
dst_fxsave.fop = src->fop.u16;
|
||||
dst_fxsave.fip = src->fip.u64;
|
||||
dst_fxsave.fdp = src->fdp.u64;
|
||||
dst_fxsave.mxcsr = src->mxcsr.u32;
|
||||
dst_fxsave.mxcsr_mask = src->mxcsr_mask.u32;
|
||||
|
||||
REGS_Reg128 *st_d = (REGS_Reg128 *)dst_fxsave.st_space;
|
||||
REGS_Reg80 *st_s = &src->st0;
|
||||
@@ -1248,6 +1251,7 @@ dmn_lnx_thread_write_reg_block(DMN_LNX_Entity *thread)
|
||||
U8 *xsave_raw = push_array(scratch.arena, U8, process->xsave_size);
|
||||
X64_XSave *dst = (X64_XSave *)xsave_raw;
|
||||
dst->fxsave = dst_fxsave;
|
||||
dst->header.xstate_bv |= X64_XStateComponentFlag_FP;
|
||||
dst->header.xstate_bv |= X64_XStateComponentFlag_SSE;
|
||||
|
||||
if(process->xsave_layout.avx_offset)
|
||||
|
||||
@@ -582,57 +582,6 @@ dmn_w32_image_info_from_process_base_vaddr(HANDLE process, U64 base_vaddr)
|
||||
|
||||
//- rjf: threads
|
||||
|
||||
internal U16
|
||||
dmn_w32_real_tag_word_from_xsave(XSAVE_FORMAT *fxsave)
|
||||
{
|
||||
U16 result = 0;
|
||||
U32 top = (fxsave->StatusWord >> 11) & 7;
|
||||
for(U32 fpr = 0; fpr < 8; fpr += 1)
|
||||
{
|
||||
U32 tag = 3;
|
||||
if(fxsave->TagWord & (1 << fpr))
|
||||
{
|
||||
U32 st = (fpr - top)&7;
|
||||
|
||||
REGS_Reg80 *fp = (REGS_Reg80*)&fxsave->FloatRegisters[st*16];
|
||||
U16 exponent = fp->sign1_exp15 & bitmask15;
|
||||
U64 integer_part = fp->int1_frac63 >> 63;
|
||||
U64 fraction_part = fp->int1_frac63 & bitmask63;
|
||||
|
||||
// tag: 0 - normal; 1 - zero; 2 - special
|
||||
tag = 2;
|
||||
if(exponent == 0)
|
||||
{
|
||||
if(integer_part == 0 && fraction_part == 0)
|
||||
{
|
||||
tag = 1;
|
||||
}
|
||||
}
|
||||
else if(exponent != bitmask15 && integer_part != 0)
|
||||
{
|
||||
tag = 0;
|
||||
}
|
||||
}
|
||||
result |= tag << (2 * fpr);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
internal U16
|
||||
dmn_w32_xsave_tag_word_from_real_tag_word(U16 ftw)
|
||||
{
|
||||
U16 compact = 0;
|
||||
for(U32 fpr = 0; fpr < 8; fpr++)
|
||||
{
|
||||
U32 tag = (ftw >> (fpr * 2)) & 3;
|
||||
if(tag != 3)
|
||||
{
|
||||
compact |= (1 << fpr);
|
||||
}
|
||||
}
|
||||
return compact;
|
||||
}
|
||||
|
||||
internal B32
|
||||
dmn_w32_thread_read_reg_block(Arch arch, HANDLE thread, void *reg_block)
|
||||
{
|
||||
@@ -694,7 +643,7 @@ dmn_w32_thread_read_reg_block(Arch arch, HANDLE thread, void *reg_block)
|
||||
dst->eflags.u32 = ctx.EFlags | 0x2;
|
||||
dst->fcw.u16 = fxsave->ControlWord;
|
||||
dst->fsw.u16 = fxsave->StatusWord;
|
||||
dst->ftw.u16 = dmn_w32_real_tag_word_from_xsave(fxsave);
|
||||
dst->ftw.u16 = fxsave->TagWord;
|
||||
dst->fop.u16 = fxsave->ErrorOpcode;
|
||||
dst->fip.u32 = fxsave->ErrorOffset;
|
||||
dst->fcs.u16 = fxsave->ErrorSelector;
|
||||
@@ -704,7 +653,7 @@ dmn_w32_thread_read_reg_block(Arch arch, HANDLE thread, void *reg_block)
|
||||
dst->mxcsr_mask.u32 = fxsave->MxCsr_Mask;
|
||||
{
|
||||
M128A *float_s = fxsave->FloatRegisters;
|
||||
REGS_Reg80 *float_d = &dst->fpr0;
|
||||
REGS_Reg80 *float_d = &dst->st0;
|
||||
for(U32 n = 0; n < 8; n += 1, float_s += 1, float_d += 1)
|
||||
{
|
||||
MemoryCopy(float_d, float_s, sizeof(*float_d));
|
||||
@@ -817,17 +766,15 @@ dmn_w32_thread_read_reg_block(Arch arch, HANDLE thread, void *reg_block)
|
||||
dst->rflags.u64 = ctx->EFlags | 0x2;
|
||||
dst->fcw.u16 = xsave->ControlWord;
|
||||
dst->fsw.u16 = xsave->StatusWord;
|
||||
dst->ftw.u16 = dmn_w32_real_tag_word_from_xsave(xsave);
|
||||
dst->ftw = xsave->TagWord;
|
||||
dst->fop.u16 = xsave->ErrorOpcode;
|
||||
dst->fcs.u16 = xsave->ErrorSelector;
|
||||
dst->fds.u16 = xsave->DataSelector;
|
||||
dst->fip.u64 = xsave->ErrorOffset;
|
||||
dst->fdp.u64 = xsave->DataOffset;
|
||||
MemoryCopy(&dst->fip.u64, &xsave->ErrorOffset, sizeof(U64));
|
||||
MemoryCopy(&dst->fdp.u64, &xsave->DataOffset, sizeof(U64));
|
||||
dst->mxcsr.u32 = xsave->MxCsr;
|
||||
dst->mxcsr_mask.u32 = xsave->MxCsr_Mask;
|
||||
{
|
||||
M128A *float_s = xsave->FloatRegisters;
|
||||
REGS_Reg80 *float_d = &dst->fpr0;
|
||||
REGS_Reg80 *float_d = &dst->st0;
|
||||
for(U32 n = 0; n < 8; n += 1, float_s += 1, float_d += 1)
|
||||
{
|
||||
MemoryCopy(float_d, float_s, sizeof(*float_d));
|
||||
@@ -991,7 +938,7 @@ dmn_w32_thread_write_reg_block(Arch arch, HANDLE thread, void *reg_block)
|
||||
ctx.EFlags = src->eflags.u32;
|
||||
fxsave->ControlWord = src->fcw.u16;
|
||||
fxsave->StatusWord = src->fsw.u16;
|
||||
fxsave->TagWord = dmn_w32_xsave_tag_word_from_real_tag_word(src->ftw.u16);
|
||||
fxsave->TagWord = src->ftw.u16;
|
||||
fxsave->ErrorOpcode = src->fop.u16;
|
||||
fxsave->ErrorSelector = src->fcs.u16;
|
||||
fxsave->DataSelector = src->fds.u16;
|
||||
@@ -1001,7 +948,7 @@ dmn_w32_thread_write_reg_block(Arch arch, HANDLE thread, void *reg_block)
|
||||
fxsave->MxCsr_Mask = src->mxcsr_mask.u32;
|
||||
{
|
||||
M128A *float_d = fxsave->FloatRegisters;
|
||||
REGS_Reg80 *float_s = &src->fpr0;
|
||||
REGS_Reg80 *float_s = &src->st0;
|
||||
for(U32 n = 0; n < 8; n += 1, float_s += 1, float_d += 1)
|
||||
{
|
||||
MemoryCopy(float_d, float_s, 10);
|
||||
@@ -1098,15 +1045,13 @@ dmn_w32_thread_write_reg_block(Arch arch, HANDLE thread, void *reg_block)
|
||||
ctx->EFlags = src->rflags.u64;
|
||||
fxsave->ControlWord = src->fcw.u16;
|
||||
fxsave->StatusWord = src->fsw.u16;
|
||||
fxsave->TagWord = dmn_w32_xsave_tag_word_from_real_tag_word(src->ftw.u16);
|
||||
fxsave->TagWord = src->ftw;
|
||||
fxsave->ErrorOpcode = src->fop.u16;
|
||||
fxsave->ErrorSelector = src->fcs.u16;
|
||||
fxsave->DataSelector = src->fds.u16;
|
||||
fxsave->ErrorOffset = src->fip.u64;
|
||||
fxsave->DataOffset = src->fdp.u64;
|
||||
MemoryCopy(&fxsave->ErrorOffset, &src->fip.u64, sizeof(U64));
|
||||
MemoryCopy(&fxsave->DataOffset, &src->fdp.u64, sizeof(U64));
|
||||
{
|
||||
M128A *float_d = fxsave->FloatRegisters;
|
||||
REGS_Reg80 *float_s = &src->fpr0;
|
||||
REGS_Reg80 *float_s = &src->st0;
|
||||
for(U32 n = 0; n < 8; n += 1, float_s += 1, float_d += 1)
|
||||
{
|
||||
MemoryCopy(float_d, float_s, 10);
|
||||
|
||||
@@ -350,8 +350,6 @@ internal String16 dmn_w32_read_memory_str16(Arena *arena, HANDLE process_handle,
|
||||
internal DMN_W32_ImageInfo dmn_w32_image_info_from_process_base_vaddr(HANDLE process, U64 base_vaddr);
|
||||
|
||||
//- rjf: threads
|
||||
internal U16 dmn_w32_real_tag_word_from_xsave(XSAVE_FORMAT *fxsave);
|
||||
internal U16 dmn_w32_xsave_tag_word_from_real_tag_word(U16 ftw);
|
||||
internal B32 dmn_w32_thread_read_reg_block(Arch arch, HANDLE thread, void *reg_block);
|
||||
internal B32 dmn_w32_thread_write_reg_block(Arch arch, HANDLE thread, void *reg_block);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user