[PATCH 12/15] winedbg: Fix register read/write handlers.

Rémi Bernon rbernon at codeweavers.com
Mon Jan 27 06:07:15 CST 2020


This was using some conditional context read and dbg_curr_thread checks,
which seems overcomplicated. Just read the context of the selected
thread and write it back as needed.

Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
 programs/winedbg/gdbproxy.c | 96 ++++++++++++++++++-------------------
 1 file changed, 47 insertions(+), 49 deletions(-)

diff --git a/programs/winedbg/gdbproxy.c b/programs/winedbg/gdbproxy.c
index 160c2df0d20..d0e0cfb3428 100644
--- a/programs/winedbg/gdbproxy.c
+++ b/programs/winedbg/gdbproxy.c
@@ -501,6 +501,7 @@ static	void	handle_debug_event(struct gdb_context* gdbctx, DEBUG_EVENT* de)
         WCHAR               buffer[256];
     } u;
 
+    gdbctx->other_thread = NULL;
     dbg_curr_thread = dbg_get_thread(gdbctx->process, de->dwThreadId);
 
     switch (de->dwDebugEventCode)
@@ -941,16 +942,16 @@ static enum packet_return packet_reply_error(struct gdb_context* gdbctx, int err
     return packet_done;
 }
 
-static inline void packet_reply_register_hex_to(struct gdb_context* gdbctx, unsigned idx)
+static inline void packet_reply_register_hex_to(struct gdb_context* gdbctx, dbg_ctx_t* ctx, unsigned idx)
 {
     const struct gdb_register *cpu_register_map = gdbctx->process->be_cpu->gdb_register_map;
 
     if (cpu_register_map[idx].gdb_length == cpu_register_map[idx].ctx_length)
-        packet_reply_hex_to(gdbctx, cpu_register_ptr(gdbctx, &gdbctx->context, idx),
+        packet_reply_hex_to(gdbctx, cpu_register_ptr(gdbctx, ctx, idx),
                             cpu_register_map[idx].gdb_length);
     else
     {
-        DWORD64     val = cpu_register(gdbctx, &gdbctx->context, idx);
+        DWORD64     val = cpu_register(gdbctx, ctx, idx);
         unsigned    i;
 
         for (i = 0; i < cpu_register_map[idx].gdb_length; i++)
@@ -969,11 +970,18 @@ static inline void packet_reply_register_hex_to(struct gdb_context* gdbctx, unsi
 
 static enum packet_return packet_reply_status(struct gdb_context* gdbctx)
 {
-    if (gdbctx->process != NULL)
+    struct dbg_process *proc = gdbctx->process;
+    dbg_ctx_t ctx;
+
+    if (proc != NULL)
     {
+        struct backend_cpu *be = proc->be_cpu;
         unsigned char           sig;
         unsigned                i;
 
+        if (!be->get_context(dbg_curr_thread->handle, &ctx))
+            return packet_error;
+
         packet_reply_open(gdbctx);
         packet_reply_add(gdbctx, "T");
         sig = gdbctx->last_sig;
@@ -982,14 +990,11 @@ static enum packet_return packet_reply_status(struct gdb_context* gdbctx)
         packet_reply_val(gdbctx, dbg_curr_thread->tid, 4);
         packet_reply_add(gdbctx, ";");
 
-        for (i = 0; i < gdbctx->process->be_cpu->gdb_num_regs; i++)
+        for (i = 0; i < be->gdb_num_regs; i++)
         {
-            /* FIXME: this call will also grow the buffer...
-             * unneeded, but not harmful
-             */
             packet_reply_val(gdbctx, i, 1);
             packet_reply_add(gdbctx, ":");
-            packet_reply_register_hex_to(gdbctx, i);
+            packet_reply_register_hex_to(gdbctx, &ctx, i);
             packet_reply_add(gdbctx, ";");
         }
 
@@ -1251,20 +1256,18 @@ static enum packet_return packet_detach(struct gdb_context* gdbctx)
 
 static enum packet_return packet_read_registers(struct gdb_context* gdbctx)
 {
+    struct dbg_thread *thrd = gdbctx->other_thread ? gdbctx->other_thread : dbg_curr_thread;
+    struct backend_cpu *be = thrd->process->be_cpu;
     int                 i;
     dbg_ctx_t ctx;
 
     assert(gdbctx->in_trap);
-
-    if (dbg_curr_thread != gdbctx->other_thread && gdbctx->other_thread)
-    {
-        if (!fetch_context(gdbctx, gdbctx->other_thread->handle, &ctx))
-            return packet_error;
-    }
+    if (!thrd || !be->get_context(thrd->handle, &ctx))
+        return packet_error;
 
     packet_reply_open(gdbctx);
-    for (i = 0; i < gdbctx->process->be_cpu->gdb_num_regs; i++)
-        packet_reply_register_hex_to(gdbctx, i);
+    for (i = 0; i < be->gdb_num_regs; i++)
+        packet_reply_register_hex_to(gdbctx, &ctx, i);
 
     packet_reply_close(gdbctx);
     return packet_done;
@@ -1272,31 +1275,30 @@ static enum packet_return packet_read_registers(struct gdb_context* gdbctx)
 
 static enum packet_return packet_write_registers(struct gdb_context* gdbctx)
 {
-    const size_t cpu_num_regs = gdbctx->process->be_cpu->gdb_num_regs;
+    struct dbg_thread *thrd = gdbctx->other_thread ? gdbctx->other_thread : dbg_curr_thread;
+    struct backend_cpu *be = thrd->process->be_cpu;
+    const size_t cpu_num_regs = be->gdb_num_regs;
     unsigned    i;
     dbg_ctx_t ctx;
-    dbg_ctx_t *pctx = &gdbctx->context;
     const char* ptr;
 
     assert(gdbctx->in_trap);
-    if (dbg_curr_thread != gdbctx->other_thread && gdbctx->other_thread)
-    {
-        if (!fetch_context(gdbctx, gdbctx->other_thread->handle, pctx = &ctx))
-            return packet_error;
-    }
-    if (gdbctx->in_packet_len < cpu_num_regs * 2) return packet_error;
+    if (!thrd || !be->get_context(thrd->handle, &ctx))
+        return packet_error;
+    if (gdbctx->in_packet_len < cpu_num_regs * 2)
+        return packet_error;
 
     ptr = gdbctx->in_packet;
     for (i = 0; i < cpu_num_regs; i++)
-        cpu_register_hex_from(gdbctx, pctx, i, &ptr);
+        cpu_register_hex_from(gdbctx, &ctx, i, &ptr);
 
-    if (pctx != &gdbctx->context &&
-        !gdbctx->process->be_cpu->set_context(gdbctx->other_thread->handle, pctx))
+    if (!be->set_context(thrd->handle, &ctx))
     {
         ERR("Failed to set context for tid %04x, error %u\n",
-            gdbctx->other_thread->tid, GetLastError());
+            thrd->tid, GetLastError());
         return packet_error;
     }
+
     return packet_ok;
 }
 
@@ -1414,42 +1416,42 @@ static enum packet_return packet_write_memory(struct gdb_context* gdbctx)
 
 static enum packet_return packet_read_register(struct gdb_context* gdbctx)
 {
+    struct dbg_thread *thrd = gdbctx->other_thread ? gdbctx->other_thread : dbg_curr_thread;
+    struct backend_cpu *be = thrd->process->be_cpu;
     unsigned            reg;
     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);
-    if (reg >= gdbctx->process->be_cpu->gdb_num_regs)
+    if (reg >= be->gdb_num_regs)
     {
         WARN("Unhandled register %u\n", reg);
         return packet_error;
     }
-    if (dbg_curr_thread != gdbctx->other_thread && gdbctx->other_thread)
-    {
-        if (!fetch_context(gdbctx, gdbctx->other_thread->handle, pctx = &ctx))
-            return packet_error;
-    }
 
-    TRACE("%u => %s\n", reg, wine_dbgstr_longlong(cpu_register(gdbctx, pctx, reg)));
+    if (!thrd || !be->get_context(thrd->handle, &ctx))
+        return packet_error;
+
+    TRACE("%u => %s\n", reg, wine_dbgstr_longlong(cpu_register(gdbctx, &ctx, reg)));
 
     packet_reply_open(gdbctx);
-    packet_reply_register_hex_to(gdbctx, reg);
+    packet_reply_register_hex_to(gdbctx, &ctx, reg);
     packet_reply_close(gdbctx);
     return packet_done;
 }
 
 static enum packet_return packet_write_register(struct gdb_context* gdbctx)
 {
+    struct dbg_thread *thrd = gdbctx->other_thread ? gdbctx->other_thread : dbg_curr_thread;
+    struct backend_cpu *be = thrd->process->be_cpu;
     unsigned            reg;
     char*               ptr;
     dbg_ctx_t ctx;
-    dbg_ctx_t *pctx = &gdbctx->context;
 
     assert(gdbctx->in_trap);
 
     reg = strtoul(gdbctx->in_packet, &ptr, 16);
-    if (ptr == NULL || reg >= gdbctx->process->be_cpu->gdb_num_regs || *ptr++ != '=')
+    if (ptr == NULL || reg >= be->gdb_num_regs || *ptr++ != '=')
     {
         WARN("Unhandled register %s\n",
             debugstr_an(gdbctx->in_packet, gdbctx->in_packet_len));
@@ -1462,18 +1464,14 @@ static enum packet_return packet_write_register(struct gdb_context* gdbctx)
     TRACE("%u <= %s\n", reg,
         debugstr_an(ptr, (int)(gdbctx->in_packet_len - (ptr - gdbctx->in_packet))));
 
-    if (dbg_curr_thread != gdbctx->other_thread && gdbctx->other_thread)
-    {
-        if (!fetch_context(gdbctx, gdbctx->other_thread->handle, pctx = &ctx))
-            return packet_error;
-    }
+    if (!thrd || !be->get_context(thrd->handle, &ctx))
+        return packet_error;
 
-    cpu_register_hex_from(gdbctx, pctx, reg, (const char**)&ptr);
-    if (pctx != &gdbctx->context &&
-        !gdbctx->process->be_cpu->set_context(gdbctx->other_thread->handle, pctx))
+    cpu_register_hex_from(gdbctx, &ctx, reg, (const char**)&ptr);
+    if (!be->set_context(thrd->handle, &ctx))
     {
         ERR("Failed to set context for tid %04x, error %u\n",
-            gdbctx->other_thread->tid, GetLastError());
+            thrd->tid, GetLastError());
         return packet_error;
     }
 
-- 
2.25.0




More information about the wine-devel mailing list