[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