mirror of
git://source.winehq.org/git/wine.git
synced 2024-09-01 03:33:38 +00:00
winedbg: Use gdb's default handling of breakpoints.
We're essentially doing the same thing, so there's no reason not to leave the handling entirely to gdb. Signed-off-by: Zebediah Figura <z.figura12@gmail.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
ca313f57b1
commit
a602405efd
|
@ -72,13 +72,6 @@
|
||||||
#define GDBPXY_TRC_WIN32_ERROR 0x20
|
#define GDBPXY_TRC_WIN32_ERROR 0x20
|
||||||
#define GDBPXY_TRC_COMMAND_FIXME 0x80
|
#define GDBPXY_TRC_COMMAND_FIXME 0x80
|
||||||
|
|
||||||
struct gdb_ctx_Xpoint
|
|
||||||
{
|
|
||||||
enum be_xpoint_type type; /* (-1) == be_xpoint_free means free */
|
|
||||||
void* addr;
|
|
||||||
unsigned long val;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct gdb_context
|
struct gdb_context
|
||||||
{
|
{
|
||||||
/* gdb information */
|
/* gdb information */
|
||||||
|
@ -105,8 +98,6 @@ struct gdb_context
|
||||||
CONTEXT context;
|
CONTEXT context;
|
||||||
/* Win32 information */
|
/* Win32 information */
|
||||||
struct dbg_process* process;
|
struct dbg_process* process;
|
||||||
#define NUM_XPOINT 32
|
|
||||||
struct gdb_ctx_Xpoint Xpoints[NUM_XPOINT];
|
|
||||||
/* Unix environment */
|
/* Unix environment */
|
||||||
unsigned long wine_segs[3]; /* load addresses of the ELF wine exec segments (text, bss and data) */
|
unsigned long wine_segs[3]; /* load addresses of the ELF wine exec segments (text, bss and data) */
|
||||||
};
|
};
|
||||||
|
@ -1570,28 +1561,6 @@ static enum packet_return packet_thread(struct gdb_context* gdbctx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL read_memory(struct gdb_context *gdbctx, char *addr, char *buffer, SIZE_T blk_len, SIZE_T *r)
|
|
||||||
{
|
|
||||||
/* Wrapper around process_io->read() that replaces values displaced by breakpoints. */
|
|
||||||
|
|
||||||
BOOL ret;
|
|
||||||
|
|
||||||
ret = gdbctx->process->process_io->read(gdbctx->process->handle, addr, buffer, blk_len, r);
|
|
||||||
if (ret)
|
|
||||||
{
|
|
||||||
struct gdb_ctx_Xpoint *xpt;
|
|
||||||
|
|
||||||
for (xpt = &gdbctx->Xpoints[NUM_XPOINT - 1]; xpt >= gdbctx->Xpoints; xpt--)
|
|
||||||
{
|
|
||||||
char *xpt_addr = xpt->addr;
|
|
||||||
|
|
||||||
if (xpt->type != be_xpoint_free && xpt_addr >= addr && xpt_addr < addr + blk_len)
|
|
||||||
buffer[xpt_addr - addr] = xpt->val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static enum packet_return packet_read_memory(struct gdb_context* gdbctx)
|
static enum packet_return packet_read_memory(struct gdb_context* gdbctx)
|
||||||
{
|
{
|
||||||
char *addr;
|
char *addr;
|
||||||
|
@ -1608,7 +1577,8 @@ static enum packet_return packet_read_memory(struct gdb_context* gdbctx)
|
||||||
for (nread = 0; nread < len; nread += r, addr += r)
|
for (nread = 0; nread < len; nread += r, addr += r)
|
||||||
{
|
{
|
||||||
blk_len = min(sizeof(buffer), len - nread);
|
blk_len = min(sizeof(buffer), len - nread);
|
||||||
if (!read_memory(gdbctx, addr, buffer, blk_len, &r) || r == 0)
|
if (!gdbctx->process->process_io->read(gdbctx->process->handle, addr,
|
||||||
|
buffer, blk_len, &r) || r == 0)
|
||||||
{
|
{
|
||||||
/* fail at first address, return error */
|
/* fail at first address, return error */
|
||||||
if (nread == 0) return packet_reply_error(gdbctx, EFAULT);
|
if (nread == 0) return packet_reply_error(gdbctx, EFAULT);
|
||||||
|
@ -2163,97 +2133,6 @@ static enum packet_return packet_thread_alive(struct gdb_context* gdbctx)
|
||||||
return packet_reply_error(gdbctx, ESRCH);
|
return packet_reply_error(gdbctx, ESRCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum packet_return packet_remove_breakpoint(struct gdb_context* gdbctx)
|
|
||||||
{
|
|
||||||
void* addr;
|
|
||||||
unsigned len;
|
|
||||||
struct gdb_ctx_Xpoint* xpt;
|
|
||||||
enum be_xpoint_type t;
|
|
||||||
|
|
||||||
/* FIXME: check packet_len */
|
|
||||||
if (gdbctx->in_packet[0] < '0' || gdbctx->in_packet[0] > '4' ||
|
|
||||||
gdbctx->in_packet[1] != ',' ||
|
|
||||||
sscanf(gdbctx->in_packet + 2, "%p,%x", &addr, &len) != 2)
|
|
||||||
return packet_error;
|
|
||||||
if (gdbctx->trace & GDBPXY_TRC_COMMAND)
|
|
||||||
fprintf(stderr, "Remove bp %p[%u] typ=%c\n",
|
|
||||||
addr, len, gdbctx->in_packet[0]);
|
|
||||||
switch (gdbctx->in_packet[0])
|
|
||||||
{
|
|
||||||
case '0': t = be_xpoint_break; len = 0; break;
|
|
||||||
case '1': t = be_xpoint_watch_exec; break;
|
|
||||||
case '2': t = be_xpoint_watch_read; break;
|
|
||||||
case '3': t = be_xpoint_watch_write; break;
|
|
||||||
default: return packet_error;
|
|
||||||
}
|
|
||||||
for (xpt = &gdbctx->Xpoints[NUM_XPOINT - 1]; xpt >= gdbctx->Xpoints; xpt--)
|
|
||||||
{
|
|
||||||
if (xpt->addr == addr && xpt->type == t)
|
|
||||||
{
|
|
||||||
if (be_cpu->remove_Xpoint(gdbctx->process->handle,
|
|
||||||
gdbctx->process->process_io, &gdbctx->context,
|
|
||||||
t, xpt->addr, xpt->val, len))
|
|
||||||
{
|
|
||||||
xpt->type = be_xpoint_free;
|
|
||||||
return packet_ok;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return packet_error;
|
|
||||||
}
|
|
||||||
|
|
||||||
static enum packet_return packet_set_breakpoint(struct gdb_context* gdbctx)
|
|
||||||
{
|
|
||||||
void* addr;
|
|
||||||
unsigned len;
|
|
||||||
struct gdb_ctx_Xpoint* xpt;
|
|
||||||
enum be_xpoint_type t;
|
|
||||||
|
|
||||||
/* FIXME: check packet_len */
|
|
||||||
if (gdbctx->in_packet[0] < '0' || gdbctx->in_packet[0] > '4' ||
|
|
||||||
gdbctx->in_packet[1] != ',' ||
|
|
||||||
sscanf(gdbctx->in_packet + 2, "%p,%x", &addr, &len) != 2)
|
|
||||||
return packet_error;
|
|
||||||
if (gdbctx->trace & GDBPXY_TRC_COMMAND)
|
|
||||||
fprintf(stderr, "Set bp %p[%u] typ=%c\n",
|
|
||||||
addr, len, gdbctx->in_packet[0]);
|
|
||||||
switch (gdbctx->in_packet[0])
|
|
||||||
{
|
|
||||||
case '0': t = be_xpoint_break; len = 0; break;
|
|
||||||
case '1': t = be_xpoint_watch_exec; break;
|
|
||||||
case '2': t = be_xpoint_watch_read; break;
|
|
||||||
case '3': t = be_xpoint_watch_write; break;
|
|
||||||
default: return packet_error;
|
|
||||||
}
|
|
||||||
/* because of packet command handling, this should be made idempotent */
|
|
||||||
for (xpt = &gdbctx->Xpoints[NUM_XPOINT - 1]; xpt >= gdbctx->Xpoints; xpt--)
|
|
||||||
{
|
|
||||||
if (xpt->addr == addr && xpt->type == t)
|
|
||||||
return packet_ok; /* nothing to do */
|
|
||||||
}
|
|
||||||
/* really set the Xpoint */
|
|
||||||
for (xpt = &gdbctx->Xpoints[NUM_XPOINT - 1]; xpt >= gdbctx->Xpoints; xpt--)
|
|
||||||
{
|
|
||||||
if (xpt->type == be_xpoint_free)
|
|
||||||
{
|
|
||||||
if (be_cpu->insert_Xpoint(gdbctx->process->handle,
|
|
||||||
gdbctx->process->process_io, &gdbctx->context,
|
|
||||||
t, addr, &xpt->val, len))
|
|
||||||
{
|
|
||||||
xpt->addr = addr;
|
|
||||||
xpt->type = t;
|
|
||||||
return packet_ok;
|
|
||||||
}
|
|
||||||
fprintf(stderr, "cannot set xpoint\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* no more entries... eech */
|
|
||||||
fprintf(stderr, "Running out of spots for {break|watch}points\n");
|
|
||||||
return packet_error;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* =============================================== *
|
/* =============================================== *
|
||||||
* P A C K E T I N F R A S T R U C T U R E *
|
* P A C K E T I N F R A S T R U C T U R E *
|
||||||
* =============================================== *
|
* =============================================== *
|
||||||
|
@ -2287,8 +2166,6 @@ static struct packet_entry packet_entries[] =
|
||||||
/*{'S', packet_step_signal}, hard(er) to implement */
|
/*{'S', packet_step_signal}, hard(er) to implement */
|
||||||
{'T', packet_thread_alive},
|
{'T', packet_thread_alive},
|
||||||
{'v', packet_verbose},
|
{'v', packet_verbose},
|
||||||
{'z', packet_remove_breakpoint},
|
|
||||||
{'Z', packet_set_breakpoint},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static BOOL extract_packets(struct gdb_context* gdbctx)
|
static BOOL extract_packets(struct gdb_context* gdbctx)
|
||||||
|
@ -2578,8 +2455,6 @@ static BOOL gdb_init_context(struct gdb_context* gdbctx, unsigned flags, unsigne
|
||||||
gdbctx->in_trap = FALSE;
|
gdbctx->in_trap = FALSE;
|
||||||
gdbctx->trace = /*GDBPXY_TRC_PACKET | GDBPXY_TRC_COMMAND |*/ GDBPXY_TRC_COMMAND_ERROR | GDBPXY_TRC_COMMAND_FIXME | GDBPXY_TRC_WIN32_EVENT;
|
gdbctx->trace = /*GDBPXY_TRC_PACKET | GDBPXY_TRC_COMMAND |*/ GDBPXY_TRC_COMMAND_ERROR | GDBPXY_TRC_COMMAND_FIXME | GDBPXY_TRC_WIN32_EVENT;
|
||||||
gdbctx->process = NULL;
|
gdbctx->process = NULL;
|
||||||
for (i = 0; i < NUM_XPOINT; i++)
|
|
||||||
gdbctx->Xpoints[i].type = -1;
|
|
||||||
for (i = 0; i < sizeof(gdbctx->wine_segs) / sizeof(gdbctx->wine_segs[0]); i++)
|
for (i = 0; i < sizeof(gdbctx->wine_segs) / sizeof(gdbctx->wine_segs[0]); i++)
|
||||||
gdbctx->wine_segs[i] = 0;
|
gdbctx->wine_segs[i] = 0;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue