Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Hannes Domani <ssbssa@yahoo.de>
To: gdb-patches@sourceware.org
Subject: [PATCH v2 06/11] Move x86 register code into x86-windows-nat.c
Date: Sat, 17 Jan 2026 14:54:29 +0100	[thread overview]
Message-ID: <20260117135448.2666604-6-ssbssa@yahoo.de> (raw)
In-Reply-To: <20260117134052.2660009-1-ssbssa@yahoo.de>

---
 gdb/windows-nat.c     | 144 ++----------------------------------------
 gdb/windows-nat.h     |  29 +++++++--
 gdb/x86-windows-nat.c | 137 +++++++++++++++++++++++++++++++++++++++-
 3 files changed, 163 insertions(+), 147 deletions(-)

diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c
index e1da956b125..926b85d479b 100644
--- a/gdb/windows-nat.c
+++ b/gdb/windows-nat.c
@@ -57,9 +57,6 @@
 #include "xml-support.h"
 #include "inttypes.h"
 
-#include "i386-tdep.h"
-#include "i387-tdep.h"
-
 #include "windows-tdep.h"
 #include "windows-nat.h"
 #include "complaints.h"
@@ -389,79 +386,6 @@ windows_nat_target::delete_thread (ptid_t ptid, DWORD exit_code,
     windows_process->thread_list.erase (iter);
 }
 
-/* Fetches register number R from the given windows_thread_info,
-   and supplies its value to the given regcache.
-
-   This function assumes that R is non-negative.  A failed assertion
-   is raised if that is not true.
-
-   This function assumes that TH->RELOAD_CONTEXT is not set, meaning
-   that the windows_thread_info has an up-to-date context.  A failed
-   assertion is raised if that assumption is violated.  */
-
-static void
-windows_fetch_one_register (struct regcache *regcache,
-			    windows_thread_info *th, int r)
-{
-  gdb_assert (r >= 0);
-  gdb_assert (!th->reload_context);
-
-  char *context_ptr = windows_process->with_context (th, [] (auto *context)
-    {
-      return (char *) context;
-    });
-
-  char *context_offset = context_ptr + windows_process->mappings[r];
-  struct gdbarch *gdbarch = regcache->arch ();
-  i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
-
-  gdb_assert (!gdbarch_read_pc_p (gdbarch));
-  gdb_assert (gdbarch_pc_regnum (gdbarch) >= 0);
-  gdb_assert (!gdbarch_write_pc_p (gdbarch));
-
-  /* GDB treats some registers as 32-bit, where they are in fact only
-     16 bits long.  These cases must be handled specially to avoid
-     reading extraneous bits from the context.  */
-  if (r == I387_FISEG_REGNUM (tdep) || windows_process->segment_register_p (r))
-    {
-      gdb_byte bytes[4] = {};
-      memcpy (bytes, context_offset, 2);
-      regcache->raw_supply (r, bytes);
-    }
-  else if (r == I387_FOP_REGNUM (tdep))
-    {
-      long l = (*((long *) context_offset) >> 16) & ((1 << 11) - 1);
-      regcache->raw_supply (r, &l);
-    }
-  else
-    {
-      if (th->stopped_at_software_breakpoint
-	  && !th->pc_adjusted
-	  && r == gdbarch_pc_regnum (gdbarch))
-	{
-	  int size = register_size (gdbarch, r);
-	  if (size == 4)
-	    {
-	      uint32_t value;
-	      memcpy (&value, context_offset, size);
-	      value -= gdbarch_decr_pc_after_break (gdbarch);
-	      memcpy (context_offset, &value, size);
-	    }
-	  else
-	    {
-	      gdb_assert (size == 8);
-	      uint64_t value;
-	      memcpy (&value, context_offset, size);
-	      value -= gdbarch_decr_pc_after_break (gdbarch);
-	      memcpy (context_offset, &value, size);
-	    }
-	  /* Make sure we only rewrite the PC a single time.  */
-	  th->pc_adjusted = true;
-	}
-      regcache->raw_supply (r, context_offset);
-    }
-}
-
 void
 windows_nat_target::fetch_registers (struct regcache *regcache, int r)
 {
@@ -482,51 +406,9 @@ windows_nat_target::fetch_registers (struct regcache *regcache, int r)
 
   if (r < 0)
     for (r = 0; r < gdbarch_num_regs (regcache->arch()); r++)
-      windows_fetch_one_register (regcache, th, r);
-  else
-    windows_fetch_one_register (regcache, th, r);
-}
-
-/* Collect the register number R from the given regcache, and store
-   its value into the corresponding area of the given thread's context.
-
-   This function assumes that R is non-negative.  A failed assertion
-   assertion is raised if that is not true.  */
-
-static void
-windows_store_one_register (const struct regcache *regcache,
-			    windows_thread_info *th, int r)
-{
-  gdb_assert (r >= 0);
-
-  char *context_ptr = windows_process->with_context (th, [] (auto *context)
-    {
-      return (char *) context;
-    });
-
-  struct gdbarch *gdbarch = regcache->arch ();
-  i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
-
-  /* GDB treats some registers as 32-bit, where they are in fact only
-     16 bits long.  These cases must be handled specially to avoid
-     overwriting other registers in the context.  */
-  if (r == I387_FISEG_REGNUM (tdep) || windows_process->segment_register_p (r))
-    {
-      gdb_byte bytes[4];
-      regcache->raw_collect (r, bytes);
-      memcpy (context_ptr + windows_process->mappings[r], bytes, 2);
-    }
-  else if (r == I387_FOP_REGNUM (tdep))
-    {
-      gdb_byte bytes[4];
-      regcache->raw_collect (r, bytes);
-      /* The value of FOP occupies the top two bytes in the context,
-	 so write the two low-order bytes from the cache into the
-	 appropriate spot.  */
-      memcpy (context_ptr + windows_process->mappings[r] + 2, bytes, 2);
-    }
+      fetch_one_register (regcache, th, r);
   else
-    regcache->raw_collect (r, context_ptr + windows_process->mappings[r]);
+    fetch_one_register (regcache, th, r);
 }
 
 /* Store a new register value into the context of the thread tied to
@@ -545,9 +427,9 @@ windows_nat_target::store_registers (struct regcache *regcache, int r)
 
   if (r < 0)
     for (r = 0; r < gdbarch_num_regs (regcache->arch ()); r++)
-      windows_store_one_register (regcache, th, r);
+      store_one_register (regcache, th, r);
   else
-    windows_store_one_register (regcache, th, r);
+    store_one_register (regcache, th, r);
 }
 
 bool
@@ -1472,7 +1354,7 @@ windows_nat_target::do_initial_windows_stuff (DWORD pid, bool attaching)
 {
   struct inferior *inf;
 
-  initialize_windows_arch ();
+  initialize_windows_arch (attaching);
 
   windows_process->last_sig = GDB_SIGNAL_0;
   windows_process->open_process_used = 0;
@@ -1490,22 +1372,6 @@ windows_nat_target::do_initial_windows_stuff (DWORD pid, bool attaching)
   clear_proceed_status (0);
   init_wait_for_inferior ();
 
-#ifdef __x86_64__
-  windows_process->ignore_first_breakpoint
-    = !attaching && windows_process->wow64_process;
-
-  if (!windows_process->wow64_process)
-    {
-      windows_process->mappings  = amd64_mappings;
-      windows_process->segment_register_p = amd64_windows_segment_register_p;
-    }
-  else
-#endif
-    {
-      windows_process->mappings  = i386_mappings;
-      windows_process->segment_register_p = i386_windows_segment_register_p;
-    }
-
   inferior_appeared (inf, pid);
   inf->attach_flag = attaching;
 
diff --git a/gdb/windows-nat.h b/gdb/windows-nat.h
index 6553052f420..df872907535 100644
--- a/gdb/windows-nat.h
+++ b/gdb/windows-nat.h
@@ -83,10 +83,6 @@ struct windows_per_inferior : public windows_nat::windows_process_info
 
   const int *mappings = nullptr;
 
-  /* The function to use in order to determine whether a register is
-     a segment register or not.  */
-  segment_register_p_ftype *segment_register_p = nullptr;
-
   std::vector<windows_solib> solibs;
 
 #ifdef __CYGWIN__
@@ -184,8 +180,9 @@ struct windows_nat_target : public inf_child_target
 protected:
 
   /* Initialize arch-specific data for a new inferior (debug registers,
-     register mappings).  */
-  virtual void initialize_windows_arch () = 0;
+     register mappings).  If ATTACHING is true, we're attaching to an
+     already-running process.  */
+  virtual void initialize_windows_arch (bool attaching) = 0;
   /* Cleanup arch-specific data after inferior exit.  */
   virtual void cleanup_windows_arch () = 0;
 
@@ -198,6 +195,26 @@ struct windows_nat_target : public inf_child_target
   /* Set the stepping bit in the thread context.  */
   virtual void thread_context_step (windows_thread_info *th) = 0;
 
+  /* Fetches register number R from the given windows_thread_info,
+     and supplies its value to the given regcache.
+
+     This function assumes that R is non-negative.  A failed assertion
+     is raised if that is not true.
+
+     This function assumes that TH->RELOAD_CONTEXT is not set, meaning
+     that the windows_thread_info has an up-to-date context.  A failed
+     assertion is raised if that assumption is violated.  */
+  virtual void fetch_one_register (struct regcache *regcache,
+				   windows_thread_info *th, int r) = 0;
+
+  /* Collect the register number R from the given regcache, and store
+     its value into the corresponding area of the given thread's context.
+
+     This function assumes that R is non-negative.  A failed assertion
+     assertion is raised if that is not true.  */
+  virtual void store_one_register (const struct regcache *regcache,
+				   windows_thread_info *th, int r) = 0;
+
 private:
 
   windows_thread_info *add_thread (ptid_t ptid, HANDLE h, void *tlb,
diff --git a/gdb/x86-windows-nat.c b/gdb/x86-windows-nat.c
index 88844e0675a..96dd61b39fb 100644
--- a/gdb/x86-windows-nat.c
+++ b/gdb/x86-windows-nat.c
@@ -23,6 +23,9 @@
 
 #include "x86-nat.h"
 
+#include "i386-tdep.h"
+#include "i387-tdep.h"
+
 using namespace windows_nat;
 
 /* If we're not using the old Cygwin header file set, define the
@@ -53,17 +56,26 @@ check (BOOL ok, const char *file, int line)
 struct x86_windows_per_inferior : public windows_per_inferior
 {
   uintptr_t dr[8] {};
+
+  /* The function to use in order to determine whether a register is
+     a segment register or not.  */
+  segment_register_p_ftype *segment_register_p = nullptr;
 };
 
 struct x86_windows_nat_target final : public x86_nat_target<windows_nat_target>
 {
-  void initialize_windows_arch () override;
+  void initialize_windows_arch (bool attaching) override;
   void cleanup_windows_arch () override;
 
   void fill_thread_context (windows_thread_info *th) override;
 
   void thread_context_continue (windows_thread_info *th, int killed) override;
   void thread_context_step (windows_thread_info *th) override;
+
+  void fetch_one_register (struct regcache *regcache,
+			   windows_thread_info *th, int r) override;
+  void store_one_register (const struct regcache *regcache,
+			   windows_thread_info *th, int r) override;
 };
 
 /* The current process.  */
@@ -72,9 +84,25 @@ static x86_windows_per_inferior x86_windows_process;
 /* See windows-nat.h.  */
 
 void
-x86_windows_nat_target::initialize_windows_arch ()
+x86_windows_nat_target::initialize_windows_arch (bool attaching)
 {
   memset (x86_windows_process.dr, 0, sizeof (x86_windows_process.dr));
+
+#ifdef __x86_64__
+  x86_windows_process.ignore_first_breakpoint
+    = !attaching && x86_windows_process.wow64_process;
+
+  if (!x86_windows_process.wow64_process)
+    {
+      x86_windows_process.mappings  = amd64_mappings;
+      x86_windows_process.segment_register_p = amd64_windows_segment_register_p;
+    }
+  else
+#endif
+    {
+      x86_windows_process.mappings  = i386_mappings;
+      x86_windows_process.segment_register_p = i386_windows_segment_register_p;
+    }
 }
 
 /* See windows-nat.h.  */
@@ -158,6 +186,111 @@ x86_windows_nat_target::thread_context_step (windows_thread_info *th)
     });
 }
 
+/* See windows-nat.h.  */
+
+void
+x86_windows_nat_target::fetch_one_register (struct regcache *regcache,
+					    windows_thread_info *th, int r)
+{
+  gdb_assert (r >= 0);
+  gdb_assert (!th->reload_context);
+
+  char *context_ptr = x86_windows_process.with_context (th, [] (auto *context)
+    {
+      return (char *) context;
+    });
+
+  char *context_offset = context_ptr + x86_windows_process.mappings[r];
+  struct gdbarch *gdbarch = regcache->arch ();
+  i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
+
+  gdb_assert (!gdbarch_read_pc_p (gdbarch));
+  gdb_assert (gdbarch_pc_regnum (gdbarch) >= 0);
+  gdb_assert (!gdbarch_write_pc_p (gdbarch));
+
+  /* GDB treats some registers as 32-bit, where they are in fact only
+     16 bits long.  These cases must be handled specially to avoid
+     reading extraneous bits from the context.  */
+  if (r == I387_FISEG_REGNUM (tdep)
+      || x86_windows_process.segment_register_p (r))
+    {
+      gdb_byte bytes[4] = {};
+      memcpy (bytes, context_offset, 2);
+      regcache->raw_supply (r, bytes);
+    }
+  else if (r == I387_FOP_REGNUM (tdep))
+    {
+      long l = (*((long *) context_offset) >> 16) & ((1 << 11) - 1);
+      regcache->raw_supply (r, &l);
+    }
+  else
+    {
+      if (th->stopped_at_software_breakpoint
+	  && !th->pc_adjusted
+	  && r == gdbarch_pc_regnum (gdbarch))
+	{
+	  int size = register_size (gdbarch, r);
+	  if (size == 4)
+	    {
+	      uint32_t value;
+	      memcpy (&value, context_offset, size);
+	      value -= gdbarch_decr_pc_after_break (gdbarch);
+	      memcpy (context_offset, &value, size);
+	    }
+	  else
+	    {
+	      gdb_assert (size == 8);
+	      uint64_t value;
+	      memcpy (&value, context_offset, size);
+	      value -= gdbarch_decr_pc_after_break (gdbarch);
+	      memcpy (context_offset, &value, size);
+	    }
+	  /* Make sure we only rewrite the PC a single time.  */
+	  th->pc_adjusted = true;
+	}
+      regcache->raw_supply (r, context_offset);
+    }
+}
+
+/* See windows-nat.h.  */
+
+void
+x86_windows_nat_target::store_one_register (const struct regcache *regcache,
+					    windows_thread_info *th, int r)
+{
+  gdb_assert (r >= 0);
+
+  char *context_ptr = x86_windows_process.with_context (th, [] (auto *context)
+    {
+      return (char *) context;
+    });
+
+  struct gdbarch *gdbarch = regcache->arch ();
+  i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
+
+  /* GDB treats some registers as 32-bit, where they are in fact only
+     16 bits long.  These cases must be handled specially to avoid
+     overwriting other registers in the context.  */
+  if (r == I387_FISEG_REGNUM (tdep)
+      || x86_windows_process.segment_register_p (r))
+    {
+      gdb_byte bytes[4];
+      regcache->raw_collect (r, bytes);
+      memcpy (context_ptr + x86_windows_process.mappings[r], bytes, 2);
+    }
+  else if (r == I387_FOP_REGNUM (tdep))
+    {
+      gdb_byte bytes[4];
+      regcache->raw_collect (r, bytes);
+      /* The value of FOP occupies the top two bytes in the context,
+	 so write the two low-order bytes from the cache into the
+	 appropriate spot.  */
+      memcpy (context_ptr + x86_windows_process.mappings[r] + 2, bytes, 2);
+    }
+  else
+    regcache->raw_collect (r, context_ptr + x86_windows_process.mappings[r]);
+}
+
 /* Hardware watchpoint support, adapted from go32-nat.c code.  */
 
 /* Pass the address ADDR to the inferior in the I'th debug register.
-- 
2.52.0


  parent reply	other threads:[~2026-01-17 13:55 UTC|newest]

Thread overview: 44+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20260117134052.2660009-1-ssbssa.ref@yahoo.de>
2026-01-17 13:36 ` [PATCH v2 01/11] Remove duplicate code from windows_nat_target::resume Hannes Domani
2026-01-17 13:36   ` [PATCH v2 02/11] Simplify windows_nat_target::resume Hannes Domani
2026-01-19 13:55     ` Schimpe, Christina
2026-01-21 15:42       ` Tom Tromey
2026-01-23 19:11       ` Hannes Domani
2026-01-17 13:36   ` [PATCH v2 03/11] Move struct declarations into windows-nat.h Hannes Domani
2026-01-17 13:36   ` [PATCH v2 04/11] Create x86-windows-nat.c Hannes Domani
2026-01-21 15:38     ` Tom Tromey
2026-01-17 13:36   ` [PATCH v2 05/11] Move x86 debug registers and related code into x86-windows-nat.c Hannes Domani
2026-01-19 12:49     ` Schimpe, Christina
2026-01-20 15:49       ` Hannes Domani
2026-01-21  8:06         ` Schimpe, Christina
2026-01-23 13:17     ` [PATCH v3] " Hannes Domani
2026-01-23 18:50       ` Tom Tromey
2026-01-23 19:20         ` Hannes Domani
2026-01-23 19:56           ` Tom Tromey
2026-01-17 13:36   ` [PATCH v2 06/11] Move x86 register " Hannes Domani
2026-01-19 12:50     ` Schimpe, Christina
2026-01-17 13:36   ` [PATCH v2 07/11] Move x86 selector " Hannes Domani
2026-01-19 13:56     ` Schimpe, Christina
2026-01-17 13:36   ` [PATCH v2 08/11] Move software breakpoint recognition " Hannes Domani
2026-01-19 12:51     ` Schimpe, Christina
2026-01-21 15:43       ` Tom Tromey
2026-01-23 19:12         ` Hannes Domani
2026-01-17 13:36   ` [PATCH v2 09/11] Move auto_wide_charset gdbarch method to windows-tdep Hannes Domani
2026-01-17 13:36   ` [PATCH v2 10/11] Move setting size of long " Hannes Domani
2026-01-21 15:47     ` Tom Tromey
2026-01-17 13:54   ` [PATCH v2 04/11] Create x86-windows-nat.c Hannes Domani
2026-01-17 14:01     ` Hannes Domani
2026-01-17 14:14       ` Hannes Domani
2026-01-17 15:04       ` Simon Marchi
2026-01-17 15:15         ` Hannes Domani
2026-01-17 13:54   ` [PATCH v2 05/11] Move x86 debug registers and related code into x86-windows-nat.c Hannes Domani
2026-01-17 13:54   ` Hannes Domani [this message]
2026-01-21 16:08     ` [PATCH v2 06/11] Move x86 register " Tom Tromey
2026-01-17 13:54   ` [PATCH v2 09/11] Move auto_wide_charset gdbarch method to windows-tdep Hannes Domani
2026-01-21 15:48     ` Tom Tromey
2026-01-23 19:13       ` Hannes Domani
2026-01-17 13:54   ` [PATCH v2 10/11] Move setting size of long " Hannes Domani
2026-01-21 15:59     ` Tom Tromey
2026-01-17 13:54   ` [PATCH v2 11/11] Add aarch64-windows support Hannes Domani
2026-01-17 16:04     ` Eli Zaretskii
2026-01-21 16:18     ` Tom Tromey
2026-01-23 19:14       ` Hannes Domani

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260117135448.2666604-6-ssbssa@yahoo.de \
    --to=ssbssa@yahoo.de \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox