From d6225aff7a4f11c3443515c0d8dad12351b97575 Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Wed, 8 Apr 2020 14:33:35 -0600 Subject: [PATCH] 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. gdbserver/ChangeLog 2020-04-08 Tom Tromey * win32-low.h (win32_process_target::read_pc) (win32_process_target::write_pc): Declare. * win32-low.c (win32_process_target::read_pc) (win32_process_target::write_pc): New methods. * 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. --- gdbserver/ChangeLog | 13 +++++++++++ gdbserver/win32-arm-low.cc | 23 +++++++++++++++++++ gdbserver/win32-i386-low.cc | 46 +++++++++++++++++++++++++++++++++++++ gdbserver/win32-low.cc | 12 ++++++++++ gdbserver/win32-low.h | 9 ++++++++ 5 files changed, 103 insertions(+) diff --git a/gdbserver/ChangeLog b/gdbserver/ChangeLog index 792834077fe..ee66a4b6d99 100644 --- a/gdbserver/ChangeLog +++ b/gdbserver/ChangeLog @@ -1,3 +1,16 @@ +2020-04-08 Tom Tromey + + * win32-low.h (win32_process_target::read_pc) + (win32_process_target::write_pc): Declare. + * win32-low.c (win32_process_target::read_pc) + (win32_process_target::write_pc): New methods. + * 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. + 2020-04-08 Tom Tromey * win32-low.c (win32_kill, get_child_debug_event): Use diff --git a/gdbserver/win32-arm-low.cc b/gdbserver/win32-arm-low.cc index 78b7fd09ec3..77200112df1 100644 --- a/gdbserver/win32-arm-low.cc +++ b/gdbserver/win32-arm-low.cc @@ -115,6 +115,27 @@ arm_arch_setup (void) static const unsigned long arm_wince_breakpoint = 0xe6000010; #define arm_wince_breakpoint_len 4 +/* Implement win32_target_ops "get_pc" method. */ + +static CORE_ADDR +arm_win32_get_pc (struct regcache *regcache) +{ + uint32_t pc; + + collect_register_by_name (regcache, "pc", &pc); + return (CORE_ADDR) pc; +} + +/* Implement win32_target_ops "set_pc" method. */ + +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]), @@ -127,6 +148,8 @@ struct win32_target_ops the_low_target = { 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 */ diff --git a/gdbserver/win32-i386-low.cc b/gdbserver/win32-i386-low.cc index 1c14bc70362..eac15b5694a 100644 --- a/gdbserver/win32-i386-low.cc +++ b/gdbserver/win32-i386-low.cc @@ -450,6 +450,50 @@ i386_arch_setup (void) win32_tdesc = tdesc; } +/* Implement win32_target_ops "get_pc" method. */ + +static CORE_ADDR +i386_win32_get_pc (struct regcache *regcache) +{ + bool 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; + } +} + +/* Implement win32_target_ops "set_pc" method. */ + +static void +i386_win32_set_pc (struct regcache *regcache, CORE_ADDR pc) +{ + bool 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]), @@ -462,6 +506,8 @@ struct win32_target_ops the_low_target = { 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, diff --git a/gdbserver/win32-low.cc b/gdbserver/win32-low.cc index d151505e9f8..131eacb13c4 100644 --- a/gdbserver/win32-low.cc +++ b/gdbserver/win32-low.cc @@ -1659,6 +1659,18 @@ win32_process_target::sw_breakpoint_from_kind (int kind, int *size) return the_low_target.breakpoint; } +CORE_ADDR +win32_process_target::read_pc (struct regcache *regcache) +{ + return (*the_low_target.get_pc) (regcache); +} + +void +win32_process_target::write_pc (struct regcache *regcache, CORE_ADDR pc) +{ + return (*the_low_target.set_pc) (regcache, pc); +} + /* The win32 target ops object. */ static win32_process_target the_win32_target; diff --git a/gdbserver/win32-low.h b/gdbserver/win32-low.h index 917f7275622..56ff8a9baf2 100644 --- a/gdbserver/win32-low.h +++ b/gdbserver/win32-low.h @@ -63,6 +63,11 @@ struct win32_target_ops 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, @@ -142,6 +147,10 @@ public: int get_tib_address (ptid_t ptid, CORE_ADDR *addr) override; const gdb_byte *sw_breakpoint_from_kind (int kind, int *size) override; + + CORE_ADDR read_pc (regcache *regcache) override; + + void write_pc (regcache *regcache, CORE_ADDR pc) override; }; /* Retrieve the context for this thread, if not already retrieved. */ -- 2.30.2