public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 0/2] More Windows globals cleanups
@ 2022-04-07 19:56 Tom Tromey
  2022-04-07 19:56 ` [PATCH 1/2] Turn some windows-nat.c static functions into methods Tom Tromey
                   ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Tom Tromey @ 2022-04-07 19:56 UTC (permalink / raw)
  To: gdb-patches

This short series moves more globals from windows-nat into a
structure.  This is more preparation for multi-inferior.  (Note I
haven't implemented multi-inferior, this is just preparation in case
we do.)

This only partially converts gdbserver.  The x86 back end still has
some globals, and I didn't try to fix this.

I regression tested this using the internal AdaCore test suite.

Tom



^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 1/2] Turn some windows-nat.c static functions into methods
  2022-04-07 19:56 [PATCH 0/2] More Windows globals cleanups Tom Tromey
@ 2022-04-07 19:56 ` Tom Tromey
  2022-04-07 19:56 ` [PATCH 2/2] Use subclasses of windows_process_info Tom Tromey
  2022-06-07 18:15 ` [PATCH 0/2] More Windows globals cleanups Tom Tromey
  2 siblings, 0 replies; 7+ messages in thread
From: Tom Tromey @ 2022-04-07 19:56 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

This patch turns some windows-nat.c static functions into methods on
windows_nat_target.  This avoids having to reference the
windows_nat_target singleton in some more spots -- a minor code
cleanup.
---
 gdb/windows-nat.c | 47 ++++++++++++++++++++++++++++-------------------
 1 file changed, 28 insertions(+), 19 deletions(-)

diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c
index 646ddda7328..564eb867ff4 100644
--- a/gdb/windows-nat.c
+++ b/gdb/windows-nat.c
@@ -287,6 +287,13 @@ struct windows_nat_target final : public x86_nat_target<inf_child_target>
   int get_windows_debug_event (int pid, struct target_waitstatus *ourstatus);
 
   void do_initial_windows_stuff (DWORD pid, bool attaching);
+
+private:
+
+  windows_thread_info *add_thread (ptid_t ptid, HANDLE h, void *tlb,
+				   bool main_thread_p);
+  void delete_thread (ptid_t ptid, DWORD exit_code, bool main_thread_p);
+  DWORD fake_create_process ();
 };
 
 static windows_nat_target the_windows_nat_target;
@@ -358,8 +365,9 @@ windows_nat::windows_process_info::thread_rec
    MAIN_THREAD_P should be true if the thread to be added is
    the main thread, false otherwise.  */
 
-static windows_thread_info *
-windows_add_thread (ptid_t ptid, HANDLE h, void *tlb, bool main_thread_p)
+windows_thread_info *
+windows_nat_target::add_thread (ptid_t ptid, HANDLE h, void *tlb,
+				bool main_thread_p)
 {
   windows_thread_info *th;
 
@@ -384,9 +392,9 @@ windows_add_thread (ptid_t ptid, HANDLE h, void *tlb, bool main_thread_p)
      the main thread silently (in reality, this thread is really
      more of a process to the user than a thread).  */
   if (main_thread_p)
-    add_thread_silent (&the_windows_nat_target, ptid);
+    add_thread_silent (this, ptid);
   else
-    add_thread (&the_windows_nat_target, ptid);
+    ::add_thread (this, ptid);
 
   /* It's simplest to always set this and update the debug
      registers.  */
@@ -411,8 +419,9 @@ windows_init_thread_list (void)
    MAIN_THREAD_P should be true if the thread to be deleted is
    the main thread, false otherwise.  */
 
-static void
-windows_delete_thread (ptid_t ptid, DWORD exit_code, bool main_thread_p)
+void
+windows_nat_target::delete_thread (ptid_t ptid, DWORD exit_code,
+				   bool main_thread_p)
 {
   DWORD id;
 
@@ -434,7 +443,7 @@ windows_delete_thread (ptid_t ptid, DWORD exit_code, bool main_thread_p)
 		target_pid_to_str (ptid).c_str (),
 		(unsigned) exit_code);
 
-  delete_thread (find_thread_ptid (&the_windows_nat_target, ptid));
+  ::delete_thread (find_thread_ptid (&the_windows_nat_target, ptid));
 
   auto iter = std::find_if (thread_list.begin (), thread_list.end (),
 			    [=] (auto &th)
@@ -1215,8 +1224,8 @@ windows_continue (DWORD continue_status, int id, int killed)
 
 /* Called in pathological case where Windows fails to send a
    CREATE_PROCESS_DEBUG_EVENT after an attach.  */
-static DWORD
-fake_create_process (void)
+DWORD
+windows_nat_target::fake_create_process ()
 {
   windows_process.handle
     = OpenProcess (PROCESS_ALL_ACCESS, FALSE,
@@ -1229,7 +1238,7 @@ fake_create_process (void)
        (unsigned) GetLastError ());
       /*  We can not debug anything in that case.  */
     }
-  windows_add_thread (ptid_t (windows_process.current_event.dwProcessId, 0,
+  add_thread (ptid_t (windows_process.current_event.dwProcessId, 0,
 			      windows_process.current_event.dwThreadId),
 		      windows_process.current_event.u.CreateThread.hThread,
 		      windows_process.current_event.u.CreateThread.lpThreadLocalBase,
@@ -1479,7 +1488,7 @@ windows_nat_target::get_windows_debug_event (int pid,
 	}
       /* Record the existence of this thread.  */
       thread_id = current_event->dwThreadId;
-      windows_add_thread
+      add_thread
 	(ptid_t (current_event->dwProcessId, current_event->dwThreadId, 0),
 	 current_event->u.CreateThread.hThread,
 	 current_event->u.CreateThread.lpThreadLocalBase,
@@ -1492,10 +1501,10 @@ windows_nat_target::get_windows_debug_event (int pid,
 		    (unsigned) current_event->dwProcessId,
 		    (unsigned) current_event->dwThreadId,
 		    "EXIT_THREAD_DEBUG_EVENT");
-      windows_delete_thread (ptid_t (current_event->dwProcessId,
-				     current_event->dwThreadId, 0),
-			     current_event->u.ExitThread.dwExitCode,
-			     false /* main_thread_p */);
+      delete_thread (ptid_t (current_event->dwProcessId,
+			     current_event->dwThreadId, 0),
+		     current_event->u.ExitThread.dwExitCode,
+		     false /* main_thread_p */);
       break;
 
     case CREATE_PROCESS_DEBUG_EVENT:
@@ -1509,7 +1518,7 @@ windows_nat_target::get_windows_debug_event (int pid,
 
       windows_process.handle = current_event->u.CreateProcessInfo.hProcess;
       /* Add the main thread.  */
-      windows_add_thread
+      add_thread
 	(ptid_t (current_event->dwProcessId,
 		 current_event->dwThreadId, 0),
 	 current_event->u.CreateProcessInfo.hThread,
@@ -1532,9 +1541,9 @@ windows_nat_target::get_windows_debug_event (int pid,
 	}
       else if (saw_create == 1)
 	{
-	  windows_delete_thread (ptid_t (current_event->dwProcessId,
-					 current_event->dwThreadId, 0),
-				 0, true /* main_thread_p */);
+	  delete_thread (ptid_t (current_event->dwProcessId,
+				 current_event->dwThreadId, 0),
+			 0, true /* main_thread_p */);
 	  DWORD exit_status = current_event->u.ExitProcess.dwExitCode;
 	  /* If the exit status looks like a fatal exception, but we
 	     don't recognize the exception's code, make the original
-- 
2.34.1


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 2/2] Use subclasses of windows_process_info
  2022-04-07 19:56 [PATCH 0/2] More Windows globals cleanups Tom Tromey
  2022-04-07 19:56 ` [PATCH 1/2] Turn some windows-nat.c static functions into methods Tom Tromey
@ 2022-04-07 19:56 ` Tom Tromey
  2022-06-12 16:27   ` [PATCH] Fix Cygwin build after 20489cca Jon Turney
  2022-06-12 16:28   ` [PATCH 2/2] Use subclasses of windows_process_info Jon Turney
  2022-06-07 18:15 ` [PATCH 0/2] More Windows globals cleanups Tom Tromey
  2 siblings, 2 replies; 7+ messages in thread
From: Tom Tromey @ 2022-04-07 19:56 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

This changes windows_process_info to use virtual methods for its
callbacks, and then changes the two clients of this code to subclass
this class to implement the methods.

I considered using CRTP here, but that would require making the new
structures visible to the compilation of of nat/windows-nat.c.  This
seemed like a bit of a pain, so I didn't do it.

This change then lets us change all the per-inferior globals to be
members of the new subclass.  Note that there can still only be a
single inferior -- currently there's a single global of the new type.
This is just another step toward possibly implementing multi-inferior
for Windows.

It's possible this could be cleaned up further... ideally I'd like to
move more of the data into the base class.  However, because gdb
supports Cygwin and gdbserver dose not, and because I don't have a way
to build or test Cygwin, larger refactorings are difficult.
---
 gdb/nat/windows-nat.h  |  14 +-
 gdb/windows-nat.c      | 351 +++++++++++++++++++++--------------------
 gdbserver/win32-low.cc | 121 +++++++-------
 3 files changed, 248 insertions(+), 238 deletions(-)

diff --git a/gdb/nat/windows-nat.h b/gdb/nat/windows-nat.h
index 7f76ba0e58f..151bcd7b2b3 100644
--- a/gdb/nat/windows-nat.h
+++ b/gdb/nat/windows-nat.h
@@ -179,8 +179,8 @@ struct windows_process_info
      is invalidated.
 
      This function must be supplied by the embedding application.  */
-  windows_thread_info *thread_rec (ptid_t ptid,
-				   thread_disposition_type disposition);
+  virtual windows_thread_info *thread_rec (ptid_t ptid,
+					   thread_disposition_type disposition) = 0;
 
   /* Handle OUTPUT_DEBUG_STRING_EVENT from child process.  Updates
      OURSTATUS and returns the thread id if this represents a thread
@@ -190,7 +190,7 @@ struct windows_process_info
      a Cygwin signal.  Otherwise just print the string as a warning.
 
      This function must be supplied by the embedding application.  */
-  int handle_output_debug_string (struct target_waitstatus *ourstatus);
+  virtual int handle_output_debug_string (struct target_waitstatus *ourstatus) = 0;
 
   /* Handle a DLL load event.
 
@@ -202,7 +202,7 @@ struct windows_process_info
 
      This function must be supplied by the embedding application.  */
 
-  void handle_load_dll (const char *dll_name, LPVOID base);
+  virtual void handle_load_dll (const char *dll_name, LPVOID base) = 0;
 
   /* Handle a DLL unload event.
 
@@ -211,7 +211,7 @@ struct windows_process_info
 
      This function must be supplied by the embedding application.  */
 
-  void handle_unload_dll ();
+  virtual void handle_unload_dll () = 0;
 
   /* Handle MS_VC_EXCEPTION when processing a stop.  MS_VC_EXCEPTION is
      somewhat undocumented but is used to tell the debugger the name of
@@ -221,14 +221,14 @@ struct windows_process_info
 
      This function must be supplied by the embedding application.  */
 
-  bool handle_ms_vc_exception (const EXCEPTION_RECORD *rec);
+  virtual bool handle_ms_vc_exception (const EXCEPTION_RECORD *rec) = 0;
 
   /* When EXCEPTION_ACCESS_VIOLATION is processed, we give the embedding
      application a chance to change it to be considered "unhandled".
      This function must be supplied by the embedding application.  If it
      returns true, then the exception is "unhandled".  */
 
-  bool handle_access_violation (const EXCEPTION_RECORD *rec);
+  virtual bool handle_access_violation (const EXCEPTION_RECORD *rec) = 0;
 
   handle_exception_result handle_exception
        (struct target_waitstatus *ourstatus, bool debug_exceptions);
diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c
index 564eb867ff4..8082633f6fc 100644
--- a/gdb/windows-nat.c
+++ b/gdb/windows-nat.c
@@ -74,8 +74,81 @@
 
 using namespace windows_nat;
 
+/* Maintain a linked list of "so" information.  */
+struct windows_solib
+{
+  LPVOID load_addr = 0;
+  CORE_ADDR text_offset = 0;
+
+  /* Original name.  */
+  std::string original_name;
+  /* Expanded form of the name.  */
+  std::string name;
+};
+
+struct windows_per_inferior : public windows_process_info
+{
+  windows_thread_info *thread_rec (ptid_t ptid,
+				   thread_disposition_type disposition) override;
+  int handle_output_debug_string (struct target_waitstatus *ourstatus) override;
+  void handle_load_dll (const char *dll_name, LPVOID base) override;
+  void handle_unload_dll () override;
+  bool handle_ms_vc_exception (const EXCEPTION_RECORD *rec) override;
+  bool handle_access_violation (const EXCEPTION_RECORD *rec) override;
+
+
+  int have_saved_context = 0;	/* True if we've saved context from a
+				   cygwin signal.  */
+
+  uintptr_t dr[8] {};
+
+  int windows_initialization_done = 0;
+
+  std::vector<std::unique_ptr<windows_thread_info>> thread_list;
+
+  /* Counts of things.  */
+  int saw_create = 0;
+  int open_process_used = 0;
+#ifdef __x86_64__
+  void *wow64_dbgbreak = nullptr;
+#endif
+
+  /* This vector maps GDB's idea of a register's number into an offset
+     in the windows exception context vector.
+
+     It also contains the bit mask needed to load the register in question.
+
+     The contents of this table can only be computed by the units
+     that provide CPU-specific support for Windows native debugging.
+
+     One day we could read a reg, we could inspect the context we
+     already have loaded, if it doesn't have the bit set that we need,
+     we read that set of registers in using GetThreadContext.  If the
+     context already contains what we need, we just unpack it.  Then to
+     write a register, first we have to ensure that the context contains
+     the other regs of the group, and then we copy the info in and set
+     out bit.  */
+
+  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__
+  CONTEXT saved_context {};	/* Contains the saved context from a
+				   cygwin signal.  */
+
+  /* The starting and ending address of the cygwin1.dll text segment.  */
+  CORE_ADDR cygwin_load_start = 0;
+  CORE_ADDR cygwin_load_end = 0;
+#endif /* __CYGWIN__ */
+};
+
 /* The current process.  */
-static windows_process_info windows_process;
+static windows_per_inferior windows_process;
 
 #undef STARTUPINFO
 #undef CreateProcess
@@ -88,9 +161,6 @@ static windows_process_info windows_process;
 # define CreateProcess CreateProcessA
 #else
 # define __PMAX	PATH_MAX
-/* The starting and ending address of the cygwin1.dll text segment.  */
-  static CORE_ADDR cygwin_load_start;
-  static CORE_ADDR cygwin_load_end;
 #   define __USEWIDE
     typedef wchar_t cygwin_buf_t;
 #   define GetModuleFileNameEx GetModuleFileNameExW
@@ -98,13 +168,6 @@ static windows_process_info windows_process;
 #   define CreateProcess CreateProcessW
 #endif
 
-static int have_saved_context;	/* True if we've saved context from a
-				   cygwin signal.  */
-#ifdef __CYGWIN__
-static CONTEXT saved_context;	/* Contains the saved context from a
-				   cygwin signal.  */
-#endif
-
 /* If we're not using the old Cygwin header file set, define the
    following which never should have been in the generic Win32 API
    headers in the first place since they were our own invention...  */
@@ -125,9 +188,6 @@ enum
 	| CONTEXT_SEGMENTS | CONTEXT_DEBUG_REGISTERS \
 	| CONTEXT_EXTENDED_REGISTERS
 
-static uintptr_t dr[8];
-
-static int windows_initialization_done;
 #define DR6_CLEAR_VALUE 0xffff0ff0
 
 /* The string sent by cygwin when it processes a signal.
@@ -155,15 +215,6 @@ static CORE_ADDR cygwin_get_dr (int i);
 static unsigned long cygwin_get_dr6 (void);
 static unsigned long cygwin_get_dr7 (void);
 
-static std::vector<std::unique_ptr<windows_thread_info>> thread_list;
-
-/* Counts of things.  */
-static int saw_create;
-static int open_process_used = 0;
-#ifdef __x86_64__
-static void *wow64_dbgbreak;
-#endif
-
 /* User options.  */
 static bool new_console = false;
 #ifdef __CYGWIN__
@@ -176,30 +227,6 @@ static bool debug_memory = false;	/* show target memory accesses */
 static bool debug_exceptions = false;	/* show target exceptions */
 static bool useshell = false;		/* use shell for subprocesses */
 
-/* This vector maps GDB's idea of a register's number into an offset
-   in the windows exception context vector.
-
-   It also contains the bit mask needed to load the register in question.
-
-   The contents of this table can only be computed by the units
-   that provide CPU-specific support for Windows native debugging.
-   These units should set the table by calling
-   windows_set_context_register_offsets.
-
-   One day we could read a reg, we could inspect the context we
-   already have loaded, if it doesn't have the bit set that we need,
-   we read that set of registers in using GetThreadContext.  If the
-   context already contains what we need, we just unpack it.  Then to
-   write a register, first we have to ensure that the context contains
-   the other regs of the group, and then we copy the info in and set
-   out bit.  */
-
-static const int *mappings;
-
-/* The function to use in order to determine whether a register is
-   a segment register or not.  */
-static segment_register_p_ftype *segment_register_p;
-
 /* See windows_nat_target::resume to understand why this is commented
    out.  */
 #if 0
@@ -298,24 +325,6 @@ struct windows_nat_target final : public x86_nat_target<inf_child_target>
 
 static windows_nat_target the_windows_nat_target;
 
-/* Set the MAPPINGS static global to OFFSETS.
-   See the description of MAPPINGS for more details.  */
-
-static void
-windows_set_context_register_offsets (const int *offsets)
-{
-  mappings = offsets;
-}
-
-/* Set the function that should be used by this module to determine
-   whether a given register is a segment register or not.  */
-
-static void
-windows_set_segment_register_p (segment_register_p_ftype *fun)
-{
-  segment_register_p = fun;
-}
-
 static void
 check (BOOL ok, const char *file, int line)
 {
@@ -327,7 +336,7 @@ check (BOOL ok, const char *file, int line)
 /* See nat/windows-nat.h.  */
 
 windows_thread_info *
-windows_nat::windows_process_info::thread_rec
+windows_per_inferior::thread_rec
      (ptid_t ptid, thread_disposition_type disposition)
 {
   for (auto &th : thread_list)
@@ -384,7 +393,7 @@ windows_nat_target::add_thread (ptid_t ptid, HANDLE h, void *tlb,
     base += 0x2000;
 #endif
   th = new windows_thread_info (ptid.lwp (), h, base);
-  thread_list.emplace_back (th);
+  windows_process.thread_list.emplace_back (th);
 
   /* Add this new thread to the list of threads.
 
@@ -409,7 +418,7 @@ static void
 windows_init_thread_list (void)
 {
   DEBUG_EVENTS ("called");
-  thread_list.clear ();
+  windows_process.thread_list.clear ();
 }
 
 /* Delete a thread from the list of threads.
@@ -445,14 +454,15 @@ windows_nat_target::delete_thread (ptid_t ptid, DWORD exit_code,
 
   ::delete_thread (find_thread_ptid (&the_windows_nat_target, ptid));
 
-  auto iter = std::find_if (thread_list.begin (), thread_list.end (),
+  auto iter = std::find_if (windows_process.thread_list.begin (),
+			    windows_process.thread_list.end (),
 			    [=] (auto &th)
 			    {
 			      return th->tid == id;
 			    });
 
-  if (iter != thread_list.end ())
-    thread_list.erase (iter);
+  if (iter != windows_process.thread_list.end ())
+    windows_process.thread_list.erase (iter);
 }
 
 /* Fetches register number R from the given windows_thread_info,
@@ -478,7 +488,7 @@ windows_fetch_one_register (struct regcache *regcache,
     context_ptr = (char *) &th->wow64_context;
 #endif
 
-  char *context_offset = context_ptr + mappings[r];
+  char *context_offset = context_ptr + windows_process.mappings[r];
   struct gdbarch *gdbarch = regcache->arch ();
   i386_gdbarch_tdep *tdep = (i386_gdbarch_tdep *) gdbarch_tdep (gdbarch);
 
@@ -496,7 +506,7 @@ windows_fetch_one_register (struct regcache *regcache,
       long l = (*((long *) context_offset) >> 16) & ((1 << 11) - 1);
       regcache->raw_supply (r, (char *) &l);
     }
-  else if (segment_register_p (r))
+  else if (windows_process.segment_register_p (r))
     {
       /* GDB treats segment registers as 32bit registers, but they are
 	 in fact only 16 bits long.  Make sure we do not read extra
@@ -569,12 +579,12 @@ windows_nat_target::fetch_registers (struct regcache *regcache, int r)
 	     PR gdb/2388 */
 	  if (!th->debug_registers_changed)
 	    {
-	      dr[0] = th->wow64_context.Dr0;
-	      dr[1] = th->wow64_context.Dr1;
-	      dr[2] = th->wow64_context.Dr2;
-	      dr[3] = th->wow64_context.Dr3;
-	      dr[6] = th->wow64_context.Dr6;
-	      dr[7] = th->wow64_context.Dr7;
+	      windows_process.dr[0] = th->wow64_context.Dr0;
+	      windows_process.dr[1] = th->wow64_context.Dr1;
+	      windows_process.dr[2] = th->wow64_context.Dr2;
+	      windows_process.dr[3] = th->wow64_context.Dr3;
+	      windows_process.dr[6] = th->wow64_context.Dr6;
+	      windows_process.dr[7] = th->wow64_context.Dr7;
 	    }
 	}
       else
@@ -587,12 +597,12 @@ windows_nat_target::fetch_registers (struct regcache *regcache, int r)
 	     PR gdb/2388 */
 	  if (!th->debug_registers_changed)
 	    {
-	      dr[0] = th->context.Dr0;
-	      dr[1] = th->context.Dr1;
-	      dr[2] = th->context.Dr2;
-	      dr[3] = th->context.Dr3;
-	      dr[6] = th->context.Dr6;
-	      dr[7] = th->context.Dr7;
+	      windows_process.dr[0] = th->context.Dr0;
+	      windows_process.dr[1] = th->context.Dr1;
+	      windows_process.dr[2] = th->context.Dr2;
+	      windows_process.dr[3] = th->context.Dr3;
+	      windows_process.dr[6] = th->context.Dr6;
+	      windows_process.dr[7] = th->context.Dr7;
 	    }
 	}
       th->reload_context = false;
@@ -623,7 +633,7 @@ windows_store_one_register (const struct regcache *regcache,
     context_ptr = (char *) &th->wow64_context;
 #endif
 
-  regcache->raw_collect (r, context_ptr + mappings[r]);
+  regcache->raw_collect (r, context_ptr + windows_process.mappings[r]);
 }
 
 /* Store a new register value into the context of the thread tied to
@@ -647,20 +657,6 @@ windows_nat_target::store_registers (struct regcache *regcache, int r)
     windows_store_one_register (regcache, th, r);
 }
 
-/* Maintain a linked list of "so" information.  */
-struct windows_solib
-{
-  LPVOID load_addr = 0;
-  CORE_ADDR text_offset = 0;
-
-  /* Original name.  */
-  std::string original_name;
-  /* Expanded form of the name.  */
-  std::string name;
-};
-
-static std::vector<windows_solib> solibs;
-
 /* See nat/windows-nat.h.  */
 
 static windows_solib *
@@ -714,8 +710,8 @@ windows_make_so (const char *name, LPVOID load_addr)
 #endif
     }
 #endif
-  solibs.emplace_back ();
-  windows_solib *so = &solibs.back ();
+  windows_process.solibs.emplace_back ();
+  windows_solib *so = &windows_process.solibs.back ();
   so->load_addr = load_addr;
   so->original_name = name;
 #ifndef __CYGWIN__
@@ -776,8 +772,7 @@ windows_make_so (const char *name, LPVOID load_addr)
 /* See nat/windows-nat.h.  */
 
 void
-windows_nat::windows_process_info::handle_load_dll (const char *dll_name,
-						    LPVOID base)
+windows_per_inferior::handle_load_dll (const char *dll_name, LPVOID base)
 {
   windows_solib *solib = windows_make_so (dll_name, base);
   DEBUG_EVENTS ("Loading dll \"%s\" at %s.", solib->name.c_str (),
@@ -787,11 +782,12 @@ windows_nat::windows_process_info::handle_load_dll (const char *dll_name,
 /* See nat/windows-nat.h.  */
 
 void
-windows_nat::windows_process_info::handle_unload_dll ()
+windows_per_inferior::handle_unload_dll ()
 {
   LPVOID lpBaseOfDll = current_event.u.UnloadDll.lpBaseOfDll;
 
-  auto iter = std::remove_if (solibs.begin (), solibs.end (),
+  auto iter = std::remove_if (windows_process.solibs.begin (),
+			      windows_process.solibs.end (),
 			      [&] (windows_solib &lib)
     {
       if (lib.load_addr == lpBaseOfDll)
@@ -802,9 +798,9 @@ windows_nat::windows_process_info::handle_unload_dll ()
       return false;
     });
 
-  if (iter != solibs.end ())
+  if (iter != windows_process.solibs.end ())
     {
-      solibs.erase (iter, solibs.end ());
+      windows_process.solibs.erase (iter, windows_process.solibs.end ());
       return;
     }
 
@@ -823,7 +819,7 @@ windows_nat::windows_process_info::handle_unload_dll ()
 static void
 windows_clear_solib (void)
 {
-  solibs.clear ();
+  windows_process.solibs.clear ();
 }
 
 static void
@@ -848,7 +844,7 @@ signal_event_command (const char *args, int from_tty)
 /* See nat/windows-nat.h.  */
 
 int
-windows_nat::windows_process_info::handle_output_debug_string
+windows_per_inferior::handle_output_debug_string
      (struct target_waitstatus *ourstatus)
 {
   int retval = 0;
@@ -1064,7 +1060,7 @@ display_selectors (const char * args, int from_tty)
 /* See nat/windows-nat.h.  */
 
 bool
-windows_nat::windows_process_info::handle_ms_vc_exception
+windows_per_inferior::handle_ms_vc_exception
      (const EXCEPTION_RECORD *rec)
 {
   if (rec->NumberParameters >= 3
@@ -1104,7 +1100,7 @@ windows_nat::windows_process_info::handle_ms_vc_exception
 /* See nat/windows-nat.h.  */
 
 bool
-windows_nat::windows_process_info::handle_access_violation
+windows_per_inferior::handle_access_violation
      (const EXCEPTION_RECORD *rec)
 {
 #ifdef __CYGWIN__
@@ -1141,7 +1137,7 @@ windows_continue (DWORD continue_status, int id, int killed)
   if (windows_process.matching_pending_stop (debug_events))
     return TRUE;
 
-  for (auto &th : thread_list)
+  for (auto &th : windows_process.thread_list)
     if (id == -1 || id == (int) th->tid)
       {
 #ifdef __x86_64__
@@ -1150,12 +1146,12 @@ windows_continue (DWORD continue_status, int id, int killed)
 	    if (th->debug_registers_changed)
 	      {
 		th->wow64_context.ContextFlags |= CONTEXT_DEBUG_REGISTERS;
-		th->wow64_context.Dr0 = dr[0];
-		th->wow64_context.Dr1 = dr[1];
-		th->wow64_context.Dr2 = dr[2];
-		th->wow64_context.Dr3 = dr[3];
+		th->wow64_context.Dr0 = windows_process.dr[0];
+		th->wow64_context.Dr1 = windows_process.dr[1];
+		th->wow64_context.Dr2 = windows_process.dr[2];
+		th->wow64_context.Dr3 = windows_process.dr[3];
 		th->wow64_context.Dr6 = DR6_CLEAR_VALUE;
-		th->wow64_context.Dr7 = dr[7];
+		th->wow64_context.Dr7 = windows_process.dr[7];
 		th->debug_registers_changed = false;
 	      }
 	    if (th->wow64_context.ContextFlags)
@@ -1180,12 +1176,12 @@ windows_continue (DWORD continue_status, int id, int killed)
 	    if (th->debug_registers_changed)
 	      {
 		th->context.ContextFlags |= CONTEXT_DEBUG_REGISTERS;
-		th->context.Dr0 = dr[0];
-		th->context.Dr1 = dr[1];
-		th->context.Dr2 = dr[2];
-		th->context.Dr3 = dr[3];
+		th->context.Dr0 = windows_process.dr[0];
+		th->context.Dr1 = windows_process.dr[1];
+		th->context.Dr2 = windows_process.dr[2];
+		th->context.Dr3 = windows_process.dr[3];
 		th->context.Dr6 = DR6_CLEAR_VALUE;
-		th->context.Dr7 = dr[7];
+		th->context.Dr7 = windows_process.dr[7];
 		th->debug_registers_changed = false;
 	      }
 	    if (th->context.ContextFlags)
@@ -1231,7 +1227,7 @@ windows_nat_target::fake_create_process ()
     = OpenProcess (PROCESS_ALL_ACCESS, FALSE,
 		   windows_process.current_event.dwProcessId);
   if (windows_process.handle != NULL)
-    open_process_used = 1;
+    windows_process.open_process_used = 1;
   else
     {
       error (_("OpenProcess call failed, GetLastError = %u"),
@@ -1319,12 +1315,12 @@ windows_nat_target::resume (ptid_t ptid, int step, enum gdb_signal sig)
 	    {
 	      if (th->debug_registers_changed)
 		{
-		  th->wow64_context.Dr0 = dr[0];
-		  th->wow64_context.Dr1 = dr[1];
-		  th->wow64_context.Dr2 = dr[2];
-		  th->wow64_context.Dr3 = dr[3];
+		  th->wow64_context.Dr0 = windows_process.dr[0];
+		  th->wow64_context.Dr1 = windows_process.dr[1];
+		  th->wow64_context.Dr2 = windows_process.dr[2];
+		  th->wow64_context.Dr3 = windows_process.dr[3];
 		  th->wow64_context.Dr6 = DR6_CLEAR_VALUE;
-		  th->wow64_context.Dr7 = dr[7];
+		  th->wow64_context.Dr7 = windows_process.dr[7];
 		  th->debug_registers_changed = false;
 		}
 	      CHECK (Wow64SetThreadContext (th->h, &th->wow64_context));
@@ -1347,12 +1343,12 @@ windows_nat_target::resume (ptid_t ptid, int step, enum gdb_signal sig)
 	    {
 	      if (th->debug_registers_changed)
 		{
-		  th->context.Dr0 = dr[0];
-		  th->context.Dr1 = dr[1];
-		  th->context.Dr2 = dr[2];
-		  th->context.Dr3 = dr[3];
+		  th->context.Dr0 = windows_process.dr[0];
+		  th->context.Dr1 = windows_process.dr[1];
+		  th->context.Dr2 = windows_process.dr[2];
+		  th->context.Dr3 = windows_process.dr[3];
 		  th->context.Dr6 = DR6_CLEAR_VALUE;
-		  th->context.Dr7 = dr[7];
+		  th->context.Dr7 = windows_process.dr[7];
 		  th->debug_registers_changed = false;
 		}
 	      CHECK (SetThreadContext (th->h, &th->context));
@@ -1394,19 +1390,20 @@ ctrl_c_handler (DWORD event_type)
       /* Call DbgUiRemoteBreakin of the 32bit ntdll.dll in the target process.
 	 DebugBreakProcess would call the one of the 64bit ntdll.dll, which
 	 can't be correctly handled by gdb.  */
-      if (wow64_dbgbreak == nullptr)
+      if (windows_process.wow64_dbgbreak == nullptr)
 	{
 	  CORE_ADDR addr;
 	  if (!find_minimal_symbol_address ("ntdll!DbgUiRemoteBreakin",
 					    &addr, 0))
-	    wow64_dbgbreak = (void *) addr;
+	    windows_process.wow64_dbgbreak = (void *) addr;
 	}
 
-      if (wow64_dbgbreak != nullptr)
+      if (windows_process.wow64_dbgbreak != nullptr)
 	{
 	  HANDLE thread = CreateRemoteThread (windows_process.handle, NULL,
 					      0, (LPTHREAD_START_ROUTINE)
-					      wow64_dbgbreak, NULL, 0, NULL);
+					      windows_process.wow64_dbgbreak,
+					      NULL, 0, NULL);
 	  if (thread)
 	    CloseHandle (thread);
 	}
@@ -1463,7 +1460,7 @@ windows_nat_target::get_windows_debug_event (int pid,
 
   event_code = windows_process.current_event.dwDebugEventCode;
   ourstatus->set_spurious ();
-  have_saved_context = 0;
+  windows_process.have_saved_context = 0;
 
   switch (event_code)
     {
@@ -1472,17 +1469,17 @@ windows_nat_target::get_windows_debug_event (int pid,
 		    (unsigned) current_event->dwProcessId,
 		    (unsigned) current_event->dwThreadId,
 		    "CREATE_THREAD_DEBUG_EVENT");
-      if (saw_create != 1)
+      if (windows_process.saw_create != 1)
 	{
 	  inferior *inf = find_inferior_pid (this, current_event->dwProcessId);
-	  if (!saw_create && inf->attach_flag)
+	  if (!windows_process.saw_create && inf->attach_flag)
 	    {
 	      /* Kludge around a Windows bug where first event is a create
 		 thread event.  Caused when attached process does not have
 		 a main thread.  */
 	      thread_id = fake_create_process ();
 	      if (thread_id)
-		saw_create++;
+		windows_process.saw_create++;
 	    }
 	  break;
 	}
@@ -1513,7 +1510,7 @@ windows_nat_target::get_windows_debug_event (int pid,
 		    (unsigned) current_event->dwThreadId,
 		    "CREATE_PROCESS_DEBUG_EVENT");
       CloseHandle (current_event->u.CreateProcessInfo.hFile);
-      if (++saw_create != 1)
+      if (++windows_process.saw_create != 1)
 	break;
 
       windows_process.handle = current_event->u.CreateProcessInfo.hProcess;
@@ -1532,14 +1529,14 @@ windows_nat_target::get_windows_debug_event (int pid,
 		    (unsigned) current_event->dwProcessId,
 		    (unsigned) current_event->dwThreadId,
 		    "EXIT_PROCESS_DEBUG_EVENT");
-      if (!windows_initialization_done)
+      if (!windows_process.windows_initialization_done)
 	{
 	  target_terminal::ours ();
 	  target_mourn_inferior (inferior_ptid);
 	  error (_("During startup program exited with code 0x%x."),
 		 (unsigned int) current_event->u.ExitProcess.dwExitCode);
 	}
-      else if (saw_create == 1)
+      else if (windows_process.saw_create == 1)
 	{
 	  delete_thread (ptid_t (current_event->dwProcessId,
 				 current_event->dwThreadId, 0),
@@ -1566,7 +1563,8 @@ windows_nat_target::get_windows_debug_event (int pid,
 		    (unsigned) current_event->dwThreadId,
 		    "LOAD_DLL_DEBUG_EVENT");
       CloseHandle (current_event->u.LoadDll.hFile);
-      if (saw_create != 1 || ! windows_initialization_done)
+      if (windows_process.saw_create != 1
+	  || ! windows_process.windows_initialization_done)
 	break;
       try
 	{
@@ -1585,7 +1583,8 @@ windows_nat_target::get_windows_debug_event (int pid,
 		    (unsigned) current_event->dwProcessId,
 		    (unsigned) current_event->dwThreadId,
 		    "UNLOAD_DLL_DEBUG_EVENT");
-      if (saw_create != 1 || ! windows_initialization_done)
+      if (windows_process.saw_create != 1
+	  || ! windows_process.windows_initialization_done)
 	break;
       try
 	{
@@ -1604,7 +1603,7 @@ windows_nat_target::get_windows_debug_event (int pid,
 		    (unsigned) current_event->dwProcessId,
 		    (unsigned) current_event->dwThreadId,
 		    "EXCEPTION_DEBUG_EVENT");
-      if (saw_create != 1)
+      if (windows_process.saw_create != 1)
 	break;
       switch (windows_process.handle_exception (ourstatus, debug_exceptions))
 	{
@@ -1626,13 +1625,13 @@ windows_nat_target::get_windows_debug_event (int pid,
 		    (unsigned) current_event->dwProcessId,
 		    (unsigned) current_event->dwThreadId,
 		    "OUTPUT_DEBUG_STRING_EVENT");
-      if (saw_create != 1)
+      if (windows_process.saw_create != 1)
 	break;
       thread_id = windows_process.handle_output_debug_string (ourstatus);
       break;
 
     default:
-      if (saw_create != 1)
+      if (windows_process.saw_create != 1)
 	break;
       gdb_printf ("gdb: kernel event for pid=%u tid=0x%x\n",
 		  (unsigned) current_event->dwProcessId,
@@ -1642,7 +1641,7 @@ windows_nat_target::get_windows_debug_event (int pid,
       break;
     }
 
-  if (!thread_id || saw_create != 1)
+  if (!thread_id || windows_process.saw_create != 1)
     {
       CHECK (windows_continue (continue_status,
 			       windows_process.desired_stop_thread_id, 0));
@@ -1661,7 +1660,7 @@ windows_nat_target::get_windows_debug_event (int pid,
 	       == EXCEPTION_BREAKPOINT)
 	      || (current_event->u.Exception.ExceptionRecord.ExceptionCode
 		  == STATUS_WX86_BREAKPOINT))
-	  && windows_initialization_done)
+	  && windows_process.windows_initialization_done)
 	{
 	  ptid_t ptid = ptid_t (current_event->dwProcessId, thread_id, 0);
 	  windows_thread_info *th
@@ -1747,7 +1746,7 @@ windows_nat_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
 			   == EXCEPTION_BREAKPOINT)
 			  || (windows_process.current_event.u.Exception.ExceptionRecord.ExceptionCode
 			      == STATUS_WX86_BREAKPOINT))
-		      && windows_initialization_done)
+		      && windows_process.windows_initialization_done)
 		    {
 		      th->stopped_at_software_breakpoint = true;
 		      th->pc_adjusted = false;
@@ -1777,9 +1776,11 @@ windows_nat_target::do_initial_windows_stuff (DWORD pid, bool attaching)
   struct inferior *inf;
 
   windows_process.last_sig = GDB_SIGNAL_0;
-  open_process_used = 0;
-  for (i = 0; i < sizeof (dr) / sizeof (dr[0]); i++)
-    dr[i] = 0;
+  windows_process.open_process_used = 0;
+  for (i = 0;
+       i < sizeof (windows_process.dr) / sizeof (windows_process.dr[0]);
+       i++)
+    windows_process.dr[i] = 0;
 #ifdef __CYGWIN__
   cygwin_load_start = cygwin_load_end = 0;
 #endif
@@ -1800,14 +1801,14 @@ windows_nat_target::do_initial_windows_stuff (DWORD pid, bool attaching)
 
   if (!windows_process.wow64_process)
     {
-      windows_set_context_register_offsets (amd64_mappings);
-      windows_set_segment_register_p (amd64_windows_segment_register_p);
+      windows_process.mappings  = amd64_mappings;
+      windows_process.segment_register_p = amd64_windows_segment_register_p;
     }
   else
 #endif
     {
-      windows_set_context_register_offsets (i386_mappings);
-      windows_set_segment_register_p (i386_windows_segment_register_p);
+      windows_process.mappings  = i386_mappings;
+      windows_process.segment_register_p = i386_windows_segment_register_p;
     }
 
   inferior_appeared (inf, pid);
@@ -1816,7 +1817,7 @@ windows_nat_target::do_initial_windows_stuff (DWORD pid, bool attaching)
   target_terminal::init ();
   target_terminal::inferior ();
 
-  windows_initialization_done = 0;
+  windows_process.windows_initialization_done = 0;
 
   ptid_t last_ptid;
 
@@ -1854,7 +1855,7 @@ windows_nat_target::do_initial_windows_stuff (DWORD pid, bool attaching)
      phase, and then process them all in one batch now.  */
   windows_process.add_all_dlls ();
 
-  windows_initialization_done = 1;
+  windows_process.windows_initialization_done = 1;
   return;
 }
 
@@ -1923,7 +1924,7 @@ windows_nat_target::attach (const char *args, int from_tty)
 
   windows_init_thread_list ();
   ok = DebugActiveProcess (pid);
-  saw_create = 0;
+  windows_process.saw_create = 0;
 
 #ifdef __CYGWIN__
   if (!ok)
@@ -2790,9 +2791,9 @@ windows_nat_target::create_inferior (const char *exec_file,
   CloseHandle (pi.hProcess);
 
   if (useshell && shell[0] != '\0')
-    saw_create = -1;
+    windows_process.saw_create = -1;
   else
-    saw_create = 0;
+    windows_process.saw_create = 0;
 
   do_initial_windows_stuff (pi.dwProcessId, 0);
 
@@ -2804,10 +2805,10 @@ windows_nat_target::mourn_inferior ()
 {
   (void) windows_continue (DBG_CONTINUE, -1, 0);
   x86_cleanup_dregs();
-  if (open_process_used)
+  if (windows_process.open_process_used)
     {
       CHECK (CloseHandle (windows_process.handle));
-      open_process_used = 0;
+      windows_process.open_process_used = 0;
     }
   windows_process.siginfo_er.ExceptionCode = 0;
   inf_child_target::mourn_inferior ();
@@ -2915,7 +2916,7 @@ windows_xfer_shared_libraries (struct target_ops *ops,
     return TARGET_XFER_E_IO;
 
   obstack_grow_str (&obstack, "<library-list>\n");
-  for (windows_solib &so : solibs)
+  for (windows_solib &so : windows_process.solibs)
     windows_xfer_shared_library (so.name.c_str (),
 				 (CORE_ADDR) (uintptr_t) so.load_addr,
 				 &so.text_offset,
@@ -3165,9 +3166,9 @@ cygwin_set_dr (int i, CORE_ADDR addr)
   if (i < 0 || i > 3)
     internal_error (__FILE__, __LINE__,
 		    _("Invalid register %d in cygwin_set_dr.\n"), i);
-  dr[i] = addr;
+  windows_process.dr[i] = addr;
 
-  for (auto &th : thread_list)
+  for (auto &th : windows_process.thread_list)
     th->debug_registers_changed = true;
 }
 
@@ -3177,9 +3178,9 @@ cygwin_set_dr (int i, CORE_ADDR addr)
 static void
 cygwin_set_dr7 (unsigned long val)
 {
-  dr[7] = (CORE_ADDR) val;
+  windows_process.dr[7] = (CORE_ADDR) val;
 
-  for (auto &th : thread_list)
+  for (auto &th : windows_process.thread_list)
     th->debug_registers_changed = true;
 }
 
@@ -3188,7 +3189,7 @@ cygwin_set_dr7 (unsigned long val)
 static CORE_ADDR
 cygwin_get_dr (int i)
 {
-  return dr[i];
+  return windows_process.dr[i];
 }
 
 /* Get the value of the DR6 debug status register from the inferior.
@@ -3197,7 +3198,7 @@ cygwin_get_dr (int i)
 static unsigned long
 cygwin_get_dr6 (void)
 {
-  return (unsigned long) dr[6];
+  return (unsigned long) windows_process.dr[6];
 }
 
 /* Get the value of the DR7 debug status register from the inferior.
@@ -3207,7 +3208,7 @@ cygwin_get_dr6 (void)
 static unsigned long
 cygwin_get_dr7 (void)
 {
-  return (unsigned long) dr[7];
+  return (unsigned long) windows_process.dr[7];
 }
 
 /* Determine if the thread referenced by "ptid" is alive
diff --git a/gdbserver/win32-low.cc b/gdbserver/win32-low.cc
index 8437c69e1cc..3bad1dd8831 100644
--- a/gdbserver/win32-low.cc
+++ b/gdbserver/win32-low.cc
@@ -38,7 +38,40 @@
 
 using namespace windows_nat;
 
-static windows_process_info windows_process;
+struct gdbserver_windows_process : public windows_process_info
+{
+  windows_thread_info *thread_rec (ptid_t ptid,
+				   thread_disposition_type disposition) override;
+  int handle_output_debug_string (struct target_waitstatus *ourstatus) override;
+  void handle_load_dll (const char *dll_name, LPVOID base) override;
+  void handle_unload_dll () override;
+  bool handle_ms_vc_exception (const EXCEPTION_RECORD *rec) override;
+  bool handle_access_violation (const EXCEPTION_RECORD *rec) override;
+
+  int attaching = 0;
+
+  /* A status that hasn't been reported to the core yet, and so
+     win32_wait should return it next, instead of fetching the next
+     debug event off the win32 API.  */
+  struct target_waitstatus cached_status;
+
+  /* Non zero if an interrupt request is to be satisfied by suspending
+     all threads.  */
+  int soft_interrupt_requested = 0;
+
+  /* Non zero if the inferior is stopped in a simulated breakpoint done
+     by suspending all the threads.  */
+  int faked_breakpoint = 0;
+
+  /* True if current_process_handle needs to be closed.  */
+  bool open_process_used = false;
+
+  /* Zero during the child initialization phase, and nonzero
+     otherwise.  */
+  int child_initialization_done = 0;
+};
+
+static gdbserver_windows_process windows_process;
 
 #ifndef USE_WIN32API
 #include <sys/cygwin.h>
@@ -66,25 +99,6 @@ static windows_process_info windows_process;
 
 int using_threads = 1;
 
-/* Globals.  */
-static int attaching = 0;
-
-/* A status that hasn't been reported to the core yet, and so
-   win32_wait should return it next, instead of fetching the next
-   debug event off the win32 API.  */
-static struct target_waitstatus cached_status;
-
-/* Non zero if an interrupt request is to be satisfied by suspending
-   all threads.  */
-static int soft_interrupt_requested = 0;
-
-/* Non zero if the inferior is stopped in a simulated breakpoint done
-   by suspending all the threads.  */
-static int faked_breakpoint = 0;
-
-/* True if current_process_handle needs to be closed.  */
-static bool open_process_used = false;
-
 const struct target_desc *win32_tdesc;
 #ifdef __x86_64__
 const struct target_desc *wow64_win32_tdesc;
@@ -165,7 +179,7 @@ win32_require_context (windows_thread_info *th)
 /* See nat/windows-nat.h.  */
 
 windows_thread_info *
-windows_nat::windows_process_info::thread_rec
+gdbserver_windows_process::thread_rec
      (ptid_t ptid, thread_disposition_type disposition)
 {
   thread_info *thread = find_thread_ptid (ptid);
@@ -325,10 +339,6 @@ child_init_thread_list (void)
   for_each_thread (delete_thread_info);
 }
 
-/* Zero during the child initialization phase, and nonzero otherwise.  */
-
-static int child_initialization_done = 0;
-
 static void
 do_initial_child_stuff (HANDLE proch, DWORD pid, int attached)
 {
@@ -339,9 +349,9 @@ do_initial_child_stuff (HANDLE proch, DWORD pid, int attached)
   windows_process.id = pid;
   windows_process.main_thread_id = 0;
 
-  soft_interrupt_requested = 0;
-  faked_breakpoint = 0;
-  open_process_used = true;
+  windows_process.soft_interrupt_requested = 0;
+  windows_process.faked_breakpoint = 0;
+  windows_process.open_process_used = true;
 
   memset (&windows_process.current_event, 0,
 	  sizeof (windows_process.current_event));
@@ -372,12 +382,12 @@ do_initial_child_stuff (HANDLE proch, DWORD pid, int attached)
 #endif
     proc->tdesc = win32_tdesc;
   child_init_thread_list ();
-  child_initialization_done = 0;
+  windows_process.child_initialization_done = 0;
 
   if (the_low_target.initial_stuff != NULL)
     (*the_low_target.initial_stuff) ();
 
-  cached_status.set_ignore ();
+  windows_process.cached_status.set_ignore ();
 
   /* Flush all currently pending debug events (thread and dll list) up
      to the initial breakpoint.  */
@@ -390,7 +400,7 @@ do_initial_child_stuff (HANDLE proch, DWORD pid, int attached)
       /* Note win32_wait doesn't return thread events.  */
       if (status.kind () != TARGET_WAITKIND_LOADED)
 	{
-	  cached_status = status;
+	  windows_process.cached_status = status;
 	  break;
 	}
 
@@ -422,7 +432,7 @@ do_initial_child_stuff (HANDLE proch, DWORD pid, int attached)
      phase, and then process them all in one batch now.  */
   windows_process.add_all_dlls ();
 
-  child_initialization_done = 1;
+  windows_process.child_initialization_done = 1;
 }
 
 /* Resume all artificially suspended threads if we are continuing
@@ -469,7 +479,7 @@ child_continue (DWORD continue_status, int thread_id)
     {
       continue_one_thread (thread, thread_id);
     });
-  faked_breakpoint = 0;
+  windows_process.faked_breakpoint = 0;
 
   return continue_last_debug_event (continue_status, debug_threads);
 }
@@ -616,7 +626,7 @@ win32_process_target::create_inferior (const char *program,
   char *args = (char *) str_program_args.c_str ();
 
   /* win32_wait needs to know we're not attaching.  */
-  attaching = 0;
+  windows_process.attaching = 0;
 
   if (!program)
     error ("No executable specified, specify executable to debug.\n");
@@ -701,7 +711,7 @@ win32_process_target::attach (unsigned long pid)
 	  DebugSetProcessKillOnExit (FALSE);
 
 	  /* win32_wait needs to know we're attaching.  */
-	  attaching = 1;
+	  windows_process.attaching = 1;
 	  do_initial_child_stuff (h, pid, 1);
 	  return 0;
 	}
@@ -717,7 +727,7 @@ win32_process_target::attach (unsigned long pid)
 /* See nat/windows-nat.h.  */
 
 int
-windows_nat::windows_process_info::handle_output_debug_string
+gdbserver_windows_process::handle_output_debug_string
      (struct target_waitstatus *ourstatus)
 {
 #define READ_BUFFER_LEN 1024
@@ -766,10 +776,10 @@ windows_nat::windows_process_info::handle_output_debug_string
 static void
 win32_clear_inferiors (void)
 {
-  if (open_process_used)
+  if (windows_process.open_process_used)
     {
       CloseHandle (windows_process.handle);
-      open_process_used = false;
+      windows_process.open_process_used = false;
     }
 
   for_each_thread (delete_thread_info);
@@ -947,8 +957,7 @@ win32_process_target::resume (thread_resume *resume_info, size_t n)
 /* See nat/windows-nat.h.  */
 
 void
-windows_nat::windows_process_info::handle_load_dll (const char *name,
-						    LPVOID base)
+gdbserver_windows_process::handle_load_dll (const char *name, LPVOID base)
 {
   CORE_ADDR load_addr = (CORE_ADDR) (uintptr_t) base;
 
@@ -1002,7 +1011,7 @@ windows_nat::windows_process_info::handle_load_dll (const char *name,
 /* See nat/windows-nat.h.  */
 
 void
-windows_nat::windows_process_info::handle_unload_dll ()
+gdbserver_windows_process::handle_unload_dll ()
 {
   CORE_ADDR load_addr =
 	  (CORE_ADDR) (uintptr_t) current_event.u.UnloadDll.lpBaseOfDll;
@@ -1027,7 +1036,7 @@ fake_breakpoint_event (void)
 {
   OUTMSG2(("fake_breakpoint_event\n"));
 
-  faked_breakpoint = 1;
+  windows_process.faked_breakpoint = 1;
 
   memset (&windows_process.current_event, 0,
 	  sizeof (windows_process.current_event));
@@ -1042,7 +1051,7 @@ fake_breakpoint_event (void)
 /* See nat/windows-nat.h.  */
 
 bool
-windows_nat::windows_process_info::handle_ms_vc_exception
+gdbserver_windows_process::handle_ms_vc_exception
      (const EXCEPTION_RECORD *rec)
 {
   return false;
@@ -1051,7 +1060,7 @@ windows_nat::windows_process_info::handle_ms_vc_exception
 /* See nat/windows-nat.h.  */
 
 bool
-windows_nat::windows_process_info::handle_access_violation
+gdbserver_windows_process::handle_access_violation
      (const EXCEPTION_RECORD *rec)
 {
   return false;
@@ -1077,7 +1086,7 @@ maybe_adjust_pc ()
 	   == EXCEPTION_BREAKPOINT)
 	  || (windows_process.current_event.u.Exception.ExceptionRecord.ExceptionCode
 	      == STATUS_WX86_BREAKPOINT))
-      && child_initialization_done)
+      && windows_process.child_initialization_done)
     {
       th->stopped_at_software_breakpoint = true;
       CORE_ADDR pc = regcache_read_pc (regcache);
@@ -1103,14 +1112,14 @@ get_child_debug_event (DWORD *continue_status,
 
   DEBUG_EVENT *current_event = &windows_process.current_event;
 
-  if (soft_interrupt_requested)
+  if (windows_process.soft_interrupt_requested)
     {
-      soft_interrupt_requested = 0;
+      windows_process.soft_interrupt_requested = 0;
       fake_breakpoint_event ();
       goto gotevent;
     }
 
-  attaching = 0;
+  windows_process.attaching = 0;
   {
     gdb::optional<pending_stop> stop
       = windows_process.fetch_pending_stop (debug_threads);
@@ -1179,10 +1188,10 @@ get_child_debug_event (DWORD *continue_status,
 		(unsigned) current_event->dwThreadId));
       CloseHandle (current_event->u.CreateProcessInfo.hFile);
 
-      if (open_process_used)
+      if (windows_process.open_process_used)
 	{
 	  CloseHandle (windows_process.handle);
-	  open_process_used = false;
+	  windows_process.open_process_used = false;
 	}
 
       windows_process.handle = current_event->u.CreateProcessInfo.hProcess;
@@ -1221,7 +1230,7 @@ get_child_debug_event (DWORD *continue_status,
 		(unsigned) current_event->dwProcessId,
 		(unsigned) current_event->dwThreadId));
       CloseHandle (current_event->u.LoadDll.hFile);
-      if (! child_initialization_done)
+      if (! windows_process.child_initialization_done)
 	break;
       windows_process.dll_loaded_event ();
 
@@ -1233,7 +1242,7 @@ get_child_debug_event (DWORD *continue_status,
 		"for pid=%u tid=%x\n",
 		(unsigned) current_event->dwProcessId,
 		(unsigned) current_event->dwThreadId));
-      if (! child_initialization_done)
+      if (! windows_process.child_initialization_done)
 	break;
       windows_process.handle_unload_dll ();
       ourstatus->set_loaded ();
@@ -1295,14 +1304,14 @@ ptid_t
 win32_process_target::wait (ptid_t ptid, target_waitstatus *ourstatus,
 			    target_wait_flags options)
 {
-  if (cached_status.kind () != TARGET_WAITKIND_IGNORE)
+  if (windows_process.cached_status.kind () != TARGET_WAITKIND_IGNORE)
     {
       /* The core always does a wait after creating the inferior, and
 	 do_initial_child_stuff already ran the inferior to the
 	 initial breakpoint (or an exit, if creating the process
 	 fails).  Report it now.  */
-      *ourstatus = cached_status;
-      cached_status.set_ignore ();
+      *ourstatus = windows_process.cached_status;
+      windows_process.cached_status.set_ignore ();
       return debug_event_ptid (&windows_process.current_event);
     }
 
@@ -1394,7 +1403,7 @@ win32_process_target::request_interrupt ()
     return;
 
   /* Last resort, suspend all threads manually.  */
-  soft_interrupt_requested = 1;
+  windows_process.soft_interrupt_requested = 1;
 }
 
 bool
-- 
2.34.1


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 0/2] More Windows globals cleanups
  2022-04-07 19:56 [PATCH 0/2] More Windows globals cleanups Tom Tromey
  2022-04-07 19:56 ` [PATCH 1/2] Turn some windows-nat.c static functions into methods Tom Tromey
  2022-04-07 19:56 ` [PATCH 2/2] Use subclasses of windows_process_info Tom Tromey
@ 2022-06-07 18:15 ` Tom Tromey
  2 siblings, 0 replies; 7+ messages in thread
From: Tom Tromey @ 2022-06-07 18:15 UTC (permalink / raw)
  To: Tom Tromey via Gdb-patches; +Cc: Tom Tromey

>>>>> "Tom" == Tom Tromey via Gdb-patches <gdb-patches@sourceware.org> writes:

Tom> This short series moves more globals from windows-nat into a
Tom> structure.  This is more preparation for multi-inferior.  (Note I
Tom> haven't implemented multi-inferior, this is just preparation in case
Tom> we do.)

Tom> This only partially converts gdbserver.  The x86 back end still has
Tom> some globals, and I didn't try to fix this.

Tom> I regression tested this using the internal AdaCore test suite.

I've rebased this and I am checking it in now.

Tom

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH] Fix Cygwin build after 20489cca
  2022-04-07 19:56 ` [PATCH 2/2] Use subclasses of windows_process_info Tom Tromey
@ 2022-06-12 16:27   ` Jon Turney
  2022-11-02 14:39     ` Jon Turney
  2022-06-12 16:28   ` [PATCH 2/2] Use subclasses of windows_process_info Jon Turney
  1 sibling, 1 reply; 7+ messages in thread
From: Jon Turney @ 2022-06-12 16:27 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey, Jon Turney

Update code under __CYGWIN__ which accesses inferior process information
which is now stored in windows_process_info rather than globals.
---
 gdb/windows-nat.c | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c
index 9705fa33cc2..553b9ba45ce 100644
--- a/gdb/windows-nat.c
+++ b/gdb/windows-nat.c
@@ -553,15 +553,15 @@ windows_nat_target::fetch_registers (struct regcache *regcache, int r)
   if (th->reload_context)
     {
 #ifdef __CYGWIN__
-      if (have_saved_context)
+      if (windows_process.have_saved_context)
 	{
 	  /* Lie about where the program actually is stopped since
 	     cygwin has informed us that we should consider the signal
 	     to have occurred at another location which is stored in
 	     "saved_context.  */
-	  memcpy (&th->context, &saved_context,
+	  memcpy (&th->context, &windows_process.saved_context,
 		  __COPY_CONTEXT_SIZE);
-	  have_saved_context = 0;
+	  windows_process.have_saved_context = 0;
 	}
       else
 #endif
@@ -749,9 +749,10 @@ windows_make_so (const char *name, LPVOID load_addr)
       /* The symbols in a dll are offset by 0x1000, which is the
 	 offset from 0 of the first byte in an image - because of the
 	 file header and the section alignment.  */
-      cygwin_load_start = (CORE_ADDR) (uintptr_t) ((char *)
-						   load_addr + 0x1000);
-      cygwin_load_end = cygwin_load_start + bfd_section_size (text);
+      windows_process.cygwin_load_start = (CORE_ADDR) (uintptr_t) ((char *)
+								   load_addr + 0x1000);
+      windows_process.cygwin_load_end = windows_process.cygwin_load_start +
+	bfd_section_size (text);
     }
 #endif
 
@@ -1731,7 +1732,8 @@ windows_nat_target::do_initial_windows_stuff (DWORD pid, bool attaching)
        i++)
     windows_process.dr[i] = 0;
 #ifdef __CYGWIN__
-  cygwin_load_start = cygwin_load_end = 0;
+  windows_process.cygwin_load_start = 0;
+  windows_process.cygwin_load_end = 0;
 #endif
   windows_process.current_event.dwProcessId = pid;
   memset (&windows_process.current_event, 0,
-- 
2.36.1


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 2/2] Use subclasses of windows_process_info
  2022-04-07 19:56 ` [PATCH 2/2] Use subclasses of windows_process_info Tom Tromey
  2022-06-12 16:27   ` [PATCH] Fix Cygwin build after 20489cca Jon Turney
@ 2022-06-12 16:28   ` Jon Turney
  1 sibling, 0 replies; 7+ messages in thread
From: Jon Turney @ 2022-06-12 16:28 UTC (permalink / raw)
  To: Tom Tromey, gdb-patches

On 07/04/2022 20:56, Tom Tromey via Gdb-patches wrote:
> This changes windows_process_info to use virtual methods for its
> callbacks, and then changes the two clients of this code to subclass
> this class to implement the methods.
> 
> I considered using CRTP here, but that would require making the new
> structures visible to the compilation of of nat/windows-nat.c.  This
> seemed like a bit of a pain, so I didn't do it.
> 
> This change then lets us change all the per-inferior globals to be
> members of the new subclass.  Note that there can still only be a
> single inferior -- currently there's a single global of the new type.
> This is just another step toward possibly implementing multi-inferior
> for Windows.
> 
> It's possible this could be cleaned up further... ideally I'd like to
> move more of the data into the base class.  However, because gdb
> supports Cygwin and gdbserver dose not, and because I don't have a way
> to build or test Cygwin, larger refactorings are difficult.

Understandably, without that capability, this change breaks building on 
Cygwin. I've sent a patch to fix that.

If you explain what the difficulties are with building for and testing 
on Cygwin are, I may be able help you.


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] Fix Cygwin build after 20489cca
  2022-06-12 16:27   ` [PATCH] Fix Cygwin build after 20489cca Jon Turney
@ 2022-11-02 14:39     ` Jon Turney
  0 siblings, 0 replies; 7+ messages in thread
From: Jon Turney @ 2022-11-02 14:39 UTC (permalink / raw)
  To: gdb-patches

On 12/06/2022 17:27, Jon Turney wrote:
> Update code under __CYGWIN__ which accesses inferior process information
> which is now stored in windows_process_info rather than globals.
> ---
>   gdb/windows-nat.c | 16 +++++++++-------
>   1 file changed, 9 insertions(+), 7 deletions(-)
I applied this as obvious.

(sorry about forgetting about it for several months!)


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2022-11-02 14:39 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-04-07 19:56 [PATCH 0/2] More Windows globals cleanups Tom Tromey
2022-04-07 19:56 ` [PATCH 1/2] Turn some windows-nat.c static functions into methods Tom Tromey
2022-04-07 19:56 ` [PATCH 2/2] Use subclasses of windows_process_info Tom Tromey
2022-06-12 16:27   ` [PATCH] Fix Cygwin build after 20489cca Jon Turney
2022-11-02 14:39     ` Jon Turney
2022-06-12 16:28   ` [PATCH 2/2] Use subclasses of windows_process_info Jon Turney
2022-06-07 18:15 ` [PATCH 0/2] More Windows globals cleanups Tom Tromey

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).