Add read_pc / write_pc support to win32-low
authorTom Tromey <tromey@adacore.com>
Wed, 8 Apr 2020 20:33:35 +0000 (14:33 -0600)
committerTom Tromey <tromey@adacore.com>
Wed, 8 Apr 2020 20:47:59 +0000 (14:47 -0600)
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  <tromey@adacore.com>

* 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
gdbserver/win32-arm-low.cc
gdbserver/win32-i386-low.cc
gdbserver/win32-low.cc
gdbserver/win32-low.h

index 792834077feddd098ab54a03487a4440cf550af0..ee66a4b6d99d62c8837ebe56669ff906b12c4c43 100644 (file)
@@ -1,3 +1,16 @@
+2020-04-08  Tom Tromey  <tromey@adacore.com>
+
+       * 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  <tromey@adacore.com>
 
        * win32-low.c (win32_kill, get_child_debug_event): Use
index 78b7fd09ec3266466f4701df4ef03fc5c9cff0e3..77200112df135e25c515ba6792225451d9b9cdca 100644 (file)
@@ -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 */
index 1c14bc70362586a883fd975cb426d4e3cd5c391f..eac15b5694a8e4c4477b6bfe93ae5f44f259bd3f 100644 (file)
@@ -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,
index d151505e9f8cad5fdfdbd1112fd0edbb3db210bf..131eacb13c4110e7eb22a36d174f1147ebf10101 100644 (file)
@@ -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;
index 917f72756229d9648bc4434abc7a255f7d646a78..56ff8a9baf2a8360881adc5178fed5c667739a4d 100644 (file)
@@ -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.  */