[PATCH 3/5] winedbg: Use WOW64_CONTEXT instead of CONTEXT for i386 backend.

Zebediah Figura zfigura at codeweavers.com
Tue Jun 12 17:53:18 CDT 2018


Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
---
 programs/winedbg/be_cpu.h       |  22 ++---
 programs/winedbg/be_i386.c      | 211 ++++++++++++++++++++--------------------
 programs/winedbg/be_x86_64.c    |  73 +++++++-------
 programs/winedbg/debugger.h     |  12 ++-
 programs/winedbg/gdbproxy.c     |  35 ++++---
 programs/winedbg/memory.c       |   2 +-
 programs/winedbg/stack.c        |  16 +--
 programs/winedbg/tgt_active.c   |  10 +-
 programs/winedbg/tgt_minidump.c |   2 +-
 programs/winedbg/winedbg.c      |   2 +-
 10 files changed, 199 insertions(+), 186 deletions(-)

diff --git a/programs/winedbg/be_cpu.h b/programs/winedbg/be_cpu.h
index 751ac9d..03776d0 100644
--- a/programs/winedbg/be_cpu.h
+++ b/programs/winedbg/be_cpu.h
@@ -37,13 +37,13 @@ struct backend_cpu
      * in an ADDRESS64 (except an linear one).
      * Non segmented CPU shall use be_cpu_build_addr
      */
-    BOOL                (*build_addr)(HANDLE hThread, const CONTEXT* ctx,
+    BOOL                (*build_addr)(HANDLE hThread, const dbg_ctx_t *ctx,
                                       ADDRESS64* addr, unsigned seg,
                                       unsigned long offset);
     /* Retrieves in addr an address related to the context (program counter, stack
      * pointer, frame pointer)
      */
-    BOOL                (*get_addr)(HANDLE hThread, const CONTEXT* ctx,
+    BOOL                (*get_addr)(HANDLE hThread, const dbg_ctx_t *ctx,
                                     enum be_cpu_addr, ADDRESS64* addr);
 
     /* returns which kind of information a given register number refers to */
@@ -53,13 +53,13 @@ struct backend_cpu
      * context manipulation 
      * ------------------------------------------------------------------------------- */
     /* Enables/disables CPU single step mode (depending on enable) */
-    void                (*single_step)(CONTEXT* ctx, BOOL enable);
+    void                (*single_step)(dbg_ctx_t *ctx, BOOL enable);
     /* Dumps out the content of the context */
-    void                (*print_context)(HANDLE hThread, const CONTEXT* ctx, int all_regs);
+    void                (*print_context)(HANDLE hThread, const dbg_ctx_t *ctx, int all_regs);
     /* Prints information about segments. Non segmented CPU should leave this
      * function empty
      */
-    void                (*print_segment_info)(HANDLE hThread, const CONTEXT* ctx);
+    void                (*print_segment_info)(HANDLE hThread, const dbg_ctx_t *ctx);
     /* all the CONTEXT's relative variables, bound to this CPU */
     const struct dbg_internal_var* context_vars;
 
@@ -89,22 +89,22 @@ struct backend_cpu
      * -------------------------------------------------------------------------------*/
     /* Inserts an Xpoint in the CPU context and/or debuggee address space */
     BOOL                (*insert_Xpoint)(HANDLE hProcess, const struct be_process_io* pio,
-                                         CONTEXT* ctx, enum be_xpoint_type type,
+                                         dbg_ctx_t *ctx, enum be_xpoint_type type,
                                          void* addr, unsigned long* val, unsigned size);
     /* Removes an Xpoint in the CPU context and/or debuggee address space */
     BOOL                (*remove_Xpoint)(HANDLE hProcess, const struct be_process_io* pio,
-                                         CONTEXT* ctx, enum be_xpoint_type type,
+                                         dbg_ctx_t *ctx, enum be_xpoint_type type,
                                          void* addr, unsigned long val, unsigned size);
     /* Checks whether a given watchpoint has been triggered */
-    BOOL                (*is_watchpoint_set)(const CONTEXT* ctx, unsigned idx);
+    BOOL                (*is_watchpoint_set)(const dbg_ctx_t *ctx, unsigned idx);
     /* Clears the watchpoint indicator */
-    void                (*clear_watchpoint)(CONTEXT* ctx, unsigned idx);
+    void                (*clear_watchpoint)(dbg_ctx_t *ctx, unsigned idx);
     /* After a break instruction is executed, in the corresponding exception handler,
      * some CPUs report the address of the insn after the break insn, some others 
      * report the address of the break insn itself.
      * This function lets adjust the context PC to reflect this behavior.
      */
-    int                 (*adjust_pc_for_break)(CONTEXT* ctx, BOOL way);
+    int                 (*adjust_pc_for_break)(dbg_ctx_t *ctx, BOOL way);
     /* -------------------------------------------------------------------------------
      * basic type read/write 
      * -------------------------------------------------------------------------------*/
@@ -118,5 +118,5 @@ struct backend_cpu
 
 /* some handy functions for non segmented CPUs */
 void*    be_cpu_linearize(HANDLE hThread, const ADDRESS64*);
-BOOL be_cpu_build_addr(HANDLE hThread, const CONTEXT* ctx, ADDRESS64* addr,
+BOOL be_cpu_build_addr(HANDLE hThread, const dbg_ctx_t *ctx, ADDRESS64* addr,
                        unsigned seg, unsigned long offset);
diff --git a/programs/winedbg/be_i386.c b/programs/winedbg/be_i386.c
index 4d22708..bdc2ece 100644
--- a/programs/winedbg/be_i386.c
+++ b/programs/winedbg/be_i386.c
@@ -57,7 +57,7 @@ typedef struct _XMM_SAVE_AREA32 {
     BYTE Reserved4[96];      /* 1a0 */
 } XMM_SAVE_AREA32, *PXMM_SAVE_AREA32;
 
-static ADDRESS_MODE get_selector_type(HANDLE hThread, const CONTEXT* ctx, WORD sel)
+static ADDRESS_MODE get_selector_type(HANDLE hThread, const WOW64_CONTEXT *ctx, WORD sel)
 {
     LDT_ENTRY	le;
 
@@ -93,7 +93,7 @@ static void* be_i386_linearize(HANDLE hThread, const ADDRESS64* addr)
     return NULL;
 }
 
-static BOOL be_i386_build_addr(HANDLE hThread, const CONTEXT* ctx, ADDRESS64* addr,
+static BOOL be_i386_build_addr(HANDLE hThread, const dbg_ctx_t *ctx, ADDRESS64* addr,
                                unsigned seg, unsigned long offset)
 {
     addr->Mode    = AddrModeFlat;
@@ -101,7 +101,7 @@ static BOOL be_i386_build_addr(HANDLE hThread, const CONTEXT* ctx, ADDRESS64* ad
     addr->Offset  = offset;
     if (seg)
     {
-        addr->Mode = get_selector_type(hThread, ctx, seg);
+        addr->Mode = get_selector_type(hThread, &ctx->x86, seg);
         switch (addr->Mode)
         {
         case AddrModeReal:
@@ -119,17 +119,17 @@ static BOOL be_i386_build_addr(HANDLE hThread, const CONTEXT* ctx, ADDRESS64* ad
     return TRUE;
 }
 
-static BOOL be_i386_get_addr(HANDLE hThread, const CONTEXT* ctx,
+static BOOL be_i386_get_addr(HANDLE hThread, const dbg_ctx_t *ctx,
                              enum be_cpu_addr bca, ADDRESS64* addr)
 {
     switch (bca)
     {
     case be_cpu_addr_pc:
-        return be_i386_build_addr(hThread, ctx, addr, ctx->SegCs, ctx->Eip);
+        return be_i386_build_addr(hThread, ctx, addr, ctx->x86.SegCs, ctx->x86.Eip);
     case be_cpu_addr_stack:
-        return be_i386_build_addr(hThread, ctx, addr, ctx->SegSs, ctx->Esp);
+        return be_i386_build_addr(hThread, ctx, addr, ctx->x86.SegSs, ctx->x86.Esp);
     case be_cpu_addr_frame:
-        return be_i386_build_addr(hThread, ctx, addr, ctx->SegSs, ctx->Ebp);
+        return be_i386_build_addr(hThread, ctx, addr, ctx->x86.SegSs, ctx->x86.Ebp);
     }
     return FALSE;
 }
@@ -145,16 +145,17 @@ static BOOL be_i386_get_register_info(int regno, enum be_cpu_addr* kind)
     return FALSE;
 }
 
-static void be_i386_single_step(CONTEXT* ctx, BOOL enable)
+static void be_i386_single_step(dbg_ctx_t *ctx, BOOL enable)
 {
-    if (enable) ctx->EFlags |= STEP_FLAG;
-    else ctx->EFlags &= ~STEP_FLAG;
+    if (enable) ctx->x86.EFlags |= STEP_FLAG;
+    else ctx->x86.EFlags &= ~STEP_FLAG;
 }
 
-static void be_i386_all_print_context(HANDLE hThread, const CONTEXT* ctx)
+static void be_i386_all_print_context(HANDLE hThread, const dbg_ctx_t *pctx)
 {
     static const char mxcsr_flags[16][4] = { "IE", "DE", "ZE", "OE", "UE", "PE", "DAZ", "IM",
                                              "DM", "ZM", "OM", "UM", "PM", "R-", "R+", "FZ" };
+    const WOW64_CONTEXT *ctx = &pctx->x86;
     XMM_SAVE_AREA32 *xmm_area;
     long double ST[8];                         /* These are for floating regs */
     int         cnt;
@@ -245,9 +246,10 @@ static void be_i386_all_print_context(HANDLE hThread, const CONTEXT* ctx)
     dbg_printf("\n");
 }
 
-static void be_i386_print_context(HANDLE hThread, const CONTEXT* ctx, int all_regs)
+static void be_i386_print_context(HANDLE hThread, const dbg_ctx_t *pctx, int all_regs)
 {
     static const char flags[] = "aVR-N--ODITSZ-A-P-C";
+    const WOW64_CONTEXT *ctx = &pctx->x86;
     int i;
     char        buf[33];
 
@@ -287,72 +289,73 @@ static void be_i386_print_context(HANDLE hThread, const CONTEXT* ctx, int all_re
         break;
     }
 
-    if (all_regs) be_i386_all_print_context(hThread, ctx); /* print floating regs */
+    if (all_regs) be_i386_all_print_context(hThread, pctx);
 
 }
 
-static void be_i386_print_segment_info(HANDLE hThread, const CONTEXT* ctx)
+static void be_i386_print_segment_info(HANDLE hThread, const dbg_ctx_t *ctx)
 {
-    if (get_selector_type(hThread, ctx, ctx->SegCs) == AddrMode1616)
+    if (get_selector_type(hThread, &ctx->x86, ctx->x86.SegCs) == AddrMode1616)
     {
-        info_win32_segments(ctx->SegDs >> 3, 1);
-        if (ctx->SegEs != ctx->SegDs) info_win32_segments(ctx->SegEs >> 3, 1);
+        info_win32_segments(ctx->x86.SegDs >> 3, 1);
+        if (ctx->x86.SegEs != ctx->x86.SegDs)
+            info_win32_segments(ctx->x86.SegEs >> 3, 1);
     }
-    info_win32_segments(ctx->SegFs >> 3, 1);
+    info_win32_segments(ctx->x86.SegFs >> 3, 1);
 }
 
 static struct dbg_internal_var be_i386_ctx[] =
 {
-    {CV_REG_AL,         "AL",           (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Eax),     dbg_itype_unsigned_char_int},
-    {CV_REG_CL,         "CL",           (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Ecx),     dbg_itype_unsigned_char_int},
-    {CV_REG_DL,         "DL",           (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Edx),     dbg_itype_unsigned_char_int},
-    {CV_REG_BL,         "BL",           (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Ebx),     dbg_itype_unsigned_char_int},
-    {CV_REG_AH,         "AH",           (DWORD_PTR*)(FIELD_OFFSET(CONTEXT, Eax)+1), dbg_itype_unsigned_char_int},
-    {CV_REG_CH,         "CH",           (DWORD_PTR*)(FIELD_OFFSET(CONTEXT, Ecx)+1), dbg_itype_unsigned_char_int},
-    {CV_REG_DH,         "DH",           (DWORD_PTR*)(FIELD_OFFSET(CONTEXT, Edx)+1), dbg_itype_unsigned_char_int},
-    {CV_REG_BH,         "BH",           (DWORD_PTR*)(FIELD_OFFSET(CONTEXT, Ebx)+1), dbg_itype_unsigned_char_int},
-    {CV_REG_AX,         "AX",           (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Eax),     dbg_itype_unsigned_short_int},
-    {CV_REG_CX,         "CX",           (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Ecx),     dbg_itype_unsigned_short_int},
-    {CV_REG_DX,         "DX",           (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Edx),     dbg_itype_unsigned_short_int},
-    {CV_REG_BX,         "BX",           (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Ebx),     dbg_itype_unsigned_short_int},
-    {CV_REG_SP,         "SP",           (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Esp),     dbg_itype_unsigned_short_int},
-    {CV_REG_BP,         "BP",           (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Ebp),     dbg_itype_unsigned_short_int},
-    {CV_REG_SI,         "SI",           (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Esi),     dbg_itype_unsigned_short_int},
-    {CV_REG_DI,         "DI",           (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Edi),     dbg_itype_unsigned_short_int},
-    {CV_REG_EAX,        "EAX",          (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Eax),     dbg_itype_unsigned_int},
-    {CV_REG_ECX,        "ECX",          (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Ecx),     dbg_itype_unsigned_int},
-    {CV_REG_EDX,        "EDX",          (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Edx),     dbg_itype_unsigned_int},
-    {CV_REG_EBX,        "EBX",          (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Ebx),     dbg_itype_unsigned_int},
-    {CV_REG_ESP,        "ESP",          (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Esp),     dbg_itype_unsigned_int},
-    {CV_REG_EBP,        "EBP",          (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Ebp),     dbg_itype_unsigned_int},
-    {CV_REG_ESI,        "ESI",          (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Esi),     dbg_itype_unsigned_int},
-    {CV_REG_EDI,        "EDI",          (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Edi),     dbg_itype_unsigned_int},
-    {CV_REG_ES,         "ES",           (DWORD_PTR*)FIELD_OFFSET(CONTEXT, SegEs),   dbg_itype_unsigned_short_int},
-    {CV_REG_CS,         "CS",           (DWORD_PTR*)FIELD_OFFSET(CONTEXT, SegCs),   dbg_itype_unsigned_short_int},
-    {CV_REG_SS,         "SS",           (DWORD_PTR*)FIELD_OFFSET(CONTEXT, SegSs),   dbg_itype_unsigned_short_int},
-    {CV_REG_DS,         "DS",           (DWORD_PTR*)FIELD_OFFSET(CONTEXT, SegDs),   dbg_itype_unsigned_short_int},
-    {CV_REG_FS,         "FS",           (DWORD_PTR*)FIELD_OFFSET(CONTEXT, SegFs),   dbg_itype_unsigned_short_int},
-    {CV_REG_GS,         "GS",           (DWORD_PTR*)FIELD_OFFSET(CONTEXT, SegGs),   dbg_itype_unsigned_short_int},
-    {CV_REG_IP,         "IP",           (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Eip),     dbg_itype_unsigned_short_int},
-    {CV_REG_FLAGS,      "FLAGS",        (DWORD_PTR*)FIELD_OFFSET(CONTEXT, EFlags),  dbg_itype_unsigned_short_int},
-    {CV_REG_EIP,        "EIP",          (DWORD_PTR*)FIELD_OFFSET(CONTEXT, Eip),     dbg_itype_unsigned_int},
-    {CV_REG_EFLAGS,     "EFLAGS",       (DWORD_PTR*)FIELD_OFFSET(CONTEXT, EFlags),  dbg_itype_unsigned_int},
-    {CV_REG_ST0,        "ST0",          (DWORD_PTR*)FIELD_OFFSET(CONTEXT, FloatSave.RegisterArea[ 0]), dbg_itype_long_real},
-    {CV_REG_ST0+1,      "ST1",          (DWORD_PTR*)FIELD_OFFSET(CONTEXT, FloatSave.RegisterArea[10]), dbg_itype_long_real},
-    {CV_REG_ST0+2,      "ST2",          (DWORD_PTR*)FIELD_OFFSET(CONTEXT, FloatSave.RegisterArea[20]), dbg_itype_long_real},
-    {CV_REG_ST0+3,      "ST3",          (DWORD_PTR*)FIELD_OFFSET(CONTEXT, FloatSave.RegisterArea[30]), dbg_itype_long_real},
-    {CV_REG_ST0+4,      "ST4",          (DWORD_PTR*)FIELD_OFFSET(CONTEXT, FloatSave.RegisterArea[40]), dbg_itype_long_real},
-    {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},
+    {CV_REG_AL,         "AL",           (DWORD_PTR*)FIELD_OFFSET(WOW64_CONTEXT, Eax),     dbg_itype_unsigned_char_int},
+    {CV_REG_CL,         "CL",           (DWORD_PTR*)FIELD_OFFSET(WOW64_CONTEXT, Ecx),     dbg_itype_unsigned_char_int},
+    {CV_REG_DL,         "DL",           (DWORD_PTR*)FIELD_OFFSET(WOW64_CONTEXT, Edx),     dbg_itype_unsigned_char_int},
+    {CV_REG_BL,         "BL",           (DWORD_PTR*)FIELD_OFFSET(WOW64_CONTEXT, Ebx),     dbg_itype_unsigned_char_int},
+    {CV_REG_AH,         "AH",           (DWORD_PTR*)(FIELD_OFFSET(WOW64_CONTEXT, Eax)+1), dbg_itype_unsigned_char_int},
+    {CV_REG_CH,         "CH",           (DWORD_PTR*)(FIELD_OFFSET(WOW64_CONTEXT, Ecx)+1), dbg_itype_unsigned_char_int},
+    {CV_REG_DH,         "DH",           (DWORD_PTR*)(FIELD_OFFSET(WOW64_CONTEXT, Edx)+1), dbg_itype_unsigned_char_int},
+    {CV_REG_BH,         "BH",           (DWORD_PTR*)(FIELD_OFFSET(WOW64_CONTEXT, Ebx)+1), dbg_itype_unsigned_char_int},
+    {CV_REG_AX,         "AX",           (DWORD_PTR*)FIELD_OFFSET(WOW64_CONTEXT, Eax),     dbg_itype_unsigned_short_int},
+    {CV_REG_CX,         "CX",           (DWORD_PTR*)FIELD_OFFSET(WOW64_CONTEXT, Ecx),     dbg_itype_unsigned_short_int},
+    {CV_REG_DX,         "DX",           (DWORD_PTR*)FIELD_OFFSET(WOW64_CONTEXT, Edx),     dbg_itype_unsigned_short_int},
+    {CV_REG_BX,         "BX",           (DWORD_PTR*)FIELD_OFFSET(WOW64_CONTEXT, Ebx),     dbg_itype_unsigned_short_int},
+    {CV_REG_SP,         "SP",           (DWORD_PTR*)FIELD_OFFSET(WOW64_CONTEXT, Esp),     dbg_itype_unsigned_short_int},
+    {CV_REG_BP,         "BP",           (DWORD_PTR*)FIELD_OFFSET(WOW64_CONTEXT, Ebp),     dbg_itype_unsigned_short_int},
+    {CV_REG_SI,         "SI",           (DWORD_PTR*)FIELD_OFFSET(WOW64_CONTEXT, Esi),     dbg_itype_unsigned_short_int},
+    {CV_REG_DI,         "DI",           (DWORD_PTR*)FIELD_OFFSET(WOW64_CONTEXT, Edi),     dbg_itype_unsigned_short_int},
+    {CV_REG_EAX,        "EAX",          (DWORD_PTR*)FIELD_OFFSET(WOW64_CONTEXT, Eax),     dbg_itype_unsigned_int},
+    {CV_REG_ECX,        "ECX",          (DWORD_PTR*)FIELD_OFFSET(WOW64_CONTEXT, Ecx),     dbg_itype_unsigned_int},
+    {CV_REG_EDX,        "EDX",          (DWORD_PTR*)FIELD_OFFSET(WOW64_CONTEXT, Edx),     dbg_itype_unsigned_int},
+    {CV_REG_EBX,        "EBX",          (DWORD_PTR*)FIELD_OFFSET(WOW64_CONTEXT, Ebx),     dbg_itype_unsigned_int},
+    {CV_REG_ESP,        "ESP",          (DWORD_PTR*)FIELD_OFFSET(WOW64_CONTEXT, Esp),     dbg_itype_unsigned_int},
+    {CV_REG_EBP,        "EBP",          (DWORD_PTR*)FIELD_OFFSET(WOW64_CONTEXT, Ebp),     dbg_itype_unsigned_int},
+    {CV_REG_ESI,        "ESI",          (DWORD_PTR*)FIELD_OFFSET(WOW64_CONTEXT, Esi),     dbg_itype_unsigned_int},
+    {CV_REG_EDI,        "EDI",          (DWORD_PTR*)FIELD_OFFSET(WOW64_CONTEXT, Edi),     dbg_itype_unsigned_int},
+    {CV_REG_ES,         "ES",           (DWORD_PTR*)FIELD_OFFSET(WOW64_CONTEXT, SegEs),   dbg_itype_unsigned_short_int},
+    {CV_REG_CS,         "CS",           (DWORD_PTR*)FIELD_OFFSET(WOW64_CONTEXT, SegCs),   dbg_itype_unsigned_short_int},
+    {CV_REG_SS,         "SS",           (DWORD_PTR*)FIELD_OFFSET(WOW64_CONTEXT, SegSs),   dbg_itype_unsigned_short_int},
+    {CV_REG_DS,         "DS",           (DWORD_PTR*)FIELD_OFFSET(WOW64_CONTEXT, SegDs),   dbg_itype_unsigned_short_int},
+    {CV_REG_FS,         "FS",           (DWORD_PTR*)FIELD_OFFSET(WOW64_CONTEXT, SegFs),   dbg_itype_unsigned_short_int},
+    {CV_REG_GS,         "GS",           (DWORD_PTR*)FIELD_OFFSET(WOW64_CONTEXT, SegGs),   dbg_itype_unsigned_short_int},
+    {CV_REG_IP,         "IP",           (DWORD_PTR*)FIELD_OFFSET(WOW64_CONTEXT, Eip),     dbg_itype_unsigned_short_int},
+    {CV_REG_FLAGS,      "FLAGS",        (DWORD_PTR*)FIELD_OFFSET(WOW64_CONTEXT, EFlags),  dbg_itype_unsigned_short_int},
+    {CV_REG_EIP,        "EIP",          (DWORD_PTR*)FIELD_OFFSET(WOW64_CONTEXT, Eip),     dbg_itype_unsigned_int},
+    {CV_REG_EFLAGS,     "EFLAGS",       (DWORD_PTR*)FIELD_OFFSET(WOW64_CONTEXT, EFlags),  dbg_itype_unsigned_int},
+    {CV_REG_ST0,        "ST0",          (DWORD_PTR*)FIELD_OFFSET(WOW64_CONTEXT, FloatSave.RegisterArea[ 0]), dbg_itype_long_real},
+    {CV_REG_ST0+1,      "ST1",          (DWORD_PTR*)FIELD_OFFSET(WOW64_CONTEXT, FloatSave.RegisterArea[10]), dbg_itype_long_real},
+    {CV_REG_ST0+2,      "ST2",          (DWORD_PTR*)FIELD_OFFSET(WOW64_CONTEXT, FloatSave.RegisterArea[20]), dbg_itype_long_real},
+    {CV_REG_ST0+3,      "ST3",          (DWORD_PTR*)FIELD_OFFSET(WOW64_CONTEXT, FloatSave.RegisterArea[30]), dbg_itype_long_real},
+    {CV_REG_ST0+4,      "ST4",          (DWORD_PTR*)FIELD_OFFSET(WOW64_CONTEXT, FloatSave.RegisterArea[40]), dbg_itype_long_real},
+    {CV_REG_ST0+5,      "ST5",          (DWORD_PTR*)FIELD_OFFSET(WOW64_CONTEXT, FloatSave.RegisterArea[50]), dbg_itype_long_real},
+    {CV_REG_ST0+6,      "ST6",          (DWORD_PTR*)FIELD_OFFSET(WOW64_CONTEXT, FloatSave.RegisterArea[60]), dbg_itype_long_real},
+    {CV_REG_ST0+7,      "ST7",          (DWORD_PTR*)FIELD_OFFSET(WOW64_CONTEXT, FloatSave.RegisterArea[70]), dbg_itype_long_real},
+    {CV_AMD64_XMM0,     "XMM0",         (DWORD_PTR*)(FIELD_OFFSET(WOW64_CONTEXT, ExtendedRegisters) + FIELD_OFFSET(XMM_SAVE_AREA32, XmmRegisters[0])), dbg_itype_m128a},
+    {CV_AMD64_XMM0+1,   "XMM1",         (DWORD_PTR*)(FIELD_OFFSET(WOW64_CONTEXT, ExtendedRegisters) + FIELD_OFFSET(XMM_SAVE_AREA32, XmmRegisters[1])), dbg_itype_m128a},
+    {CV_AMD64_XMM0+2,   "XMM2",         (DWORD_PTR*)(FIELD_OFFSET(WOW64_CONTEXT, ExtendedRegisters) + FIELD_OFFSET(XMM_SAVE_AREA32, XmmRegisters[2])), dbg_itype_m128a},
+    {CV_AMD64_XMM0+3,   "XMM3",         (DWORD_PTR*)(FIELD_OFFSET(WOW64_CONTEXT, ExtendedRegisters) + FIELD_OFFSET(XMM_SAVE_AREA32, XmmRegisters[3])), dbg_itype_m128a},
+    {CV_AMD64_XMM0+4,   "XMM4",         (DWORD_PTR*)(FIELD_OFFSET(WOW64_CONTEXT, ExtendedRegisters) + FIELD_OFFSET(XMM_SAVE_AREA32, XmmRegisters[4])), dbg_itype_m128a},
+    {CV_AMD64_XMM0+5,   "XMM5",         (DWORD_PTR*)(FIELD_OFFSET(WOW64_CONTEXT, ExtendedRegisters) + FIELD_OFFSET(XMM_SAVE_AREA32, XmmRegisters[5])), dbg_itype_m128a},
+    {CV_AMD64_XMM0+6,   "XMM6",         (DWORD_PTR*)(FIELD_OFFSET(WOW64_CONTEXT, ExtendedRegisters) + FIELD_OFFSET(XMM_SAVE_AREA32, XmmRegisters[6])), dbg_itype_m128a},
+    {CV_AMD64_XMM0+7,   "XMM7",         (DWORD_PTR*)(FIELD_OFFSET(WOW64_CONTEXT, ExtendedRegisters) + FIELD_OFFSET(XMM_SAVE_AREA32, XmmRegisters[7])), dbg_itype_m128a},
     {0,                 NULL,           0,                                      dbg_itype_none}
 };
 
@@ -477,8 +480,8 @@ static BOOL be_i386_is_func_call(const void* insn, ADDRESS64* callee)
     unsigned            operand_size;
     ADDRESS_MODE        cs_addr_mode;
 
-    cs_addr_mode = get_selector_type(dbg_curr_thread->handle, &dbg_context,
-                                     dbg_context.SegCs);
+    cs_addr_mode = get_selector_type(dbg_curr_thread->handle, &dbg_context.x86,
+                                     dbg_context.x86.SegCs);
     operand_size = get_size(cs_addr_mode);
 
     /* get operand_size (also getting rid of the various prefixes */
@@ -498,7 +501,7 @@ static BOOL be_i386_is_func_call(const void* insn, ADDRESS64* callee)
         callee->Mode = cs_addr_mode;
         if (!fetch_value((const char*)insn + 1, operand_size, &delta))
             return FALSE;
-        callee->Segment = dbg_context.SegCs;
+        callee->Segment = dbg_context.x86.SegCs;
         callee->Offset = (DWORD)insn + 1 + (operand_size / 8) + delta;
         return TRUE;
 
@@ -506,7 +509,7 @@ static BOOL be_i386_is_func_call(const void* insn, ADDRESS64* callee)
         if (!dbg_read_memory((const char*)insn + 1 + operand_size / 8,
                              &segment, sizeof(segment)))
             return FALSE;
-        callee->Mode = get_selector_type(dbg_curr_thread->handle, &dbg_context,
+        callee->Mode = get_selector_type(dbg_curr_thread->handle, &dbg_context.x86,
                                          segment);
         if (!fetch_value((const char*)insn + 1, operand_size, &delta))
             return FALSE;
@@ -521,7 +524,7 @@ static BOOL be_i386_is_func_call(const void* insn, ADDRESS64* callee)
         switch ((ch >> 3) & 0x07)
         {
         case 0x02:
-            segment = dbg_context.SegCs;
+            segment = dbg_context.x86.SegCs;
             break;
         case 0x03:
             if (!dbg_read_memory((const char*)insn + 1 + operand_size / 8,
@@ -555,10 +558,10 @@ static BOOL be_i386_is_func_call(const void* insn, ADDRESS64* callee)
                     if (!dbg_read_memory((const char*)addr + operand_size, &segment, sizeof(segment)))
                         return FALSE;
                 }
-                else segment = dbg_context.SegCs;
+                else segment = dbg_context.x86.SegCs;
                 if (!dbg_read_memory((const char*)addr, &dst, sizeof(dst)))
                     return FALSE;
-                callee->Mode = get_selector_type(dbg_curr_thread->handle, &dbg_context, segment);
+                callee->Mode = get_selector_type(dbg_curr_thread->handle, &dbg_context.x86, segment);
                 callee->Segment = segment;
                 callee->Offset = dst;
                 return TRUE;
@@ -567,14 +570,14 @@ static BOOL be_i386_is_func_call(const void* insn, ADDRESS64* callee)
         default:
             switch (ch & 0x07)
             {
-            case 0x00: dst = dbg_context.Eax; break;
-            case 0x01: dst = dbg_context.Ecx; break;
-            case 0x02: dst = dbg_context.Edx; break;
-            case 0x03: dst = dbg_context.Ebx; break;
-            case 0x04: dst = dbg_context.Esp; break;
-            case 0x05: dst = dbg_context.Ebp; break;
-            case 0x06: dst = dbg_context.Esi; break;
-            case 0x07: dst = dbg_context.Edi; break;
+            case 0x00: dst = dbg_context.x86.Eax; break;
+            case 0x01: dst = dbg_context.x86.Ecx; break;
+            case 0x02: dst = dbg_context.x86.Edx; break;
+            case 0x03: dst = dbg_context.x86.Ebx; break;
+            case 0x04: dst = dbg_context.x86.Esp; break;
+            case 0x05: dst = dbg_context.x86.Ebp; break;
+            case 0x06: dst = dbg_context.x86.Esi; break;
+            case 0x07: dst = dbg_context.x86.Edi; break;
             }
             if ((ch >> 6) != 0x03) /* indirect address */
             {
@@ -589,10 +592,10 @@ static BOOL be_i386_is_func_call(const void* insn, ADDRESS64* callee)
                     if (!dbg_read_memory((const char*)dst + operand_size, &segment, sizeof(segment)))
                         return FALSE;
                 }
-                else segment = dbg_context.SegCs;
+                else segment = dbg_context.x86.SegCs;
                 if (!dbg_read_memory((const char*)dst, &delta, sizeof(delta)))
                     return FALSE;
-                callee->Mode = get_selector_type(dbg_curr_thread->handle, &dbg_context,
+                callee->Mode = get_selector_type(dbg_curr_thread->handle, &dbg_context.x86,
                                                  segment);
                 callee->Segment = segment;
                 callee->Offset = delta;
@@ -600,7 +603,7 @@ static BOOL be_i386_is_func_call(const void* insn, ADDRESS64* callee)
             else
             {
                 callee->Mode = cs_addr_mode;
-                callee->Segment = dbg_context.SegCs;
+                callee->Segment = dbg_context.x86.SegCs;
                 callee->Offset = dst;
             }
         }
@@ -618,8 +621,8 @@ static BOOL be_i386_is_jump(const void* insn, ADDRESS64* jumpee)
     unsigned            operand_size;
     ADDRESS_MODE        cs_addr_mode;
 
-    cs_addr_mode = get_selector_type(dbg_curr_thread->handle, &dbg_context,
-                                     dbg_context.SegCs);
+    cs_addr_mode = get_selector_type(dbg_curr_thread->handle, &dbg_context.x86,
+                                     dbg_context.x86.SegCs);
     operand_size = get_size(cs_addr_mode);
 
     /* get operand_size (also getting rid of the various prefixes */
@@ -639,7 +642,7 @@ static BOOL be_i386_is_jump(const void* insn, ADDRESS64* jumpee)
         jumpee->Mode = cs_addr_mode;
         if (!fetch_value((const char*)insn + 1, operand_size, &delta))
             return FALSE;
-        jumpee->Segment = dbg_context.SegCs;
+        jumpee->Segment = dbg_context.x86.SegCs;
         jumpee->Offset = (DWORD)insn + 1 + (operand_size / 8) + delta;
         return TRUE;
     default: WINE_FIXME("unknown %x\n", ch); return FALSE;
@@ -672,8 +675,10 @@ static BOOL be_i386_is_jump(const void* insn, ADDRESS64* jumpee)
 #define	DR7_ENABLE_MASK(dr)	(1<<(DR7_LOCAL_ENABLE_SHIFT+DR7_ENABLE_SIZE*(dr)))
 #define	IS_DR7_SET(ctrl,dr) 	((ctrl)&DR7_ENABLE_MASK(dr))
 
-static inline int be_i386_get_unused_DR(CONTEXT* ctx, DWORD** r)
+static inline int be_i386_get_unused_DR(dbg_ctx_t *pctx, DWORD** r)
 {
+    WOW64_CONTEXT *ctx = &pctx->x86;
+
     if (!IS_DR7_SET(ctx->Dr7, 0))
     {
         *r = &ctx->Dr0;
@@ -700,7 +705,7 @@ static inline int be_i386_get_unused_DR(CONTEXT* ctx, DWORD** r)
 }
 
 static BOOL be_i386_insert_Xpoint(HANDLE hProcess, const struct be_process_io* pio,
-                                  CONTEXT* ctx, enum be_xpoint_type type,
+                                  dbg_ctx_t *ctx, enum be_xpoint_type type,
                                   void* addr, unsigned long* val, unsigned size)
 {
     unsigned char       ch;
@@ -738,10 +743,10 @@ static BOOL be_i386_insert_Xpoint(HANDLE hProcess, const struct be_process_io* p
         }
         *val = reg;
         /* clear old values */
-        ctx->Dr7 &= ~(0x0F << (DR7_CONTROL_SHIFT + DR7_CONTROL_SIZE * reg));
+        ctx->x86.Dr7 &= ~(0x0F << (DR7_CONTROL_SHIFT + DR7_CONTROL_SIZE * reg));
         /* set the correct ones */
-        ctx->Dr7 |= bits << (DR7_CONTROL_SHIFT + DR7_CONTROL_SIZE * reg);
-	ctx->Dr7 |= DR7_ENABLE_MASK(reg) | DR7_LOCAL_SLOWDOWN;
+        ctx->x86.Dr7 |= bits << (DR7_CONTROL_SHIFT + DR7_CONTROL_SIZE * reg);
+        ctx->x86.Dr7 |= DR7_ENABLE_MASK(reg) | DR7_LOCAL_SLOWDOWN;
         break;
     default:
         dbg_printf("Unknown bp type %c\n", type);
@@ -751,7 +756,7 @@ static BOOL be_i386_insert_Xpoint(HANDLE hProcess, const struct be_process_io* p
 }
 
 static BOOL be_i386_remove_Xpoint(HANDLE hProcess, const struct be_process_io* pio,
-                                  CONTEXT* ctx, enum be_xpoint_type type,
+                                  dbg_ctx_t *ctx, enum be_xpoint_type type,
                                   void* addr, unsigned long val, unsigned size)
 {
     SIZE_T              sz;
@@ -772,7 +777,7 @@ static BOOL be_i386_remove_Xpoint(HANDLE hProcess, const struct be_process_io* p
     case be_xpoint_watch_read:
     case be_xpoint_watch_write:
         /* simply disable the entry */
-        ctx->Dr7 &= ~DR7_ENABLE_MASK(val);
+        ctx->x86.Dr7 &= ~DR7_ENABLE_MASK(val);
         break;
     default:
         dbg_printf("Unknown bp type %c\n", type);
@@ -781,24 +786,24 @@ static BOOL be_i386_remove_Xpoint(HANDLE hProcess, const struct be_process_io* p
     return TRUE;
 }
 
-static BOOL be_i386_is_watchpoint_set(const CONTEXT* ctx, unsigned idx)
+static BOOL be_i386_is_watchpoint_set(const dbg_ctx_t *ctx, unsigned idx)
 {
-    return ctx->Dr6 & (1 << idx);
+    return ctx->x86.Dr6 & (1 << idx);
 }
 
-static void be_i386_clear_watchpoint(CONTEXT* ctx, unsigned idx)
+static void be_i386_clear_watchpoint(dbg_ctx_t *ctx, unsigned idx)
 {
-    ctx->Dr6 &= ~(1 << idx);
+    ctx->x86.Dr6 &= ~(1 << idx);
 }
 
-static int be_i386_adjust_pc_for_break(CONTEXT* ctx, BOOL way)
+static int be_i386_adjust_pc_for_break(dbg_ctx_t *ctx, BOOL way)
 {
     if (way)
     {
-        ctx->Eip--;
+        ctx->x86.Eip--;
         return -1;
     }
-    ctx->Eip++;
+    ctx->x86.Eip++;
     return 1;
 }
 
diff --git a/programs/winedbg/be_x86_64.c b/programs/winedbg/be_x86_64.c
index 280cdec..450cc87 100644
--- a/programs/winedbg/be_x86_64.c
+++ b/programs/winedbg/be_x86_64.c
@@ -31,23 +31,23 @@ WINE_DEFAULT_DEBUG_CHANNEL(winedbg);
 
 #define STEP_FLAG 0x00000100 /* single step flag */
 
-static BOOL be_x86_64_get_addr(HANDLE hThread, const CONTEXT* ctx,
+static BOOL be_x86_64_get_addr(HANDLE hThread, const dbg_ctx_t *ctx,
                                enum be_cpu_addr bca, ADDRESS64* addr)
 {
     addr->Mode = AddrModeFlat;
     switch (bca)
     {
     case be_cpu_addr_pc:
-        addr->Segment = ctx->SegCs;
-        addr->Offset = ctx->Rip;
+        addr->Segment = ctx->ctx.SegCs;
+        addr->Offset = ctx->ctx.Rip;
         return TRUE;
     case be_cpu_addr_stack:
-        addr->Segment = ctx->SegSs;
-        addr->Offset = ctx->Rsp;
+        addr->Segment = ctx->ctx.SegSs;
+        addr->Offset = ctx->ctx.Rsp;
         return TRUE;
     case be_cpu_addr_frame:
-        addr->Segment = ctx->SegSs;
-        addr->Offset = ctx->Rbp;
+        addr->Segment = ctx->ctx.SegSs;
+        addr->Offset = ctx->ctx.Rbp;
         return TRUE;
     default:
         addr->Mode = -1;
@@ -67,10 +67,10 @@ static BOOL be_x86_64_get_register_info(int regno, enum be_cpu_addr* kind)
     return FALSE;
 }
 
-static void be_x86_64_single_step(CONTEXT* ctx, BOOL enable)
+static void be_x86_64_single_step(dbg_ctx_t *ctx, BOOL enable)
 {
-    if (enable) ctx->EFlags |= STEP_FLAG;
-    else ctx->EFlags &= ~STEP_FLAG;
+    if (enable) ctx->ctx.EFlags |= STEP_FLAG;
+    else ctx->ctx.EFlags &= ~STEP_FLAG;
 }
 
 static inline long double m128a_to_longdouble(const M128A m)
@@ -81,12 +81,13 @@ static inline long double m128a_to_longdouble(const M128A m)
     return *(long double*)&m;
 }
 
-static void be_x86_64_print_context(HANDLE hThread, const CONTEXT* ctx,
+static void be_x86_64_print_context(HANDLE hThread, const dbg_ctx_t *pctx,
                                     int all_regs)
 {
     static const char mxcsr_flags[16][4] = { "IE", "DE", "ZE", "OE", "UE", "PE", "DAZ", "IM",
                                              "DM", "ZM", "OM", "UM", "PM", "R-", "R+", "FZ" };
     static const char flags[] = "aVR-N--ODITSZ-A-P-C";
+    const CONTEXT *ctx = &pctx->ctx;
     char buf[33];
     int i;
 
@@ -183,7 +184,7 @@ static void be_x86_64_print_context(HANDLE hThread, const CONTEXT* ctx,
     }
 }
 
-static void be_x86_64_print_segment_info(HANDLE hThread, const CONTEXT* ctx)
+static void be_x86_64_print_segment_info(HANDLE hThread, const dbg_ctx_t *ctx)
 {
 }
 
@@ -390,7 +391,7 @@ static BOOL be_x86_64_is_func_call(const void* insn, ADDRESS64* callee)
 
     /* that's the only mode we support anyway */
     callee->Mode = AddrModeFlat;
-    callee->Segment = dbg_context.SegCs;
+    callee->Segment = dbg_context.ctx.SegCs;
 
     switch (ch)
     {
@@ -435,14 +436,14 @@ static BOOL be_x86_64_is_func_call(const void* insn, ADDRESS64* callee)
         default:
             switch (f_rm(ch))
             {
-            case 0x00: dst = dbg_context.Rax; break;
-            case 0x01: dst = dbg_context.Rcx; break;
-            case 0x02: dst = dbg_context.Rdx; break;
-            case 0x03: dst = dbg_context.Rbx; break;
-            case 0x04: dst = dbg_context.Rsp; break;
-            case 0x05: dst = dbg_context.Rbp; break;
-            case 0x06: dst = dbg_context.Rsi; break;
-            case 0x07: dst = dbg_context.Rdi; break;
+            case 0x00: dst = dbg_context.ctx.Rax; break;
+            case 0x01: dst = dbg_context.ctx.Rcx; break;
+            case 0x02: dst = dbg_context.ctx.Rdx; break;
+            case 0x03: dst = dbg_context.ctx.Rbx; break;
+            case 0x04: dst = dbg_context.ctx.Rsp; break;
+            case 0x05: dst = dbg_context.ctx.Rbp; break;
+            case 0x06: dst = dbg_context.ctx.Rsi; break;
+            case 0x07: dst = dbg_context.ctx.Rdi; break;
             }
             if (f_mod(ch) != 0x03)
                 WINE_FIXME("Unsupported yet call insn (0xFF 0x%02x) at %p\n", ch, insn);
@@ -494,8 +495,10 @@ extern void be_x86_64_disasm_one_insn(ADDRESS64* addr, int display);
 #define	DR7_ENABLE_MASK(dr)	(1<<(DR7_LOCAL_ENABLE_SHIFT+DR7_ENABLE_SIZE*(dr)))
 #define	IS_DR7_SET(ctrl,dr) 	((ctrl)&DR7_ENABLE_MASK(dr))
 
-static inline int be_x86_64_get_unused_DR(CONTEXT* ctx, DWORD64** r)
+static inline int be_x86_64_get_unused_DR(dbg_ctx_t *pctx, DWORD64** r)
 {
+    CONTEXT *ctx = &pctx->ctx;
+
     if (!IS_DR7_SET(ctx->Dr7, 0))
     {
         *r = &ctx->Dr0;
@@ -522,7 +525,7 @@ static inline int be_x86_64_get_unused_DR(CONTEXT* ctx, DWORD64** r)
 }
 
 static BOOL be_x86_64_insert_Xpoint(HANDLE hProcess, const struct be_process_io* pio,
-                                    CONTEXT* ctx, enum be_xpoint_type type,
+                                    dbg_ctx_t *ctx, enum be_xpoint_type type,
                                     void* addr, unsigned long* val, unsigned size)
 {
     unsigned char       ch;
@@ -561,10 +564,10 @@ static BOOL be_x86_64_insert_Xpoint(HANDLE hProcess, const struct be_process_io*
         }
         *val = reg;
         /* clear old values */
-        ctx->Dr7 &= ~(0x0F << (DR7_CONTROL_SHIFT + DR7_CONTROL_SIZE * reg));
+        ctx->ctx.Dr7 &= ~(0x0F << (DR7_CONTROL_SHIFT + DR7_CONTROL_SIZE * reg));
         /* set the correct ones */
-        ctx->Dr7 |= bits << (DR7_CONTROL_SHIFT + DR7_CONTROL_SIZE * reg);
-	ctx->Dr7 |= DR7_ENABLE_MASK(reg) | DR7_LOCAL_SLOWDOWN;
+        ctx->ctx.Dr7 |= bits << (DR7_CONTROL_SHIFT + DR7_CONTROL_SIZE * reg);
+        ctx->ctx.Dr7 |= DR7_ENABLE_MASK(reg) | DR7_LOCAL_SLOWDOWN;
         break;
     default:
         dbg_printf("Unknown bp type %c\n", type);
@@ -574,7 +577,7 @@ static BOOL be_x86_64_insert_Xpoint(HANDLE hProcess, const struct be_process_io*
 }
 
 static BOOL be_x86_64_remove_Xpoint(HANDLE hProcess, const struct be_process_io* pio,
-                                    CONTEXT* ctx, enum be_xpoint_type type,
+                                    dbg_ctx_t *ctx, enum be_xpoint_type type,
                                     void* addr, unsigned long val, unsigned size)
 {
     SIZE_T              sz;
@@ -594,7 +597,7 @@ static BOOL be_x86_64_remove_Xpoint(HANDLE hProcess, const struct be_process_io*
     case be_xpoint_watch_read:
     case be_xpoint_watch_write:
         /* simply disable the entry */
-        ctx->Dr7 &= ~DR7_ENABLE_MASK(val);
+        ctx->ctx.Dr7 &= ~DR7_ENABLE_MASK(val);
         break;
     default:
         dbg_printf("Unknown bp type %c\n", type);
@@ -603,24 +606,24 @@ static BOOL be_x86_64_remove_Xpoint(HANDLE hProcess, const struct be_process_io*
     return TRUE;
 }
 
-static BOOL be_x86_64_is_watchpoint_set(const CONTEXT* ctx, unsigned idx)
+static BOOL be_x86_64_is_watchpoint_set(const dbg_ctx_t *ctx, unsigned idx)
 {
-    return ctx->Dr6 & (1 << idx);
+    return ctx->ctx.Dr6 & (1 << idx);
 }
 
-static void be_x86_64_clear_watchpoint(CONTEXT* ctx, unsigned idx)
+static void be_x86_64_clear_watchpoint(dbg_ctx_t *ctx, unsigned idx)
 {
-    ctx->Dr6 &= ~(1 << idx);
+    ctx->ctx.Dr6 &= ~(1 << idx);
 }
 
-static int be_x86_64_adjust_pc_for_break(CONTEXT* ctx, BOOL way)
+static int be_x86_64_adjust_pc_for_break(dbg_ctx_t *ctx, BOOL way)
 {
     if (way)
     {
-        ctx->Rip--;
+        ctx->ctx.Rip--;
         return -1;
     }
-    ctx->Rip++;
+    ctx->ctx.Rip++;
     return 1;
 }
 
diff --git a/programs/winedbg/debugger.h b/programs/winedbg/debugger.h
index 0ceb150..490bd06 100644
--- a/programs/winedbg/debugger.h
+++ b/programs/winedbg/debugger.h
@@ -170,6 +170,12 @@ typedef struct tagTHREADNAME_INFO
    DWORD   dwFlags;    /* Reserved for future use.  Must be zero. */
 } THREADNAME_INFO;
 
+typedef union dbg_ctx
+{
+    CONTEXT ctx;
+    WOW64_CONTEXT x86;
+} dbg_ctx_t;
+
 struct dbg_thread
 {
     struct list                 entry;
@@ -196,7 +202,7 @@ struct dbg_thread
         DWORD_PTR               linear_pc;
         DWORD_PTR               linear_frame;
         DWORD_PTR               linear_stack;
-        CONTEXT                 context;        /* context we got out of stackwalk for this frame */
+        dbg_ctx_t               context;        /* context we got out of stackwalk for this frame */
         BOOL                    is_ctx_valid;   /* is the context above valid */
     }*                          frames;
     int                         num_frames;
@@ -255,7 +261,7 @@ extern	struct dbg_process*	dbg_curr_process;
 extern	DWORD_PTR	        dbg_curr_pid;
 extern	struct dbg_thread*	dbg_curr_thread;
 extern	DWORD_PTR	        dbg_curr_tid;
-extern  CONTEXT 	        dbg_context;
+extern  dbg_ctx_t               dbg_context;
 extern  BOOL                    dbg_interactiveP;
 extern  HANDLE                  dbg_houtput;
 
@@ -396,7 +402,7 @@ extern void             stack_backtrace(DWORD threadID);
 extern BOOL             stack_set_frame(int newframe);
 extern BOOL             stack_get_current_frame(IMAGEHLP_STACK_FRAME* ihsf);
 extern BOOL             stack_get_register_frame(const struct dbg_internal_var* div, DWORD_PTR** pval);
-extern unsigned         stack_fetch_frames(const CONTEXT* ctx);
+extern unsigned         stack_fetch_frames(const dbg_ctx_t *ctx);
 extern BOOL             stack_get_current_symbol(SYMBOL_INFO* sym);
 
   /* symbol.c */
diff --git a/programs/winedbg/gdbproxy.c b/programs/winedbg/gdbproxy.c
index 8742135..d5786b2 100644
--- a/programs/winedbg/gdbproxy.c
+++ b/programs/winedbg/gdbproxy.c
@@ -95,7 +95,7 @@ struct gdb_context
     /* current Win32 trap env */
     unsigned                    last_sig;
     BOOL                        in_trap;
-    CONTEXT                     context;
+    dbg_ctx_t                   context;
     /* Win32 information */
     struct dbg_process*         process;
     /* Unix environment */
@@ -497,13 +497,13 @@ static struct cpu_register cpu_register_map[] = {
 
 static const size_t cpu_num_regs = (sizeof(cpu_register_map) / sizeof(cpu_register_map[0]));
 
-static inline void* cpu_register_ptr(CONTEXT* ctx, unsigned idx)
+static inline void* cpu_register_ptr(dbg_ctx_t *ctx, unsigned idx)
 {
     assert(idx < cpu_num_regs);
     return (char*)ctx + cpu_register_map[idx].ctx_offset;
 }
 
-static inline DWORD64   cpu_register(CONTEXT* ctx, unsigned idx)
+static inline DWORD64 cpu_register(dbg_ctx_t *ctx, unsigned idx)
 {
     switch (cpu_register_map[idx].ctx_length)
     {
@@ -518,7 +518,7 @@ static inline DWORD64   cpu_register(CONTEXT* ctx, unsigned idx)
     }
 }
 
-static inline   void    cpu_register_hex_from(CONTEXT* ctx, unsigned idx, const char** phex)
+static inline void cpu_register_hex_from(dbg_ctx_t* ctx, unsigned idx, const char **phex)
 {
     if (cpu_register_map[idx].gdb_length == cpu_register_map[idx].ctx_length)
         hex_from(cpu_register_ptr(ctx, idx), *phex, cpu_register_map[idx].gdb_length);
@@ -550,10 +550,9 @@ static inline   void    cpu_register_hex_from(CONTEXT* ctx, unsigned idx, const
  * =============================================== *
  */
 
-static BOOL fetch_context(struct gdb_context* gdbctx, HANDLE h, CONTEXT* ctx)
+static BOOL fetch_context(struct gdb_context *gdbctx, HANDLE h, dbg_ctx_t *ctx)
 {
-    ctx->ContextFlags = CONTEXT_ALL;
-    if (!GetThreadContext(h, ctx))
+    if (!GetThreadContext(h, &ctx->ctx))
     {
         if (gdbctx->trace & GDBPXY_TRC_WIN32_ERROR)
             fprintf(stderr, "Can't get thread's context\n");
@@ -769,7 +768,7 @@ static void resume_debuggee(struct gdb_context* gdbctx, DWORD cont)
 {
     if (dbg_curr_thread)
     {
-        if (!SetThreadContext(dbg_curr_thread->handle, &gdbctx->context))
+        if (!SetThreadContext(dbg_curr_thread->handle, &gdbctx->context.ctx))
             if (gdbctx->trace & GDBPXY_TRC_WIN32_ERROR)
                 fprintf(stderr, "Cannot set context on thread %04x\n", dbg_curr_thread->tid);
         if (!ContinueDebugEvent(gdbctx->process->pid, dbg_curr_thread->tid, cont))
@@ -789,7 +788,7 @@ static void resume_debuggee_thread(struct gdb_context* gdbctx, DWORD cont, unsig
     {
         if(dbg_curr_thread->tid  == threadid){
             /* Windows debug and GDB don't seem to work well here, windows only likes ContinueDebugEvent being used on the reporter of the event */
-            if (!SetThreadContext(dbg_curr_thread->handle, &gdbctx->context))
+            if (!SetThreadContext(dbg_curr_thread->handle, &gdbctx->context.ctx))
                 if (gdbctx->trace & GDBPXY_TRC_WIN32_ERROR)
                     fprintf(stderr, "Cannot set context on thread %04x\n", dbg_curr_thread->tid);
             if (!ContinueDebugEvent(gdbctx->process->pid, dbg_curr_thread->tid, cont))
@@ -1443,7 +1442,7 @@ static enum packet_return packet_detach(struct gdb_context* gdbctx)
 static enum packet_return packet_read_registers(struct gdb_context* gdbctx)
 {
     int                 i;
-    CONTEXT             ctx;
+    dbg_ctx_t ctx;
 
     assert(gdbctx->in_trap);
 
@@ -1463,8 +1462,8 @@ static enum packet_return packet_read_registers(struct gdb_context* gdbctx)
 static enum packet_return packet_write_registers(struct gdb_context* gdbctx)
 {
     unsigned    i;
-    CONTEXT     ctx;
-    CONTEXT*    pctx = &gdbctx->context;
+    dbg_ctx_t ctx;
+    dbg_ctx_t *pctx = &gdbctx->context;
     const char* ptr;
 
     assert(gdbctx->in_trap);
@@ -1479,7 +1478,7 @@ static enum packet_return packet_write_registers(struct gdb_context* gdbctx)
     for (i = 0; i < cpu_num_regs; i++)
         cpu_register_hex_from(pctx, i, &ptr);
 
-    if (pctx != &gdbctx->context && !SetThreadContext(gdbctx->other_thread->handle, pctx))
+    if (pctx != &gdbctx->context && !SetThreadContext(gdbctx->other_thread->handle, &pctx->ctx))
     {
         if (gdbctx->trace & GDBPXY_TRC_WIN32_ERROR)
             fprintf(stderr, "Cannot set context on thread %04x\n", gdbctx->other_thread->tid);
@@ -1616,8 +1615,8 @@ static enum packet_return packet_write_memory(struct gdb_context* gdbctx)
 static enum packet_return packet_read_register(struct gdb_context* gdbctx)
 {
     unsigned            reg;
-    CONTEXT             ctx;
-    CONTEXT*            pctx = &gdbctx->context;
+    dbg_ctx_t ctx;
+    dbg_ctx_t *pctx = &gdbctx->context;
 
     assert(gdbctx->in_trap);
     reg = hex_to_int(gdbctx->in_packet, gdbctx->in_packet_len);
@@ -1650,8 +1649,8 @@ static enum packet_return packet_write_register(struct gdb_context* gdbctx)
 {
     unsigned            reg;
     char*               ptr;
-    CONTEXT             ctx;
-    CONTEXT*            pctx = &gdbctx->context;
+    dbg_ctx_t ctx;
+    dbg_ctx_t *pctx = &gdbctx->context;
 
     assert(gdbctx->in_trap);
 
@@ -1678,7 +1677,7 @@ static enum packet_return packet_write_register(struct gdb_context* gdbctx)
     }
 
     cpu_register_hex_from(pctx, reg, (const char**)&ptr);
-    if (pctx != &gdbctx->context && !SetThreadContext(gdbctx->other_thread->handle, pctx))
+    if (pctx != &gdbctx->context && !SetThreadContext(gdbctx->other_thread->handle, &pctx->ctx))
     {
         if (gdbctx->trace & GDBPXY_TRC_WIN32_ERROR)
             fprintf(stderr, "Cannot set context for thread %04x\n", gdbctx->other_thread->tid);
diff --git a/programs/winedbg/memory.c b/programs/winedbg/memory.c
index 6e65fa6..f3585f2 100644
--- a/programs/winedbg/memory.c
+++ b/programs/winedbg/memory.c
@@ -39,7 +39,7 @@ void* be_cpu_linearize(HANDLE hThread, const ADDRESS64* addr)
     return (void*)(DWORD_PTR)addr->Offset;
 }
 
-BOOL be_cpu_build_addr(HANDLE hThread, const CONTEXT* ctx, ADDRESS64* addr,
+BOOL be_cpu_build_addr(HANDLE hThread, const dbg_ctx_t *ctx, ADDRESS64* addr,
                        unsigned seg, unsigned long offset)
 {
     addr->Mode    = AddrModeFlat;
diff --git a/programs/winedbg/stack.c b/programs/winedbg/stack.c
index 2ab4e60..a036107 100644
--- a/programs/winedbg/stack.c
+++ b/programs/winedbg/stack.c
@@ -184,14 +184,14 @@ static BOOL CALLBACK stack_read_mem(HANDLE hProc, DWORD64 addr,
  *
  * Do a backtrace on the current thread
  */
-unsigned stack_fetch_frames(const CONTEXT* _ctx)
+unsigned stack_fetch_frames(const dbg_ctx_t* _ctx)
 {
     STACKFRAME64 sf;
     unsigned     nf = 0;
     /* as native stackwalk can modify the context passed to it, simply copy
      * it to avoid any damage
      */
-    CONTEXT      ctx = *_ctx;
+    dbg_ctx_t ctx = *_ctx;
     BOOL         ret;
 
     HeapFree(GetProcessHeap(), 0, dbg_curr_thread->frames);
@@ -351,21 +351,21 @@ static void backtrace_tid(struct dbg_process* pcs, DWORD tid)
         dbg_printf("Unknown thread id (%04x) in process (%04x)\n", tid, pcs->pid);
     else
     {
-        CONTEXT context;
+        dbg_ctx_t ctx = {0};
 
         dbg_curr_tid = dbg_curr_thread->tid;
-        memset(&context, 0, sizeof(context));
-        context.ContextFlags = CONTEXT_FULL;
+
+        ctx.ctx.ContextFlags = CONTEXT_FULL;
         if (SuspendThread(dbg_curr_thread->handle) != -1)
         {
-            if (!GetThreadContext(dbg_curr_thread->handle, &context))
+            if (!GetThreadContext(dbg_curr_thread->handle, &ctx.ctx))
             {
                 dbg_printf("Can't get context for thread %04x in current process\n",
                            tid);
             }
             else
             {
-                stack_fetch_frames(&context);
+                stack_fetch_frames(&ctx);
                 backtrace();
             }
             ResumeThread(dbg_curr_thread->handle);
@@ -386,7 +386,7 @@ static void backtrace_all(void)
 {
     struct dbg_process* process = dbg_curr_process;
     struct dbg_thread*  thread = dbg_curr_thread;
-    CONTEXT             ctx = dbg_context;
+    dbg_ctx_t ctx = dbg_context;
     DWORD               cpid = dbg_curr_pid;
     THREADENTRY32       entry;
     HANDLE              snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
diff --git a/programs/winedbg/tgt_active.c b/programs/winedbg/tgt_active.c
index d891cfe..8c94402 100644
--- a/programs/winedbg/tgt_active.c
+++ b/programs/winedbg/tgt_active.c
@@ -91,7 +91,7 @@ BOOL dbg_attach_debuggee(DWORD pid, BOOL cofe)
 
 static unsigned dbg_fetch_context(void)
 {
-    dbg_context.ContextFlags = CONTEXT_CONTROL
+    dbg_context.ctx.ContextFlags = CONTEXT_CONTROL
         | CONTEXT_INTEGER
 #ifdef CONTEXT_FLOATING_POINT
         | CONTEXT_FLOATING_POINT
@@ -103,7 +103,7 @@ static unsigned dbg_fetch_context(void)
         | CONTEXT_DEBUG_REGISTERS
 #endif
         ;
-    if (!GetThreadContext(dbg_curr_thread->handle, &dbg_context))
+    if (!GetThreadContext(dbg_curr_thread->handle, &dbg_context.ctx))
     {
         WINE_WARN("Can't get thread's context\n");
         return FALSE;
@@ -356,7 +356,7 @@ static unsigned dbg_handle_debug_event(DEBUG_EVENT* de)
                                         de->u.Exception.dwFirstChance);
             if (cont && dbg_curr_thread)
             {
-                SetThreadContext(dbg_curr_thread->handle, &dbg_context);
+                SetThreadContext(dbg_curr_thread->handle, &dbg_context.ctx);
             }
         }
         break;
@@ -539,7 +539,7 @@ static void dbg_resume_debuggee(DWORD cont)
                    dbg_curr_thread->exec_count);
         if (dbg_curr_thread)
         {
-            if (!SetThreadContext(dbg_curr_thread->handle, &dbg_context))
+            if (!SetThreadContext(dbg_curr_thread->handle, &dbg_context.ctx))
                 dbg_printf("Cannot set ctx on %04lx\n", dbg_curr_tid);
         }
     }
@@ -1001,7 +1001,7 @@ static BOOL tgt_process_active_close_process(struct dbg_process* pcs, BOOL kill)
         dbg_curr_process->be_cpu->single_step(&dbg_context, FALSE);
         if (dbg_curr_thread->in_exception)
         {
-            SetThreadContext(dbg_curr_thread->handle, &dbg_context);
+            SetThreadContext(dbg_curr_thread->handle, &dbg_context.ctx);
             ContinueDebugEvent(dbg_curr_pid, dbg_curr_tid, DBG_CONTINUE);
         }
     }
diff --git a/programs/winedbg/tgt_minidump.c b/programs/winedbg/tgt_minidump.c
index a17f32b..f168633 100644
--- a/programs/winedbg/tgt_minidump.c
+++ b/programs/winedbg/tgt_minidump.c
@@ -69,7 +69,7 @@ void minidump_write(const char* file, const EXCEPTION_RECORD* rec)
         mei.ThreadId = dbg_curr_thread->tid;
         mei.ExceptionPointers = &ep;
         ep.ExceptionRecord = (EXCEPTION_RECORD*)rec;
-        ep.ContextRecord = &dbg_context;
+        ep.ContextRecord = &dbg_context.ctx;
         mei.ClientPointers = FALSE;
     }
     MiniDumpWriteDump(dbg_curr_process->handle, dbg_curr_process->pid,
diff --git a/programs/winedbg/winedbg.c b/programs/winedbg/winedbg.c
index b32b24c..b5ffd76 100644
--- a/programs/winedbg/winedbg.c
+++ b/programs/winedbg/winedbg.c
@@ -87,7 +87,7 @@ struct dbg_process*	dbg_curr_process = NULL;
 struct dbg_thread*	dbg_curr_thread = NULL;
 DWORD_PTR	        dbg_curr_tid = 0;
 DWORD_PTR	        dbg_curr_pid = 0;
-CONTEXT                 dbg_context;
+dbg_ctx_t               dbg_context;
 BOOL    	        dbg_interactiveP = FALSE;
 HANDLE                  dbg_houtput = 0;
 
-- 
2.7.4




More information about the wine-devel mailing list