[PATCH 2/2] tools/winedbg: Add support for printing SSE (XMM) registers.

Zebediah Figura z.figura12 at gmail.com
Fri Jun 23 16:02:24 CDT 2017


Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
---
 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




More information about the wine-patches mailing list