[PATCH 1/3] programs/winedbg: correctly read register values

Eric Pouech eric.pouech at gmail.com
Thu Feb 17 07:04:15 CST 2022


(was incorrectly reading all registers as debugger's DWORD_PTR)

this is mainly needed:
- for a 64bit debugger attached to a 32bit debuggee
- when register is of different size than machine word

(regressions introduced in wine-7.0-rc1)

Signed-off-by: Eric Pouech <eric.pouech at gmail.com>

---
 programs/winedbg/debugger.h |    4 ++--
 programs/winedbg/memory.c   |    4 ++--
 programs/winedbg/stack.c    |   11 ++++++-----
 programs/winedbg/symbol.c   |   10 +++-------
 4 files changed, 13 insertions(+), 16 deletions(-)

diff --git a/programs/winedbg/debugger.h b/programs/winedbg/debugger.h
index 0cc2f8b7a6c..2ea1dc5a25f 100644
--- a/programs/winedbg/debugger.h
+++ b/programs/winedbg/debugger.h
@@ -404,7 +404,7 @@ extern BOOL             memory_get_current_pc(ADDRESS64* address);
 extern BOOL             memory_get_current_stack(ADDRESS64* address);
 extern BOOL             memory_get_string(struct dbg_process* pcs, void* addr, BOOL in_debuggee, BOOL unicode, char* buffer, int size);
 extern BOOL             memory_get_string_indirect(struct dbg_process* pcs, void* addr, BOOL unicode, WCHAR* buffer, int size);
-extern BOOL             memory_get_register(DWORD regno, DWORD_PTR** value, char* buffer, int len);
+extern BOOL             memory_get_register(DWORD regno, struct dbg_lvalue* value, char* buffer, int len);
 extern void             memory_disassemble(const struct dbg_lvalue*, const struct dbg_lvalue*, int instruction_count);
 extern BOOL             memory_disasm_one_insn(ADDRESS64* addr);
 #define MAX_OFFSET_TO_STR_LEN 19
@@ -425,7 +425,7 @@ extern void             source_free_files(struct dbg_process* p);
 extern void             stack_info(int len);
 extern void             stack_backtrace(DWORD threadID);
 extern BOOL             stack_set_frame(int newframe);
-extern BOOL             stack_get_register_frame(const struct dbg_internal_var* div, DWORD_PTR** pval);
+extern BOOL             stack_get_register_frame(const struct dbg_internal_var* div, struct dbg_lvalue* lvalue);
 extern unsigned         stack_fetch_frames(const dbg_ctx_t *ctx);
 extern BOOL             stack_get_current_symbol(SYMBOL_INFO* sym);
 static inline struct dbg_frame*
diff --git a/programs/winedbg/memory.c b/programs/winedbg/memory.c
index faa5ac9ddcb..d0698bff5a9 100644
--- a/programs/winedbg/memory.c
+++ b/programs/winedbg/memory.c
@@ -788,7 +788,7 @@ void memory_disassemble(const struct dbg_lvalue* xstart,
         memory_disasm_one_insn(&last);
 }
 
-BOOL memory_get_register(DWORD regno, DWORD_PTR** value, char* buffer, int len)
+BOOL memory_get_register(DWORD regno, struct dbg_lvalue* lvalue, char* buffer, int len)
 {
     const struct dbg_internal_var*  div;
 
@@ -818,7 +818,7 @@ BOOL memory_get_register(DWORD regno, DWORD_PTR** value, char* buffer, int len)
     {
         if (div->val == regno)
         {
-            if (!stack_get_register_frame(div, value))
+            if (!stack_get_register_frame(div, lvalue))
             {
                 if (buffer) snprintf(buffer, len, "<register %s not accessible in this frame>", div->name);
                 return FALSE;
diff --git a/programs/winedbg/stack.c b/programs/winedbg/stack.c
index 5d3504f1057..f395fd3d480 100644
--- a/programs/winedbg/stack.c
+++ b/programs/winedbg/stack.c
@@ -98,12 +98,13 @@ static BOOL stack_set_frame_internal(int newframe)
     return TRUE;
 }
 
-BOOL stack_get_register_frame(const struct dbg_internal_var* div, DWORD_PTR** pval)
+BOOL stack_get_register_frame(const struct dbg_internal_var* div, struct dbg_lvalue* lvalue)
 {
     struct dbg_frame* currfrm = stack_get_curr_frame();
     if (currfrm == NULL) return FALSE;
     if (currfrm->is_ctx_valid)
-        *pval = (DWORD_PTR*)((char*)&currfrm->context + (DWORD_PTR)div->pval);
+        init_lvalue_in_debugger(lvalue, div->typeid,
+                                (char*)&currfrm->context + (DWORD_PTR)div->pval);
     else
     {
         enum be_cpu_addr        kind;
@@ -114,13 +115,13 @@ BOOL stack_get_register_frame(const struct dbg_internal_var* div, DWORD_PTR** pv
         switch (kind)
         {
         case be_cpu_addr_pc:
-            *pval = &currfrm->linear_pc;
+            init_lvalue_in_debugger(lvalue, dbg_itype_unsigned_long_int, &currfrm->linear_pc);
             break;
         case be_cpu_addr_stack:
-            *pval = &currfrm->linear_stack;
+            init_lvalue_in_debugger(lvalue, dbg_itype_unsigned_long_int, &currfrm->linear_stack);
             break;
         case be_cpu_addr_frame:
-            *pval = &currfrm->linear_frame;
+            init_lvalue_in_debugger(lvalue, dbg_itype_unsigned_long_int, &currfrm->linear_frame);
             break;
         }
     }
diff --git a/programs/winedbg/symbol.c b/programs/winedbg/symbol.c
index 9cbfc8b77de..4c4486ce5d8 100644
--- a/programs/winedbg/symbol.c
+++ b/programs/winedbg/symbol.c
@@ -67,24 +67,20 @@ static BOOL fill_sym_lvalue(const SYMBOL_INFO* sym, ULONG_PTR base,
     if (buffer) buffer[0] = '\0';
     if (sym->Flags & SYMFLAG_REGISTER)
     {
-        DWORD_PTR* pval;
-
-        if (!memory_get_register(sym->Register, &pval, buffer, sz))
+        if (!memory_get_register(sym->Register, lvalue, buffer, sz))
             return FALSE;
-        init_lvalue(lvalue, FALSE, pval);
     }
     else if (sym->Flags & SYMFLAG_REGREL)
     {
-        DWORD_PTR* pval;
         size_t  l;
 
         *buffer++ = '['; sz--;
-        if (!memory_get_register(sym->Register, &pval, buffer, sz))
+        if (!memory_get_register(sym->Register, lvalue, buffer, sz))
             return FALSE;
         l = strlen(buffer);
         sz -= l;
         buffer += l;
-        init_lvalue(lvalue, TRUE, (void*)(DWORD_PTR)(*pval + sym->Address));
+        init_lvalue(lvalue, TRUE, (void*)(DWORD_PTR)(types_extract_as_integer(lvalue) + sym->Address));
         if ((LONG64)sym->Address >= 0)
             snprintf(buffer, sz, "+%I64d]", sym->Address);
         else




More information about the wine-devel mailing list