[review] Add read_pc / write_pc support to win32-low
Commit Message
Change URL: https://gnutoolchain-gerrit.osci.io/r/c/binutils-gdb/+/430
......................................................................
Add read_pc / write_pc support to win32-low
This changes win32-low.c to implement the read_pc and write_pc
methods. A subsequent patch will need these.
Note that I have no way to test, or even compile, the win32-arm-low.c
change.
Change-Id: I83552edd4ec61204a7e56f1adbd5a9c941bb52e5
gdb/gdbserver/ChangeLog
2019-10-29 Tom Tromey <tromey@adacore.com>
* win32-low.c (win32_read_pc, win32_write_pc): New functions.
(win32_target_ops): Update.
* win32-i386-low.c (i386_win32_get_pc, i386_win32_set_pc): New
functions.
(the_low_target): Update.
* win32-arm-low.c (arm_win32_get_pc, arm_win32_set_pc): New
functions.
(the_low_target): Update.
Change-Id: I4dcb72f262b778c2db554f6ff9b675a35f14318b
---
M gdb/gdbserver/ChangeLog
M gdb/gdbserver/win32-arm-low.c
M gdb/gdbserver/win32-i386-low.c
M gdb/gdbserver/win32-low.c
M gdb/gdbserver/win32-low.h
5 files changed, 95 insertions(+), 2 deletions(-)
Comments
Pedro Alves has posted comments on this change.
Change URL: https://gnutoolchain-gerrit.osci.io/r/c/binutils-gdb/+/430
......................................................................
Patch Set 1: Code-Review+2
(4 comments)
LGTM. Minor nits below.
| --- gdb/gdbserver/win32-i386-low.c
| +++ gdb/gdbserver/win32-i386-low.c
| @@ -443,8 +443,42 @@ #else
| const char **expedite_regs = i386_expedite_regs;
| #endif
|
| init_target_desc (tdesc, expedite_regs);
|
| win32_tdesc = tdesc;
| }
|
| +static CORE_ADDR
| +i386_win32_get_pc (struct regcache *regcache)
PS1, Line 452:
Missing typical intro comment.
| +{
| + int use_64bit = register_size (regcache->tdesc, 0) == 8;
PS1, Line 454:
bool
| +
| + if (use_64bit)
| + {
| + uint64_t pc;
| +
| + collect_register_by_name (regcache, "rip", &pc);
| + return (CORE_ADDR) pc;
| + }
| + else
| + {
| + uint32_t pc;
| +
| + collect_register_by_name (regcache, "eip", &pc);
| + return (CORE_ADDR) pc;
| + }
| +}
| +
| +static void
| +i386_win32_set_pc (struct regcache *regcache, CORE_ADDR pc)
PS1, Line 473:
Ditto.
| +{
| + int use_64bit = register_size (regcache->tdesc, 0) == 8;
PS1, Line 475:
bool
| +
| + if (use_64bit)
| + {
| + uint64_t newpc = pc;
| +
| + supply_register_by_name (regcache, "rip", &newpc);
| + }
| + else
| + {
@@ -1,5 +1,16 @@
2019-10-29 Tom Tromey <tromey@adacore.com>
+ * win32-low.c (win32_read_pc, win32_write_pc): New functions.
+ (win32_target_ops): Update.
+ * win32-i386-low.c (i386_win32_get_pc, i386_win32_set_pc): New
+ functions.
+ (the_low_target): Update.
+ * win32-arm-low.c (arm_win32_get_pc, arm_win32_set_pc): New
+ functions.
+ (the_low_target): Update.
+
+2019-10-29 Tom Tromey <tromey@adacore.com>
+
* win32-low.c (win32_kill, get_child_debug_event): Use
wait_for_debug_event.
@@ -113,6 +113,23 @@
static const unsigned long arm_wince_breakpoint = 0xe6000010;
#define arm_wince_breakpoint_len 4
+static CORE_ADDR
+arm_win32_get_pc (struct regcache *regcache)
+{
+ uint32_t pc;
+
+ collect_register_by_name (regcache, "pc", &pc);
+ return (CORE_ADDR) pc;
+}
+
+static void
+arm_win32_set_pc (struct regcache *regcache, CORE_ADDR pc)
+{
+ uint32_t newpc = pc;
+
+ supply_register_by_name (regcache, "pc", &newpc);
+}
+
struct win32_target_ops the_low_target = {
arm_arch_setup,
sizeof (mappings) / sizeof (mappings[0]),
@@ -125,6 +142,8 @@
NULL, /* single_step */
(const unsigned char *) &arm_wince_breakpoint,
arm_wince_breakpoint_len,
+ arm_win32_get_pc,
+ arm_win32_set_pc,
/* Watchpoint related functions. See target.h for comments. */
NULL, /* supports_z_point_type */
NULL, /* insert_point */
@@ -448,6 +448,46 @@
win32_tdesc = tdesc;
}
+static CORE_ADDR
+i386_win32_get_pc (struct regcache *regcache)
+{
+ int use_64bit = register_size (regcache->tdesc, 0) == 8;
+
+ if (use_64bit)
+ {
+ uint64_t pc;
+
+ collect_register_by_name (regcache, "rip", &pc);
+ return (CORE_ADDR) pc;
+ }
+ else
+ {
+ uint32_t pc;
+
+ collect_register_by_name (regcache, "eip", &pc);
+ return (CORE_ADDR) pc;
+ }
+}
+
+static void
+i386_win32_set_pc (struct regcache *regcache, CORE_ADDR pc)
+{
+ int use_64bit = register_size (regcache->tdesc, 0) == 8;
+
+ if (use_64bit)
+ {
+ uint64_t newpc = pc;
+
+ supply_register_by_name (regcache, "rip", &newpc);
+ }
+ else
+ {
+ uint32_t newpc = pc;
+
+ supply_register_by_name (regcache, "eip", &newpc);
+ }
+}
+
struct win32_target_ops the_low_target = {
i386_arch_setup,
sizeof (mappings) / sizeof (mappings[0]),
@@ -460,6 +500,8 @@
i386_single_step,
&i386_win32_breakpoint,
i386_win32_breakpoint_len,
+ i386_win32_get_pc,
+ i386_win32_set_pc,
i386_supports_z_point_type,
i386_insert_point,
i386_remove_point,
@@ -1585,6 +1585,22 @@
return the_low_target.breakpoint;
}
+/* Implementation of the target_ops method "read_pc". */
+
+static CORE_ADDR
+win32_read_pc (struct regcache *regcache)
+{
+ return (*the_low_target.get_pc) (regcache);
+}
+
+/* Implementation of the target_ops method "write_pc". */
+
+static void
+win32_write_pc (struct regcache *regcache, CORE_ADDR pc)
+{
+ return (*the_low_target.set_pc) (regcache, pc);
+}
+
static struct target_ops win32_target_ops = {
win32_create_inferior,
NULL, /* post_create_inferior */
@@ -1637,8 +1653,8 @@
NULL, /* read_loadmap */
NULL, /* process_qsupported */
NULL, /* supports_tracepoints */
- NULL, /* read_pc */
- NULL, /* write_pc */
+ win32_read_pc,
+ win32_write_pc,
NULL, /* thread_stopped */
win32_get_tib_address,
NULL, /* pause_all */
@@ -63,6 +63,11 @@
const unsigned char *breakpoint;
int breakpoint_len;
+ /* Get the PC register from REGCACHE. */
+ CORE_ADDR (*get_pc) (struct regcache *regcache);
+ /* Set the PC register in REGCACHE. */
+ void (*set_pc) (struct regcache *regcache, CORE_ADDR newpc);
+
/* Breakpoint/Watchpoint related functions. See target.h for comments. */
int (*supports_z_point_type) (char z_type);
int (*insert_point) (enum raw_bkpt_type type, CORE_ADDR addr,