From: Zebediah Figura Subject: [PATCH 2/2] tools/winedbg: Add support for printing SSE (XMM) registers. Message-Id: <20170623210224.31523-2-zfigura@codeweavers.com> Date: Fri, 23 Jun 2017 16:02:24 -0500 In-Reply-To: <20170623210224.31523-1-zfigura@codeweavers.com> References: <20170623210224.31523-1-zfigura@codeweavers.com> Signed-off-by: Zebediah Figura --- programs/winedbg/be_i386.c | 57 +++++++++++++++++++++++++++++++++++++++++++- programs/winedbg/be_x86_64.c | 16 +++++++++++++ programs/winedbg/debugger.h | 1 + programs/winedbg/types.c | 9 +++++++ 4 files changed, 82 insertions(+), 1 deletion(-) diff --git a/programs/winedbg/be_i386.c b/programs/winedbg/be_i386.c index 154d4e7c851..49c9ecc6d24 100644 --- a/programs/winedbg/be_i386.c +++ b/programs/winedbg/be_i386.c @@ -33,6 +33,30 @@ extern void be_i386_disasm_one_insn(ADDRESS64* addr, int display); #define IS_VM86_MODE(ctx) (ctx->EFlags & V86_FLAG) +typedef struct DECLSPEC_ALIGN(16) _M128A { + ULONGLONG Low; + LONGLONG High; +} M128A, *PM128A; + +typedef struct _XMM_SAVE_AREA32 { + WORD ControlWord; /* 000 */ + WORD StatusWord; /* 002 */ + BYTE TagWord; /* 004 */ + BYTE Reserved1; /* 005 */ + WORD ErrorOpcode; /* 006 */ + DWORD ErrorOffset; /* 008 */ + WORD ErrorSelector; /* 00c */ + WORD Reserved2; /* 00e */ + DWORD DataOffset; /* 010 */ + WORD DataSelector; /* 014 */ + WORD Reserved3; /* 016 */ + DWORD MxCsr; /* 018 */ + DWORD MxCsr_Mask; /* 01c */ + M128A FloatRegisters[8]; /* 020 */ + M128A XmmRegisters[16]; /* 0a0 */ + BYTE Reserved4[96]; /* 1a0 */ +} XMM_SAVE_AREA32, *PXMM_SAVE_AREA32; + static ADDRESS_MODE get_selector_type(HANDLE hThread, const CONTEXT* ctx, WORD sel) { LDT_ENTRY le; @@ -129,6 +153,9 @@ static void be_i386_single_step(CONTEXT* ctx, BOOL enable) static void be_i386_all_print_context(HANDLE hThread, const CONTEXT* ctx) { + static const char mxcsr_flags[16][4] = { "IE", "DE", "ZE", "OE", "UE", "PE", "DAZ", "IM", + "DM", "ZM", "OM", "UM", "PM", "R-", "R+", "FZ" }; + XMM_SAVE_AREA32 *xmm_area; long double ST[8]; /* These are for floating regs */ int cnt; @@ -192,6 +219,26 @@ static void be_i386_all_print_context(HANDLE hThread, const CONTEXT* ctx) memcpy(&ST[cnt], &ctx->FloatSave.RegisterArea[cnt * 10], 10); dbg_printf(" ST%d:%Lf ", cnt, ST[cnt]); } + + xmm_area = (XMM_SAVE_AREA32 *) &ctx->ExtendedRegisters; + + dbg_printf(" mxcsr: %04x (", xmm_area->MxCsr ); + for (cnt = 0; cnt < 16; cnt++) + if (xmm_area->MxCsr & (1 << cnt)) dbg_printf( " %s", mxcsr_flags[cnt] ); + dbg_printf(" )\n"); + + for (cnt = 0; cnt < 8; cnt++) + { + dbg_printf( " xmm%u: uint=%016llx%016llx", cnt, + xmm_area->XmmRegisters[cnt].High, xmm_area->XmmRegisters[cnt].Low ); + dbg_printf( " double={%g; %g}", *(double *)&xmm_area->XmmRegisters[cnt].Low, + *(double *)&xmm_area->XmmRegisters[cnt].High ); + dbg_printf( " float={%g; %g; %g; %g}\n", + (double)*((float *)&xmm_area->XmmRegisters[cnt] + 0), + (double)*((float *)&xmm_area->XmmRegisters[cnt] + 1), + (double)*((float *)&xmm_area->XmmRegisters[cnt] + 2), + (double)*((float *)&xmm_area->XmmRegisters[cnt] + 3) ); + } dbg_printf("\n"); } @@ -295,6 +342,14 @@ static struct dbg_internal_var be_i386_ctx[] = {CV_REG_ST0+5, "ST5", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, FloatSave.RegisterArea[50]), dbg_itype_long_real}, {CV_REG_ST0+6, "ST6", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, FloatSave.RegisterArea[60]), dbg_itype_long_real}, {CV_REG_ST0+7, "ST7", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, FloatSave.RegisterArea[70]), dbg_itype_long_real}, + {CV_AMD64_XMM0, "XMM0", (DWORD_PTR*)(FIELD_OFFSET(CONTEXT, ExtendedRegisters) + FIELD_OFFSET(XMM_SAVE_AREA32, XmmRegisters[0])), dbg_itype_m128a}, + {CV_AMD64_XMM0+1, "XMM1", (DWORD_PTR*)(FIELD_OFFSET(CONTEXT, ExtendedRegisters) + FIELD_OFFSET(XMM_SAVE_AREA32, XmmRegisters[1])), dbg_itype_m128a}, + {CV_AMD64_XMM0+2, "XMM2", (DWORD_PTR*)(FIELD_OFFSET(CONTEXT, ExtendedRegisters) + FIELD_OFFSET(XMM_SAVE_AREA32, XmmRegisters[2])), dbg_itype_m128a}, + {CV_AMD64_XMM0+3, "XMM3", (DWORD_PTR*)(FIELD_OFFSET(CONTEXT, ExtendedRegisters) + FIELD_OFFSET(XMM_SAVE_AREA32, XmmRegisters[3])), dbg_itype_m128a}, + {CV_AMD64_XMM0+4, "XMM4", (DWORD_PTR*)(FIELD_OFFSET(CONTEXT, ExtendedRegisters) + FIELD_OFFSET(XMM_SAVE_AREA32, XmmRegisters[4])), dbg_itype_m128a}, + {CV_AMD64_XMM0+5, "XMM5", (DWORD_PTR*)(FIELD_OFFSET(CONTEXT, ExtendedRegisters) + FIELD_OFFSET(XMM_SAVE_AREA32, XmmRegisters[5])), dbg_itype_m128a}, + {CV_AMD64_XMM0+6, "XMM6", (DWORD_PTR*)(FIELD_OFFSET(CONTEXT, ExtendedRegisters) + FIELD_OFFSET(XMM_SAVE_AREA32, XmmRegisters[6])), dbg_itype_m128a}, + {CV_AMD64_XMM0+7, "XMM7", (DWORD_PTR*)(FIELD_OFFSET(CONTEXT, ExtendedRegisters) + FIELD_OFFSET(XMM_SAVE_AREA32, XmmRegisters[7])), dbg_itype_m128a}, {0, NULL, 0, dbg_itype_none} }; @@ -747,7 +802,7 @@ static int be_i386_adjust_pc_for_break(CONTEXT* ctx, BOOL way) static BOOL be_i386_fetch_integer(const struct dbg_lvalue* lvalue, unsigned size, BOOL is_signed, LONGLONG* ret) { - if (size != 1 && size != 2 && size != 4 && size != 8) return FALSE; + if (size != 1 && size != 2 && size != 4 && size != 8 && size != 16) return FALSE; memset(ret, 0, sizeof(*ret)); /* clear unread bytes */ /* FIXME: this assumes that debuggee and debugger use the same diff --git a/programs/winedbg/be_x86_64.c b/programs/winedbg/be_x86_64.c index d2a480f2c94..76497e90a9e 100644 --- a/programs/winedbg/be_x86_64.c +++ b/programs/winedbg/be_x86_64.c @@ -245,6 +245,22 @@ static struct dbg_internal_var be_x86_64_ctx[] = {CV_AMD64_ST0+5, "ST5", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, FloatSave.RegisterArea[50]), dbg_itype_long_real}, {CV_AMD64_ST0+6, "ST6", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, FloatSave.RegisterArea[60]), dbg_itype_long_real}, {CV_AMD64_ST0+7, "ST7", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, FloatSave.RegisterArea[70]), dbg_itype_long_real}, + {CV_AMD64_XMM0, "XMM0", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Xmm0), dbg_itype_m128a}, + {CV_AMD64_XMM0+1, "XMM1", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Xmm1), dbg_itype_m128a}, + {CV_AMD64_XMM0+2, "XMM2", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Xmm2), dbg_itype_m128a}, + {CV_AMD64_XMM0+3, "XMM3", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Xmm3), dbg_itype_m128a}, + {CV_AMD64_XMM0+4, "XMM4", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Xmm4), dbg_itype_m128a}, + {CV_AMD64_XMM0+5, "XMM5", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Xmm5), dbg_itype_m128a}, + {CV_AMD64_XMM0+6, "XMM6", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Xmm6), dbg_itype_m128a}, + {CV_AMD64_XMM0+7, "XMM7", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Xmm7), dbg_itype_m128a}, + {CV_AMD64_XMM8, "XMM8", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Xmm8), dbg_itype_m128a}, + {CV_AMD64_XMM8+1, "XMM9", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Xmm9), dbg_itype_m128a}, + {CV_AMD64_XMM8+2, "XMM10", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Xmm10), dbg_itype_m128a}, + {CV_AMD64_XMM8+3, "XMM11", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Xmm11), dbg_itype_m128a}, + {CV_AMD64_XMM8+4, "XMM12", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Xmm12), dbg_itype_m128a}, + {CV_AMD64_XMM8+5, "XMM13", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Xmm13), dbg_itype_m128a}, + {CV_AMD64_XMM8+6, "XMM14", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Xmm14), dbg_itype_m128a}, + {CV_AMD64_XMM8+7, "XMM15", (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Xmm15), dbg_itype_m128a}, {0, NULL, 0, dbg_itype_none} }; diff --git a/programs/winedbg/debugger.h b/programs/winedbg/debugger.h index e8a4d7375fb..a4ffd705961 100644 --- a/programs/winedbg/debugger.h +++ b/programs/winedbg/debugger.h @@ -84,6 +84,7 @@ enum dbg_internal_types dbg_itype_astring, dbg_itype_ustring, dbg_itype_segptr, /* hack for segmented pointers */ + dbg_itype_m128a, /* 128-bit (XMM) registers */ dbg_itype_none = 0xffffffff }; diff --git a/programs/winedbg/types.c b/programs/winedbg/types.c index f050db59a63..3268d7e4dbf 100644 --- a/programs/winedbg/types.c +++ b/programs/winedbg/types.c @@ -921,6 +921,15 @@ BOOL types_get_info(const struct dbg_type* type, IMAGEHLP_SYMBOL_TYPE_INFO ti, v default: WINE_FIXME("unsupported %u for long real\n", ti); return FALSE; } break; + case dbg_itype_m128a: + switch (ti) + { + case TI_GET_SYMTAG: X(DWORD) = SymTagBaseType; break; + case TI_GET_LENGTH: X(DWORD64) = 16; break; + case TI_GET_BASETYPE: X(DWORD) = btUInt; break; + default: WINE_FIXME("unsupported %u for XMM register\n", ti); return FALSE; + } + break; default: WINE_FIXME("unsupported type id 0x%lx\n", type->id); } -- 2.13.1