]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Reduce WOW64 code duplication
authorHannes Domani <ssbssa@yahoo.de>
Fri, 6 Dec 2024 13:04:00 +0000 (14:04 +0100)
committerHannes Domani <ssbssa@yahoo.de>
Fri, 6 Dec 2024 13:04:04 +0000 (14:04 +0100)
Currently we have duplicate code for each place where
windows_thread_info::context is touched, since for WOW64 processes
it has to do the equivalent with wow64_context instead.

For example this code...:

 #ifdef __x86_64__
   if (windows_process.wow64_process)
     {
       th->wow64_context.ContextFlags = WOW64_CONTEXT_ALL;
       CHECK (Wow64GetThreadContext (th->h, &th->wow64_context));
       ...
     }
   else
 #endif
     {
       th->context.ContextFlags = CONTEXT_DEBUGGER_DR;
       CHECK (GetThreadContext (th->h, &th->context));
       ...
     }

...changes to look like this instead:

   windows_process.with_context (th, [&] (auto *context)
     {
       context->ContextFlags = WindowsContext<decltype(context)>::all;
       CHECK (get_thread_context (th->h, context));
       ...
     }

The actual choice if context or wow64_context are used, is handled by
this new function in windows_process_info:

   template<typename Function>
   auto with_context (windows_thread_info *th, Function function)
   {
 #ifdef __x86_64__
     if (wow64_process)
       return function (th != nullptr ? th->wow64_context : nullptr);
     else
 #endif
       return function (th != nullptr ? th->context : nullptr);
   }

The other parts to make this work are the templated WindowsContext class
which give the appropriate ContextFlags for both types.
And there are also overloaded helper functions, like in the case of
get_thread_context here, call either GetThreadContext or
Wow64GetThreadContext.

According git log --stat, this results in 120 lines less code.

Approved-By: Tom Tromey <tom@tromey.com>
gdb/nat/windows-nat.c
gdb/nat/windows-nat.h
gdb/windows-nat.c
gdbserver/win32-i386-low.cc
gdbserver/win32-low.cc

index f9f6848861d3543cf794b1a77b74b78927faddef..6f1ce81c59b44efc01a2ae39a137dd3acb8fc6ae 100644 (file)
@@ -172,23 +172,13 @@ windows_process_info::get_exec_module_filename (char *exe_name_ret,
   DWORD cbNeeded;
 
   cbNeeded = 0;
-#ifdef __x86_64__
-  if (wow64_process)
-    {
-      if (!EnumProcessModulesEx (handle,
-                                &dh_buf, sizeof (HMODULE), &cbNeeded,
-                                LIST_MODULES_32BIT)
-         || !cbNeeded)
-       return 0;
-    }
-  else
-#endif
+  BOOL ret = with_context (nullptr, [&] (auto *context)
     {
-      if (!EnumProcessModules (handle,
-                              &dh_buf, sizeof (HMODULE), &cbNeeded)
-         || !cbNeeded)
-       return 0;
-    }
+      return enum_process_modules (context, handle, &dh_buf,
+                                  sizeof (HMODULE), &cbNeeded);
+    });
+  if (!ret || !cbNeeded)
+    return 0;
 
   /* We know the executable is always first in the list of modules,
      which we just fetched.  So no need to fetch more.  */
@@ -523,41 +513,22 @@ windows_process_info::add_dll (LPVOID load_addr)
   HMODULE *hmodules;
   int i;
 
-#ifdef __x86_64__
-  if (wow64_process)
+  BOOL ret = with_context (nullptr, [&] (auto *context)
     {
-      if (EnumProcessModulesEx (handle, &dummy_hmodule,
-                               sizeof (HMODULE), &cb_needed,
-                               LIST_MODULES_32BIT) == 0)
-       return;
-    }
-  else
-#endif
-    {
-      if (EnumProcessModules (handle, &dummy_hmodule,
-                             sizeof (HMODULE), &cb_needed) == 0)
-       return;
-    }
-
-  if (cb_needed < 1)
+      return enum_process_modules (context, handle, &dummy_hmodule,
+                                  sizeof (HMODULE), &cb_needed);
+    });
+  if (!ret || cb_needed < 1)
     return;
 
   hmodules = (HMODULE *) alloca (cb_needed);
-#ifdef __x86_64__
-  if (wow64_process)
+  ret = with_context (nullptr, [&] (auto *context)
     {
-      if (EnumProcessModulesEx (handle, hmodules,
-                               cb_needed, &cb_needed,
-                               LIST_MODULES_32BIT) == 0)
-       return;
-    }
-  else
-#endif
-    {
-      if (EnumProcessModules (handle, hmodules,
-                             cb_needed, &cb_needed) == 0)
-       return;
-    }
+      return enum_process_modules (context, handle, hmodules,
+                                  cb_needed, &cb_needed);
+    });
+  if (!ret)
+    return;
 
   char system_dir[MAX_PATH];
   char syswow_dir[MAX_PATH];
index f2b5d777016cd817bb20157bd083176995feba23..dc637d4ed048b8d7affa240c633e0a4ac71832d9 100644 (file)
 #define STATUS_WX86_BREAKPOINT 0x4000001F
 #define STATUS_WX86_SINGLE_STEP 0x4000001E
 
+#ifndef CONTEXT_EXTENDED_REGISTERS
+/* This macro is only defined on ia32.  It only makes sense on this target,
+   so define it as zero if not already defined.  */
+#define CONTEXT_EXTENDED_REGISTERS 0
+#endif
+
 namespace windows_nat
 {
 
@@ -250,6 +256,25 @@ struct windows_process_info
 
   const char *pid_to_exec_file (int);
 
+  template<typename Function>
+  auto with_context (windows_thread_info *th, Function function)
+  {
+#ifdef __x86_64__
+    if (wow64_process)
+      return function (th != nullptr ? &th->wow64_context : nullptr);
+    else
+#endif
+      return function (th != nullptr ? &th->context : nullptr);
+  }
+
+  DWORD *context_flags_ptr (windows_thread_info *th)
+  {
+    return with_context (th, [] (auto *context)
+      {
+       return &context->ContextFlags;
+      });
+  }
+
 private:
 
   /* Handle MS_VC_EXCEPTION when processing a stop.  MS_VC_EXCEPTION is
@@ -433,6 +458,98 @@ extern DeleteProcThreadAttributeList_ftype *DeleteProcThreadAttributeList;
 
 extern bool disable_randomization_available ();
 
+/* Helper classes to get the correct ContextFlags values based on the
+   used type (CONTEXT or WOW64_CONTEXT).  */
+
+template<typename Context>
+struct WindowsContext;
+
+template<>
+struct WindowsContext<CONTEXT *>
+{
+  static constexpr DWORD control  = CONTEXT_CONTROL;
+  static constexpr DWORD floating = CONTEXT_FLOATING_POINT;
+  static constexpr DWORD debug    = CONTEXT_DEBUG_REGISTERS;
+  static constexpr DWORD extended = CONTEXT_EXTENDED_REGISTERS;
+  static constexpr DWORD full    = CONTEXT_FULL;
+  static constexpr DWORD all     = (CONTEXT_FULL
+                                    | CONTEXT_FLOATING_POINT
+                                    | CONTEXT_SEGMENTS
+                                    | CONTEXT_DEBUG_REGISTERS
+                                    | CONTEXT_EXTENDED_REGISTERS);
+};
+
+#ifdef __x86_64__
+template<>
+struct WindowsContext<WOW64_CONTEXT *>
+{
+  static constexpr DWORD control  = WOW64_CONTEXT_CONTROL;
+  static constexpr DWORD floating = WOW64_CONTEXT_FLOATING_POINT;
+  static constexpr DWORD debug   = WOW64_CONTEXT_DEBUG_REGISTERS;
+  static constexpr DWORD extended = WOW64_CONTEXT_EXTENDED_REGISTERS;
+  static constexpr DWORD full    = WOW64_CONTEXT_FULL;
+  static constexpr DWORD all     = WOW64_CONTEXT_ALL;
+};
+#endif
+
+/* Overloaded helper functions to call the correct function based on the used
+   type (CONTEXT or WOW64_CONTEXT).  */
+
+static inline BOOL
+get_thread_context (HANDLE h, CONTEXT *context)
+{
+  return GetThreadContext (h, context);
+}
+
+static inline BOOL
+set_thread_context (HANDLE h, CONTEXT *context)
+{
+  return SetThreadContext (h, context);
+}
+
+static inline BOOL
+get_thread_selector_entry (CONTEXT *, HANDLE thread, DWORD sel,
+                          LDT_ENTRY *info)
+{
+  return GetThreadSelectorEntry (thread, sel, info);
+}
+
+static inline BOOL
+enum_process_modules (CONTEXT *, HANDLE process,
+                     HMODULE *modules, DWORD size, LPDWORD needed)
+{
+  return EnumProcessModules (process, modules, size, needed);
+}
+
+#ifdef __x86_64__
+static inline BOOL
+get_thread_context (HANDLE h, WOW64_CONTEXT *context)
+{
+  return Wow64GetThreadContext (h, context);
+}
+
+static inline BOOL
+set_thread_context (HANDLE h, WOW64_CONTEXT *context)
+{
+  return Wow64SetThreadContext (h, context);
+}
+
+static inline BOOL
+get_thread_selector_entry (WOW64_CONTEXT *, HANDLE thread, DWORD sel,
+                          LDT_ENTRY *info)
+{
+  return Wow64GetThreadSelectorEntry (thread, sel, info);
+}
+
+static inline BOOL
+enum_process_modules (WOW64_CONTEXT *, HANDLE process,
+                     HMODULE *modules, DWORD size, LPDWORD needed)
+{
+  return EnumProcessModulesEx (process, modules, size, needed,
+                              LIST_MODULES_32BIT);
+}
+#endif
+
 /* Load any functions which may not be available in ancient versions
    of Windows.  */
 
index abacafe7af8e48e7c7cb98a464b6314feb0c7f34..f2d0633b32fdb359053ba5971f82db94da7c1350 100644 (file)
@@ -166,16 +166,6 @@ enum
   };
 #endif
 
-#ifndef CONTEXT_EXTENDED_REGISTERS
-/* This macro is only defined on ia32.  It only makes sense on this target,
-   so define it as zero if not already defined.  */
-#define CONTEXT_EXTENDED_REGISTERS 0
-#endif
-
-#define CONTEXT_DEBUGGER_DR CONTEXT_FULL | CONTEXT_FLOATING_POINT \
-       | CONTEXT_SEGMENTS | CONTEXT_DEBUG_REGISTERS \
-       | CONTEXT_EXTENDED_REGISTERS
-
 #define DR6_CLEAR_VALUE 0xffff0ff0
 
 /* The string sent by cygwin when it processes a signal.
@@ -657,11 +647,10 @@ windows_fetch_one_register (struct regcache *regcache,
   gdb_assert (r >= 0);
   gdb_assert (!th->reload_context);
 
-  char *context_ptr = (char *) &th->context;
-#ifdef __x86_64__
-  if (windows_process.wow64_process)
-    context_ptr = (char *) &th->wow64_context;
-#endif
+  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 ();
@@ -727,42 +716,24 @@ windows_nat_target::fetch_registers (struct regcache *regcache, int r)
 
   if (th->reload_context)
     {
-#ifdef __x86_64__
-      if (windows_process.wow64_process)
+      windows_process.with_context (th, [&] (auto *context)
        {
-         th->wow64_context.ContextFlags = WOW64_CONTEXT_ALL;
-         CHECK (Wow64GetThreadContext (th->h, &th->wow64_context));
+         context->ContextFlags = WindowsContext<decltype(context)>::all;
+         CHECK (get_thread_context (th->h, context));
          /* Copy dr values from that thread.
             But only if there were not modified since last stop.
             PR gdb/2388 */
          if (!th->debug_registers_changed)
            {
-             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;
+             windows_process.dr[0] = context->Dr0;
+             windows_process.dr[1] = context->Dr1;
+             windows_process.dr[2] = context->Dr2;
+             windows_process.dr[3] = context->Dr3;
+             windows_process.dr[6] = context->Dr6;
+             windows_process.dr[7] = context->Dr7;
            }
-       }
-      else
-#endif
-       {
-         th->context.ContextFlags = CONTEXT_DEBUGGER_DR;
-         CHECK (GetThreadContext (th->h, &th->context));
-         /* Copy dr values from that thread.
-            But only if there were not modified since last stop.
-            PR gdb/2388 */
-         if (!th->debug_registers_changed)
-           {
-             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;
     }
 
@@ -785,11 +756,10 @@ windows_store_one_register (const struct regcache *regcache,
 {
   gdb_assert (r >= 0);
 
-  char *context_ptr = (char *) &th->context;
-#ifdef __x86_64__
-  if (windows_process.wow64_process)
-    context_ptr = (char *) &th->wow64_context;
-#endif
+  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);
@@ -1086,13 +1056,10 @@ static int
 display_selector (HANDLE thread, DWORD sel)
 {
   LDT_ENTRY info;
-  BOOL ret;
-#ifdef __x86_64__
-  if (windows_process.wow64_process)
-    ret = Wow64GetThreadSelectorEntry (thread, sel, &info);
-  else
-#endif
-    ret = GetThreadSelectorEntry (thread, sel, &info);
+  BOOL ret = windows_process.with_context (nullptr, [&] (auto *context)
+    {
+      return get_thread_selector_entry (context, thread, sel, &info);
+    });
   if (ret)
     {
       int base, limit;
@@ -1181,50 +1148,21 @@ display_selectors (const char * args, int from_tty)
 
   if (!args)
     {
-#ifdef __x86_64__
-      if (windows_process.wow64_process)
-       {
-         gdb_puts ("Selector $cs\n");
-         display_selector (current_windows_thread->h,
-                           current_windows_thread->wow64_context.SegCs);
-         gdb_puts ("Selector $ds\n");
-         display_selector (current_windows_thread->h,
-                           current_windows_thread->wow64_context.SegDs);
-         gdb_puts ("Selector $es\n");
-         display_selector (current_windows_thread->h,
-                           current_windows_thread->wow64_context.SegEs);
-         gdb_puts ("Selector $ss\n");
-         display_selector (current_windows_thread->h,
-                           current_windows_thread->wow64_context.SegSs);
-         gdb_puts ("Selector $fs\n");
-         display_selector (current_windows_thread->h,
-                           current_windows_thread->wow64_context.SegFs);
-         gdb_puts ("Selector $gs\n");
-         display_selector (current_windows_thread->h,
-                           current_windows_thread->wow64_context.SegGs);
-       }
-      else
-#endif
+      windows_process.with_context (current_windows_thread, [&] (auto *context)
        {
          gdb_puts ("Selector $cs\n");
-         display_selector (current_windows_thread->h,
-                           current_windows_thread->context.SegCs);
+         display_selector (current_windows_thread->h, context->SegCs);
          gdb_puts ("Selector $ds\n");
-         display_selector (current_windows_thread->h,
-                           current_windows_thread->context.SegDs);
+         display_selector (current_windows_thread->h, context->SegDs);
          gdb_puts ("Selector $es\n");
-         display_selector (current_windows_thread->h,
-                           current_windows_thread->context.SegEs);
+         display_selector (current_windows_thread->h, context->SegEs);
          gdb_puts ("Selector $ss\n");
-         display_selector (current_windows_thread->h,
-                           current_windows_thread->context.SegSs);
+         display_selector (current_windows_thread->h, context->SegSs);
          gdb_puts ("Selector $fs\n");
-         display_selector (current_windows_thread->h,
-                           current_windows_thread->context.SegFs);
+         display_selector (current_windows_thread->h, context->SegFs);
          gdb_puts ("Selector $gs\n");
-         display_selector (current_windows_thread->h,
-                           current_windows_thread->context.SegGs);
-       }
+         display_selector (current_windows_thread->h, context->SegGs);
+       });
     }
   else
     {
@@ -1285,65 +1223,36 @@ windows_nat_target::windows_continue (DWORD continue_status, int id,
   for (auto &th : windows_process.thread_list)
     if (id == -1 || id == (int) th->tid)
       {
-#ifdef __x86_64__
-       if (windows_process.wow64_process)
+       windows_process.with_context (th.get (), [&] (auto *context)
          {
            if (th->debug_registers_changed)
              {
-               th->wow64_context.ContextFlags |= WOW64_CONTEXT_DEBUG_REGISTERS;
-               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 = windows_process.dr[7];
+               context->ContextFlags
+                 |= WindowsContext<decltype(context)>::debug;
+               context->Dr0 = windows_process.dr[0];
+               context->Dr1 = windows_process.dr[1];
+               context->Dr2 = windows_process.dr[2];
+               context->Dr3 = windows_process.dr[3];
+               context->Dr6 = DR6_CLEAR_VALUE;
+               context->Dr7 = windows_process.dr[7];
                th->debug_registers_changed = false;
              }
-           if (th->wow64_context.ContextFlags)
+           if (context->ContextFlags)
              {
                DWORD ec = 0;
 
                if (GetExitCodeThread (th->h, &ec)
                    && ec == STILL_ACTIVE)
                  {
-                   BOOL status = Wow64SetThreadContext (th->h,
-                                                        &th->wow64_context);
+                   BOOL status = set_thread_context (th->h, context);
 
                    if (!killed)
                      CHECK (status);
                  }
-               th->wow64_context.ContextFlags = 0;
-             }
-         }
-       else
-#endif
-         {
-           if (th->debug_registers_changed)
-             {
-               th->context.ContextFlags |= CONTEXT_DEBUG_REGISTERS;
-               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 = windows_process.dr[7];
-               th->debug_registers_changed = false;
+               context->ContextFlags = 0;
              }
-           if (th->context.ContextFlags)
-             {
-               DWORD ec = 0;
-
-               if (GetExitCodeThread (th->h, &ec)
-                   && ec == STILL_ACTIVE)
-                 {
-                   BOOL status = SetThreadContext (th->h, &th->context);
+         });
 
-                   if (!killed)
-                     CHECK (status);
-                 }
-               th->context.ContextFlags = 0;
-             }
-         }
        th->resume ();
       }
     else
@@ -1454,8 +1363,7 @@ windows_nat_target::resume (ptid_t ptid, int step, enum gdb_signal sig)
   th = windows_process.thread_rec (inferior_ptid, DONT_INVALIDATE_CONTEXT);
   if (th)
     {
-#ifdef __x86_64__
-      if (windows_process.wow64_process)
+      windows_process.with_context (th, [&] (auto *context)
        {
          if (step)
            {
@@ -1463,53 +1371,25 @@ windows_nat_target::resume (ptid_t ptid, int step, enum gdb_signal sig)
              regcache *regcache = get_thread_regcache (inferior_thread ());
              struct gdbarch *gdbarch = regcache->arch ();
              fetch_registers (regcache, gdbarch_ps_regnum (gdbarch));
-             th->wow64_context.EFlags |= FLAG_TRACE_BIT;
+             context->EFlags |= FLAG_TRACE_BIT;
            }
 
-         if (th->wow64_context.ContextFlags)
+         if (context->ContextFlags)
            {
              if (th->debug_registers_changed)
                {
-                 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 = windows_process.dr[7];
+                 context->Dr0 = windows_process.dr[0];
+                 context->Dr1 = windows_process.dr[1];
+                 context->Dr2 = windows_process.dr[2];
+                 context->Dr3 = windows_process.dr[3];
+                 context->Dr6 = DR6_CLEAR_VALUE;
+                 context->Dr7 = windows_process.dr[7];
                  th->debug_registers_changed = false;
                }
-             CHECK (Wow64SetThreadContext (th->h, &th->wow64_context));
-             th->wow64_context.ContextFlags = 0;
+             CHECK (set_thread_context (th->h, context));
+             context->ContextFlags = 0;
            }
-       }
-      else
-#endif
-       {
-         if (step)
-           {
-             /* Single step by setting t bit.  */
-             regcache *regcache = get_thread_regcache (inferior_thread ());
-             struct gdbarch *gdbarch = regcache->arch ();
-             fetch_registers (regcache, gdbarch_ps_regnum (gdbarch));
-             th->context.EFlags |= FLAG_TRACE_BIT;
-           }
-
-         if (th->context.ContextFlags)
-           {
-             if (th->debug_registers_changed)
-               {
-                 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 = windows_process.dr[7];
-                 th->debug_registers_changed = false;
-               }
-             CHECK (SetThreadContext (th->h, &th->context));
-             th->context.ContextFlags = 0;
-           }
-       }
+       });
     }
 
   /* Allow continuing with the same signal that interrupted us.
index 4d031d4ab57147fcae4436170303e395e853f6cc..b3e68781fcca15b105b95af24f2bb7290b969292 100644 (file)
@@ -88,31 +88,12 @@ win32_get_current_dr (int dr)
 
   win32_require_context (th);
 
-#ifdef __x86_64__
-#define RET_DR(DR)                             \
-  case DR:                                     \
-    return th->wow64_context.Dr ## DR
-
-  if (windows_process.wow64_process)
+  return windows_process.with_context (th, [&] (auto *context) -> DWORD64
     {
-      switch (dr)
-       {
-         RET_DR (0);
-         RET_DR (1);
-         RET_DR (2);
-         RET_DR (3);
-         RET_DR (6);
-         RET_DR (7);
-       }
-    }
-  else
-#undef RET_DR
-#endif
 #define RET_DR(DR)                             \
-  case DR:                                     \
-    return th->context.Dr ## DR
+      case DR:                                 \
+       return context->Dr ## DR
 
-    {
       switch (dr)
        {
          RET_DR (0);
@@ -122,11 +103,10 @@ win32_get_current_dr (int dr)
          RET_DR (6);
          RET_DR (7);
        }
-    }
-
 #undef RET_DR
 
-  gdb_assert_not_reached ("unhandled dr");
+      gdb_assert_not_reached ("unhandled dr");
+    });
 }
 
 static CORE_ADDR
@@ -247,59 +227,33 @@ i386_initial_stuff (void)
 static void
 i386_get_thread_context (windows_thread_info *th)
 {
-  /* Requesting the CONTEXT_EXTENDED_REGISTERS register set fails if
-     the system doesn't support extended registers.  */
-  static DWORD extended_registers = CONTEXT_EXTENDED_REGISTERS;
-#ifdef __x86_64__
-  static DWORD wow64_extended_registers = WOW64_CONTEXT_EXTENDED_REGISTERS;
-#endif
+  windows_process.with_context (th, [&] (auto *context)
+    {
+      /* Requesting the CONTEXT_EXTENDED_REGISTERS register set fails if
+        the system doesn't support extended registers.  */
+      static DWORD extended_registers
+       = WindowsContext<decltype(context)>::extended;
 
  again:
-#ifdef __x86_64__
-  if (windows_process.wow64_process)
-    th->wow64_context.ContextFlags = (WOW64_CONTEXT_FULL
-                                     | WOW64_CONTEXT_FLOATING_POINT
-                                     | WOW64_CONTEXT_DEBUG_REGISTERS
-                                     | wow64_extended_registers);
-  else
-#endif
-    th->context.ContextFlags = (CONTEXT_FULL
-                               | CONTEXT_FLOATING_POINT
-                               | CONTEXT_DEBUG_REGISTERS
-                               | extended_registers);
-
-  BOOL ret;
-#ifdef __x86_64__
-  if (windows_process.wow64_process)
-    ret = Wow64GetThreadContext (th->h, &th->wow64_context);
-  else
-#endif
-    ret = GetThreadContext (th->h, &th->context);
-  if (!ret)
-    {
-      DWORD e = GetLastError ();
+      context->ContextFlags = (WindowsContext<decltype(context)>::full
+                              | WindowsContext<decltype(context)>::floating
+                              | WindowsContext<decltype(context)>::debug
+                              | extended_registers);
 
-#ifdef __x86_64__
-      if (windows_process.wow64_process)
-       {
-         if (wow64_extended_registers && e == ERROR_INVALID_PARAMETER)
-           {
-             wow64_extended_registers = 0;
-             goto again;
-           }
-       }
-      else
-#endif
+      BOOL ret = get_thread_context (th->h, context);
+      if (!ret)
        {
+         DWORD e = GetLastError ();
+
          if (extended_registers && e == ERROR_INVALID_PARAMETER)
            {
              extended_registers = 0;
              goto again;
            }
-       }
 
-      error ("GetThreadContext failure %ld\n", (long) e);
-    }
+         error ("GetThreadContext failure %ld\n", (long) e);
+       }
+    });
 }
 
 static void
@@ -311,28 +265,16 @@ i386_prepare_to_resume (windows_thread_info *th)
 
       win32_require_context (th);
 
-#ifdef __x86_64__
-      if (windows_process.wow64_process)
+      windows_process.with_context (th, [&] (auto *context)
        {
-         th->wow64_context.Dr0 = dr->dr_mirror[0];
-         th->wow64_context.Dr1 = dr->dr_mirror[1];
-         th->wow64_context.Dr2 = dr->dr_mirror[2];
-         th->wow64_context.Dr3 = dr->dr_mirror[3];
-         /* th->wow64_context.Dr6 = dr->dr_status_mirror;
+         context->Dr0 = dr->dr_mirror[0];
+         context->Dr1 = dr->dr_mirror[1];
+         context->Dr2 = dr->dr_mirror[2];
+         context->Dr3 = dr->dr_mirror[3];
+         /* context->Dr6 = dr->dr_status_mirror;
             FIXME: should we set dr6 also ?? */
-         th->wow64_context.Dr7 = dr->dr_control_mirror;
-       }
-      else
-#endif
-       {
-         th->context.Dr0 = dr->dr_mirror[0];
-         th->context.Dr1 = dr->dr_mirror[1];
-         th->context.Dr2 = dr->dr_mirror[2];
-         th->context.Dr3 = dr->dr_mirror[3];
-         /* th->context.Dr6 = dr->dr_status_mirror;
-            FIXME: should we set dr6 also ?? */
-         th->context.Dr7 = dr->dr_control_mirror;
-       }
+         context->Dr7 = dr->dr_control_mirror;
+       });
 
       th->debug_registers_changed = false;
     }
@@ -347,12 +289,10 @@ i386_thread_added (windows_thread_info *th)
 static void
 i386_single_step (windows_thread_info *th)
 {
-#ifdef __x86_64__
-  if (windows_process.wow64_process)
-    th->wow64_context.EFlags |= FLAG_TRACE_BIT;
-  else
-#endif
-    th->context.EFlags |= FLAG_TRACE_BIT;
+  windows_process.with_context (th, [] (auto *context)
+    {
+      context->EFlags |= FLAG_TRACE_BIT;
+    });
 }
 
 /* An array of offset mappings into a Win32 Context structure.
@@ -532,13 +472,10 @@ i386_fetch_inferior_register (struct regcache *regcache,
 #endif
     mappings = i386_mappings;
 
-  char *context_offset;
-#ifdef __x86_64__
-  if (windows_process.wow64_process)
-    context_offset = (char *) &th->wow64_context + mappings[r];
-  else
-#endif
-    context_offset = (char *) &th->context + mappings[r];
+  char *context_offset = windows_process.with_context (th, [&] (auto *context)
+    {
+      return (char *) context + mappings[r];
+    });
 
   /* GDB treats some registers as 32-bit, where they are in fact only
      16 bits long.  These cases must be handled specially to avoid
@@ -571,13 +508,10 @@ i386_store_inferior_register (struct regcache *regcache,
 #endif
     mappings = i386_mappings;
 
-  char *context_offset;
-#ifdef __x86_64__
-  if (windows_process.wow64_process)
-    context_offset = (char *) &th->wow64_context + mappings[r];
-  else
-#endif
-    context_offset = (char *) &th->context + mappings[r];
+  char *context_offset = windows_process.with_context (th, [&] (auto *context)
+    {
+      return (char *) context + mappings[r];
+    });
 
   /* GDB treats some registers as 32-bit, where they are in fact only
      16 bits long.  These cases must be handled specially to avoid
index c3115ea826c83468cc26b6ed5786b263dcd3024e..dab57f7256b2ab9e89494c0efbaa4deac033034f 100644 (file)
@@ -81,12 +81,10 @@ debug_event_ptid (DEBUG_EVENT *event)
 static void
 win32_get_thread_context (windows_thread_info *th)
 {
-#ifdef __x86_64__
-  if (windows_process.wow64_process)
-    memset (&th->wow64_context, 0, sizeof (WOW64_CONTEXT));
-  else
-#endif
-    memset (&th->context, 0, sizeof (CONTEXT));
+  windows_process.with_context (th, [] (auto *context)
+    {
+      memset (context, 0, sizeof (*context));
+    });
   (*the_low_target.get_thread_context) (th);
 }
 
@@ -95,12 +93,10 @@ win32_get_thread_context (windows_thread_info *th)
 static void
 win32_set_thread_context (windows_thread_info *th)
 {
-#ifdef __x86_64__
-  if (windows_process.wow64_process)
-    Wow64SetThreadContext (th->h, &th->wow64_context);
-  else
-#endif
-    SetThreadContext (th->h, &th->context);
+  windows_process.with_context (th, [&] (auto *context)
+    {
+      set_thread_context (th->h, context);
+    });
 }
 
 /* Set the thread context of the thread associated with TH.  */
@@ -117,13 +113,7 @@ win32_prepare_to_resume (windows_thread_info *th)
 void
 win32_require_context (windows_thread_info *th)
 {
-  DWORD context_flags;
-#ifdef __x86_64__
-  if (windows_process.wow64_process)
-    context_flags = th->wow64_context.ContextFlags;
-  else
-#endif
-    context_flags = th->context.ContextFlags;
+  DWORD context_flags = *windows_process.context_flags_ptr (th);
   if (context_flags == 0)
     {
       th->suspend ();
@@ -407,13 +397,7 @@ continue_one_thread (thread_info *thread, int thread_id)
 
       if (th->suspended)
        {
-         DWORD *context_flags;
-#ifdef __x86_64__
-         if (windows_process.wow64_process)
-           context_flags = &th->wow64_context.ContextFlags;
-         else
-#endif
-           context_flags = &th->context.ContextFlags;
+         DWORD *context_flags = windows_process.context_flags_ptr (th);
          if (*context_flags)
            {
              win32_set_thread_context (th);
@@ -823,13 +807,7 @@ win32_process_target::resume (thread_resume *resume_info, size_t n)
     {
       win32_prepare_to_resume (th);
 
-      DWORD *context_flags;
-#ifdef __x86_64__
-      if (windows_process.wow64_process)
-       context_flags = &th->wow64_context.ContextFlags;
-      else
-#endif
-       context_flags = &th->context.ContextFlags;
+      DWORD *context_flags = windows_process.context_flags_ptr (th);
       if (*context_flags)
        {
          /* Move register values from the inferior into the thread