Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* [PATCH 1/8] gdb/testsuite: Add Windows replacement for aligned_alloc
       [not found] <20260712113229.3695246-1-ssbssa.ref@yahoo.de>
@ 2026-07-12 11:32 ` Hannes Domani
  2026-07-12 11:32   ` [PATCH 2/8] Windows gdb: Use allocated buffer for CONTEXT Hannes Domani
                     ` (6 more replies)
  0 siblings, 7 replies; 20+ messages in thread
From: Hannes Domani @ 2026-07-12 11:32 UTC (permalink / raw)
  To: gdb-patches

_aligned_malloc has swapped arguments, and you have to use _aligned_free
to free the memory afterwards.
---
 gdb/testsuite/gdb.arch/i386-avx.c         |  2 +-
 gdb/testsuite/gdb.arch/i386-sse.c         |  2 +-
 gdb/testsuite/lib/precise-aligned-alloc.c | 20 ++++++++++++++++++++
 3 files changed, 22 insertions(+), 2 deletions(-)

diff --git a/gdb/testsuite/gdb.arch/i386-avx.c b/gdb/testsuite/gdb.arch/i386-avx.c
index b6cd89e5bea..229093e5164 100644
--- a/gdb/testsuite/gdb.arch/i386-avx.c
+++ b/gdb/testsuite/gdb.arch/i386-avx.c
@@ -116,7 +116,7 @@ main (int argc, char **argv)
 
   puts ("Bye!"); /* second breakpoint here */
 
-  free (allocated_ptr);
+  aligned_free (allocated_ptr);
 
   return 0;
 }
diff --git a/gdb/testsuite/gdb.arch/i386-sse.c b/gdb/testsuite/gdb.arch/i386-sse.c
index 21264ed74e7..5210aee12c3 100644
--- a/gdb/testsuite/gdb.arch/i386-sse.c
+++ b/gdb/testsuite/gdb.arch/i386-sse.c
@@ -134,7 +134,7 @@ main (int argc, char **argv)
       puts ("Bye!"); /* second breakpoint here */
     }
 
-  free (allocated_ptr);
+  aligned_free (allocated_ptr);
 
   return 0;
 }
diff --git a/gdb/testsuite/lib/precise-aligned-alloc.c b/gdb/testsuite/lib/precise-aligned-alloc.c
index 888814f12ef..1db35528bc8 100644
--- a/gdb/testsuite/lib/precise-aligned-alloc.c
+++ b/gdb/testsuite/lib/precise-aligned-alloc.c
@@ -21,6 +21,26 @@
 #include <string.h>
 #include <stdint.h>
 
+#ifdef _WIN32
+static void *
+aligned_alloc (size_t alignment, size_t size)
+{
+  return _aligned_malloc (size, alignment);
+}
+
+static void
+aligned_free (void *ptr)
+{
+  _aligned_free (ptr);
+}
+#else
+static void
+aligned_free (void *ptr)
+{
+  free (ptr);
+}
+#endif
+
 /* Return true if address P is ALIGNMENT-byte aligned.  */
 
 static int
-- 
2.54.0


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

* [PATCH 2/8] Windows gdb: Use allocated buffer for CONTEXT
  2026-07-12 11:32 ` [PATCH 1/8] gdb/testsuite: Add Windows replacement for aligned_alloc Hannes Domani
@ 2026-07-12 11:32   ` Hannes Domani
  2026-07-12 11:32   ` [PATCH 3/8] Windows gdb: Remove mappings member from windows_per_inferior Hannes Domani
                     ` (5 subsequent siblings)
  6 siblings, 0 replies; 20+ messages in thread
From: Hannes Domani @ 2026-07-12 11:32 UTC (permalink / raw)
  To: gdb-patches

This is done in preparation for the XState functions, because the
extended registers are stored directly after the CONTEXT, and its actual
size depends on the available XState features.
---
 gdb/aarch64-windows-nat.c      | 16 ++++++++--------
 gdb/nat/windows-nat.c          | 19 +++++++++++++++++++
 gdb/nat/windows-nat.h          | 16 ++++++++++++----
 gdb/windows-nat.c              |  1 +
 gdbserver/win32-aarch64-low.cc | 10 +++++-----
 gdbserver/win32-low.cc         |  1 +
 6 files changed, 46 insertions(+), 17 deletions(-)

diff --git a/gdb/aarch64-windows-nat.c b/gdb/aarch64-windows-nat.c
index ff2c9762467..630704a8caf 100644
--- a/gdb/aarch64-windows-nat.c
+++ b/gdb/aarch64-windows-nat.c
@@ -185,7 +185,7 @@ aarch64_windows_nat_target::cleanup_windows_arch ()
 void
 aarch64_windows_per_inferior::fill_thread_context (windows_thread_info *th)
 {
-  CONTEXT *context = &th->context;
+  CONTEXT *context = th->context;
 
   if (context->ContextFlags == 0)
     {
@@ -199,7 +199,7 @@ aarch64_windows_per_inferior::fill_thread_context (windows_thread_info *th)
 void
 aarch64_windows_per_inferior::invalidate_thread_context (windows_thread_info *th)
 {
-  CONTEXT *context = &th->context;
+  CONTEXT *context = th->context;
   context->ContextFlags = 0;
 }
 
@@ -209,7 +209,7 @@ void
 aarch64_windows_nat_target::thread_context_continue (windows_thread_info *th,
 						     int killed)
 {
-  CONTEXT *context = &th->context;
+  CONTEXT *context = th->context;
 
   if (th->debug_registers_changed)
     {
@@ -250,9 +250,9 @@ aarch64_windows_nat_target::thread_context_step (windows_thread_info *th,
 						 bool enable)
 {
   if (enable)
-    th->context.Cpsr |= 0x200000;
+    th->context->Cpsr |= 0x200000;
   else
-    th->context.Cpsr &= ~0x200000;
+    th->context->Cpsr &= ~0x200000;
 }
 
 /* See windows-nat.h.  */
@@ -263,7 +263,7 @@ aarch64_windows_nat_target::fetch_one_register (struct regcache *regcache,
 {
   gdb_assert (r >= 0);
 
-  char *context_ptr = (char *) &th->context;
+  char *context_ptr = (char *) th->context;
   char *context_offset = context_ptr + aarch64_windows_process.mappings[r];
   struct gdbarch *gdbarch = regcache->arch ();
 
@@ -292,9 +292,9 @@ aarch64_windows_nat_target::store_one_register (const struct regcache *regcache,
 						windows_thread_info *th, int r)
 {
   gdb_assert (r >= 0);
-  gdb_assert (th->context.ContextFlags != 0);
+  gdb_assert (th->context->ContextFlags != 0);
 
-  char *context_ptr = (char *) &th->context;
+  char *context_ptr = (char *) th->context;
 
   regcache->raw_collect (r, context_ptr + aarch64_windows_process.mappings[r]);
 }
diff --git a/gdb/nat/windows-nat.c b/gdb/nat/windows-nat.c
index e975892f487..689601f3a82 100644
--- a/gdb/nat/windows-nat.c
+++ b/gdb/nat/windows-nat.c
@@ -291,6 +291,25 @@ windows_process_info::pid_to_exec_file (int pid)
   return path;
 }
 
+/* See windows-nat.h.  */
+
+void windows_process_info::initialize_context (windows_thread_info *th)
+{
+#ifdef __x86_64__
+  if (wow64_process)
+    {
+      th->context_buffer.reset (xmalloc (sizeof (WOW64_CONTEXT)));
+      th->wow64_context = (WOW64_CONTEXT *) th->context_buffer.get ();
+    }
+  else
+#endif
+    {
+      th->context_buffer.reset (xmalloc (sizeof (CONTEXT)));
+      th->context = (CONTEXT *) th->context_buffer.get ();
+    }
+  *context_flags_ptr (th) = 0;
+}
+
 /* Return the name of the DLL referenced by H at ADDRESS.  UNICODE
    determines what sort of string is read from the inferior.  Returns
    the name of the DLL, or NULL on error.  If a name is returned, it
diff --git a/gdb/nat/windows-nat.h b/gdb/nat/windows-nat.h
index 44b628c9bd1..76688fa90da 100644
--- a/gdb/nat/windows-nat.h
+++ b/gdb/nat/windows-nat.h
@@ -183,9 +183,9 @@ struct windows_thread_info
   /* The context of the thread, including any manipulations.  */
   union
   {
-    CONTEXT context {};
+    CONTEXT *context = nullptr;
 #ifdef __x86_64__
-    WOW64_CONTEXT wow64_context;
+    WOW64_CONTEXT *wow64_context;
 #endif
   };
 
@@ -204,6 +204,10 @@ struct windows_thread_info
 
   /* The name of the thread.  */
   gdb::unique_xmalloc_ptr<char> name;
+
+  /* The buffer for the thread context, including any XState registers if
+     available.  */
+  gdb::unique_xmalloc_ptr<void> context_buffer;
 };
 
 enum handle_exception_result
@@ -313,15 +317,19 @@ struct windows_process_info
 
   const char *pid_to_exec_file (int);
 
+  /* Allocate the context buffer for this thread.  */
+
+  void initialize_context (windows_thread_info *th);
+
   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);
+      return function (th != nullptr ? th->wow64_context : nullptr);
     else
 #endif
-      return function (th != nullptr ? &th->context : nullptr);
+      return function (th != nullptr ? th->context : nullptr);
   }
 
   DWORD *context_flags_ptr (windows_thread_info *th)
diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c
index def8fa606f4..4cd301d4959 100644
--- a/gdb/windows-nat.c
+++ b/gdb/windows-nat.c
@@ -515,6 +515,7 @@ windows_nat_target::add_thread (ptid_t ptid, HANDLE h, void *tlb,
 #endif
   windows_private_thread_info *th
     = new windows_private_thread_info (windows_process, ptid.lwp (), h, base);
+  windows_process->initialize_context (th);
 
   /* Add this new thread to the list of threads.
 
diff --git a/gdbserver/win32-aarch64-low.cc b/gdbserver/win32-aarch64-low.cc
index 5a7b72155db..e94548b6fef 100644
--- a/gdbserver/win32-aarch64-low.cc
+++ b/gdbserver/win32-aarch64-low.cc
@@ -169,7 +169,7 @@ aarch64_initial_stuff (process_info *proc)
 static void
 aarch64_get_thread_context (windows_thread_info *th)
 {
-  CONTEXT *context = &th->context;
+  CONTEXT *context = th->context;
 
   context->ContextFlags = (WindowsContext<decltype(context)>::full
 			   | WindowsContext<decltype(context)>::floating
@@ -193,7 +193,7 @@ aarch64_prepare_to_resume (windows_thread_info *th)
     {
       win32_require_context (th);
 
-      CONTEXT *context = &th->context;
+      CONTEXT *context = th->context;
 
       for (int i = 0; i < aarch64_num_bp_regs; i++)
 	{
@@ -223,7 +223,7 @@ aarch64_thread_added (windows_thread_info *th)
 static void
 aarch64_single_step (windows_thread_info *th)
 {
-  th->context.Cpsr |= 0x200000;
+  th->context->Cpsr |= 0x200000;
 }
 
 /* An array of offset mappings into a Win32 Context structure.
@@ -322,7 +322,7 @@ aarch64_fetch_inferior_register (struct regcache *regcache,
   int mappings_count;
   get_mappings (mappings, mappings_count);
 
-  char *context_ptr = (char *) &th->context;
+  char *context_ptr = (char *) th->context;
   char *context_offset;
   if (r < mappings_count)
     context_offset = context_ptr + mappings[r];
@@ -341,7 +341,7 @@ aarch64_store_inferior_register (struct regcache *regcache,
   int mappings_count;
   get_mappings (mappings, mappings_count);
 
-  char *context_ptr = (char *) &th->context;
+  char *context_ptr = (char *) th->context;
   char *context_offset;
   if (r < mappings_count)
     context_offset = context_ptr + mappings[r];
diff --git a/gdbserver/win32-low.cc b/gdbserver/win32-low.cc
index 7629beca213..3d85faf0785 100644
--- a/gdbserver/win32-low.cc
+++ b/gdbserver/win32-low.cc
@@ -152,6 +152,7 @@ child_add_thread (DWORD pid, DWORD tid, HANDLE h, void *tlb)
     base += 2 * 4096; /* page size = 4096 */
 #endif
   th = new windows_thread_info (&windows_process, tid, h, base);
+  windows_process.initialize_context (th);
 
   find_process_pid (pid)->add_thread (ptid, th);
 
-- 
2.54.0


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

* [PATCH 3/8] Windows gdb: Remove mappings member from windows_per_inferior
  2026-07-12 11:32 ` [PATCH 1/8] gdb/testsuite: Add Windows replacement for aligned_alloc Hannes Domani
  2026-07-12 11:32   ` [PATCH 2/8] Windows gdb: Use allocated buffer for CONTEXT Hannes Domani
@ 2026-07-12 11:32   ` Hannes Domani
  2026-07-12 11:32   ` [PATCH 4/8] Windows gdb: Refactor getting pointer to register inside context Hannes Domani
                     ` (4 subsequent siblings)
  6 siblings, 0 replies; 20+ messages in thread
From: Hannes Domani @ 2026-07-12 11:32 UTC (permalink / raw)
  To: gdb-patches

It's not really that useful, and simplifies later XState changes.
---
 gdb/aarch64-windows-nat.c |  6 ++----
 gdb/windows-nat.h         | 18 ------------------
 gdb/x86-windows-nat.c     | 34 ++++++++++++++++++++++------------
 3 files changed, 24 insertions(+), 34 deletions(-)

diff --git a/gdb/aarch64-windows-nat.c b/gdb/aarch64-windows-nat.c
index 630704a8caf..be900439047 100644
--- a/gdb/aarch64-windows-nat.c
+++ b/gdb/aarch64-windows-nat.c
@@ -168,8 +168,6 @@ aarch64_windows_nat_target::initialize_windows_arch (bool attaching)
 {
   memset (&aarch64_windows_process.dr_state, 0,
 	  sizeof (aarch64_windows_process.dr_state));
-
-  aarch64_windows_process.mappings = aarch64_mappings;
 }
 
 /* See windows-nat.h.  */
@@ -264,7 +262,7 @@ aarch64_windows_nat_target::fetch_one_register (struct regcache *regcache,
   gdb_assert (r >= 0);
 
   char *context_ptr = (char *) th->context;
-  char *context_offset = context_ptr + aarch64_windows_process.mappings[r];
+  char *context_offset = context_ptr + aarch64_mappings[r];
   struct gdbarch *gdbarch = regcache->arch ();
 
   gdb_assert (!gdbarch_read_pc_p (gdbarch));
@@ -296,7 +294,7 @@ aarch64_windows_nat_target::store_one_register (const struct regcache *regcache,
 
   char *context_ptr = (char *) th->context;
 
-  regcache->raw_collect (r, context_ptr + aarch64_windows_process.mappings[r]);
+  regcache->raw_collect (r, context_ptr + aarch64_mappings[r]);
 }
 
 /* See windows-nat.h.  */
diff --git a/gdb/windows-nat.h b/gdb/windows-nat.h
index cbe5429fd84..d52d82c422e 100644
--- a/gdb/windows-nat.h
+++ b/gdb/windows-nat.h
@@ -139,24 +139,6 @@ struct windows_per_inferior : public windows_nat::windows_process_info
   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;
-
   std::vector<windows_solib> solibs;
 
 #ifdef __CYGWIN__
diff --git a/gdb/x86-windows-nat.c b/gdb/x86-windows-nat.c
index 3368814ed96..45f3872add6 100644
--- a/gdb/x86-windows-nat.c
+++ b/gdb/x86-windows-nat.c
@@ -85,16 +85,10 @@ x86_windows_nat_target::initialize_windows_arch (bool attaching)
     = !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;
-    }
+    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;
-    }
+    x86_windows_process.segment_register_p = i386_windows_segment_register_p;
 }
 
 /* See windows-nat.h.  */
@@ -242,7 +236,15 @@ x86_windows_nat_target::fetch_one_register (struct regcache *regcache,
       return (char *) context;
     });
 
-  char *context_offset = context_ptr + x86_windows_process.mappings[r];
+  const int *mappings;
+#ifdef __x86_64__
+  if (!x86_windows_process.wow64_process)
+    mappings = amd64_mappings;
+  else
+#endif
+    mappings = i386_mappings;
+
+  char *context_offset = context_ptr + mappings[r];
   struct gdbarch *gdbarch = regcache->arch ();
   i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
 
@@ -308,6 +310,14 @@ x86_windows_nat_target::store_one_register (const struct regcache *regcache,
       return (char *) context;
     });
 
+  const int *mappings;
+#ifdef __x86_64__
+  if (!x86_windows_process.wow64_process)
+    mappings = amd64_mappings;
+  else
+#endif
+    mappings = i386_mappings;
+
   struct gdbarch *gdbarch = regcache->arch ();
   i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
 
@@ -319,7 +329,7 @@ x86_windows_nat_target::store_one_register (const struct regcache *regcache,
     {
       gdb_byte bytes[4];
       regcache->raw_collect (r, bytes);
-      memcpy (context_ptr + x86_windows_process.mappings[r], bytes, 2);
+      memcpy (context_ptr + mappings[r], bytes, 2);
     }
   else if (r == I387_FOP_REGNUM (tdep))
     {
@@ -328,10 +338,10 @@ x86_windows_nat_target::store_one_register (const struct regcache *regcache,
       /* 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);
+      memcpy (context_ptr + mappings[r] + 2, bytes, 2);
     }
   else
-    regcache->raw_collect (r, context_ptr + x86_windows_process.mappings[r]);
+    regcache->raw_collect (r, context_ptr + mappings[r]);
 }
 
 /* See windows-nat.h.  */
-- 
2.54.0


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

* [PATCH 4/8] Windows gdb: Refactor getting pointer to register inside context
  2026-07-12 11:32 ` [PATCH 1/8] gdb/testsuite: Add Windows replacement for aligned_alloc Hannes Domani
  2026-07-12 11:32   ` [PATCH 2/8] Windows gdb: Use allocated buffer for CONTEXT Hannes Domani
  2026-07-12 11:32   ` [PATCH 3/8] Windows gdb: Remove mappings member from windows_per_inferior Hannes Domani
@ 2026-07-12 11:32   ` Hannes Domani
  2026-07-12 11:32   ` [PATCH 5/8] Windows gdb: Prepare XState functions Hannes Domani
                     ` (3 subsequent siblings)
  6 siblings, 0 replies; 20+ messages in thread
From: Hannes Domani @ 2026-07-12 11:32 UTC (permalink / raw)
  To: gdb-patches

These get_context_reg_ptr helper functions will be extended for XState
registers later.
---
 gdb/amd64-windows-nat.c     |  3 ++
 gdb/i386-windows-nat.c      |  3 ++
 gdb/windows-nat.h           |  6 +++
 gdb/x86-windows-nat.c       | 75 ++++++++++++++++++++++---------------
 gdbserver/win32-i386-low.cc | 46 +++++++++++++++--------
 5 files changed, 87 insertions(+), 46 deletions(-)

diff --git a/gdb/amd64-windows-nat.c b/gdb/amd64-windows-nat.c
index cca606b5200..9d83a5f8334 100644
--- a/gdb/amd64-windows-nat.c
+++ b/gdb/amd64-windows-nat.c
@@ -86,6 +86,9 @@ const int amd64_mappings[] =
 };
 #undef context_offset
 
+const int amd64_mappings_count
+  = sizeof (amd64_mappings) / sizeof (amd64_mappings[0]);
+
 /* segment_register_p_ftype implementation for amd64.  */
 
 int
diff --git a/gdb/i386-windows-nat.c b/gdb/i386-windows-nat.c
index 991f301cad1..151b778036c 100644
--- a/gdb/i386-windows-nat.c
+++ b/gdb/i386-windows-nat.c
@@ -74,6 +74,9 @@ const int i386_mappings[] =
 #undef context_offset
 #undef CONTEXT
 
+const int i386_mappings_count
+  = sizeof (i386_mappings) / sizeof (i386_mappings[0]);
+
 /* segment_register_p_ftype implementation for x86.  */
 
 int
diff --git a/gdb/windows-nat.h b/gdb/windows-nat.h
index d52d82c422e..492f0f7cd14 100644
--- a/gdb/windows-nat.h
+++ b/gdb/windows-nat.h
@@ -392,12 +392,18 @@ int i386_windows_segment_register_p (int regnum);
 /* context register offsets for x86.  */
 extern const int i386_mappings[];
 
+/* number of context register offests for x86.  */
+extern const int i386_mappings_count;
+
 #ifdef __x86_64__
 /* segment_register_p_ftype implementation for amd64.  */
 int amd64_windows_segment_register_p (int regnum);
 
 /* context register offsets for amd64.  */
 extern const int amd64_mappings[];
+
+/* number of context register offests for amd64.  */
+extern const int amd64_mappings_count;
 #endif
 
 /* Creates an iterator that works like all_matching_threads_iterator,
diff --git a/gdb/x86-windows-nat.c b/gdb/x86-windows-nat.c
index 45f3872add6..065c551298e 100644
--- a/gdb/x86-windows-nat.c
+++ b/gdb/x86-windows-nat.c
@@ -223,31 +223,53 @@ x86_windows_nat_target::thread_context_step (windows_thread_info *th,
     });
 }
 
-/* See windows-nat.h.  */
+/* Get pointer to register R inside CONTEXT.  */
 
-void
-x86_windows_nat_target::fetch_one_register (struct regcache *regcache,
-					    windows_thread_info *th, int r)
+template<typename Context>
+static char *
+get_context_reg_ptr (Context *context, int r)
 {
-  gdb_assert (r >= 0);
-
-  char *context_ptr = x86_windows_process.with_context (th, [] (auto *context)
-    {
-      return (char *) context;
-    });
-
   const int *mappings;
+  int mappings_count;
 #ifdef __x86_64__
   if (!x86_windows_process.wow64_process)
-    mappings = amd64_mappings;
+    {
+      mappings = amd64_mappings;
+      mappings_count = amd64_mappings_count;
+    }
   else
 #endif
-    mappings = i386_mappings;
+    {
+      mappings = i386_mappings;
+      mappings_count = i386_mappings_count;
+    }
+
+  char *context_offset;
+  if (r < mappings_count)
+    context_offset = (char *) context + mappings[r];
+  else
+    gdb_assert_not_reached ("invalid register number %d", r);
+
+  return context_offset;
+}
+
+/* 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);
 
-  char *context_offset = context_ptr + mappings[r];
   struct gdbarch *gdbarch = regcache->arch ();
   i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
 
+  char *context_offset
+    = x86_windows_process.with_context (th, [&] (auto *context)
+    {
+      return get_context_reg_ptr (context, r);
+    });
+
   gdb_assert (!gdbarch_read_pc_p (gdbarch));
   gdb_assert (gdbarch_pc_regnum (gdbarch) >= 0);
   gdb_assert (!gdbarch_write_pc_p (gdbarch));
@@ -304,23 +326,16 @@ x86_windows_nat_target::store_one_register (const struct regcache *regcache,
 {
   gdb_assert (r >= 0);
 
-  char *context_ptr = x86_windows_process.with_context (th, [] (auto *context)
+  struct gdbarch *gdbarch = regcache->arch ();
+  i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
+
+  char *context_offset
+    = x86_windows_process.with_context (th, [&] (auto *context)
     {
       gdb_assert (context->ContextFlags != 0);
-      return (char *) context;
+      return get_context_reg_ptr (context, r);
     });
 
-  const int *mappings;
-#ifdef __x86_64__
-  if (!x86_windows_process.wow64_process)
-    mappings = amd64_mappings;
-  else
-#endif
-    mappings = i386_mappings;
-
-  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.  */
@@ -329,7 +344,7 @@ x86_windows_nat_target::store_one_register (const struct regcache *regcache,
     {
       gdb_byte bytes[4];
       regcache->raw_collect (r, bytes);
-      memcpy (context_ptr + mappings[r], bytes, 2);
+      memcpy (context_offset, bytes, 2);
     }
   else if (r == I387_FOP_REGNUM (tdep))
     {
@@ -338,10 +353,10 @@ x86_windows_nat_target::store_one_register (const struct regcache *regcache,
       /* 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 + mappings[r] + 2, bytes, 2);
+      memcpy (context_offset + 2, bytes, 2);
     }
   else
-    regcache->raw_collect (r, context_ptr + mappings[r]);
+    regcache->raw_collect (r, context_offset);
 }
 
 /* See windows-nat.h.  */
diff --git a/gdbserver/win32-i386-low.cc b/gdbserver/win32-i386-low.cc
index 1aacd302074..b77f6adc6ed 100644
--- a/gdbserver/win32-i386-low.cc
+++ b/gdbserver/win32-i386-low.cc
@@ -473,22 +473,44 @@ is_segment_register (int r)
     return r >= I386_CS_REGNUM && r <= I386_GS_REGNUM;
 }
 
-/* Fetch register from gdbserver regcache data.  */
-static void
-i386_fetch_inferior_register (struct regcache *regcache,
-			      windows_thread_info *th, int r)
+/* Get pointer to register R inside CONTEXT.  */
+
+template<typename Context>
+static char *
+get_context_reg_ptr (Context *context, int r)
 {
   const int *mappings;
+  int mappings_count;
 #ifdef __x86_64__
   if (!windows_process.wow64_process)
-    mappings = amd64_mappings;
+    {
+      mappings = amd64_mappings;
+      mappings_count = sizeof (amd64_mappings) / sizeof (amd64_mappings[0]);
+    }
   else
 #endif
-    mappings = i386_mappings;
+    {
+      mappings = i386_mappings;
+      mappings_count = sizeof (i386_mappings) / sizeof (i386_mappings[0]);
+    }
+
+  char *context_offset;
+  if (r < mappings_count)
+    context_offset = (char *) context + mappings[r];
+  else
+    gdb_assert_not_reached ("invalid register number %d", r);
+
+  return context_offset;
+}
 
+/* Fetch register from gdbserver regcache data.  */
+static void
+i386_fetch_inferior_register (struct regcache *regcache,
+			      windows_thread_info *th, int r)
+{
   char *context_offset = windows_process.with_context (th, [&] (auto *context)
     {
-      return (char *) context + mappings[r];
+      return get_context_reg_ptr (context, r);
     });
 
   /* GDB treats some registers as 32-bit, where they are in fact only
@@ -514,17 +536,9 @@ static void
 i386_store_inferior_register (struct regcache *regcache,
 			      windows_thread_info *th, int r)
 {
-  const int *mappings;
-#ifdef __x86_64__
-  if (!windows_process.wow64_process)
-    mappings = amd64_mappings;
-  else
-#endif
-    mappings = i386_mappings;
-
   char *context_offset = windows_process.with_context (th, [&] (auto *context)
     {
-      return (char *) context + mappings[r];
+      return get_context_reg_ptr (context, r);
     });
 
   /* GDB treats some registers as 32-bit, where they are in fact only
-- 
2.54.0


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

* [PATCH 5/8] Windows gdb: Prepare XState functions
  2026-07-12 11:32 ` [PATCH 1/8] gdb/testsuite: Add Windows replacement for aligned_alloc Hannes Domani
                     ` (2 preceding siblings ...)
  2026-07-12 11:32   ` [PATCH 4/8] Windows gdb: Refactor getting pointer to register inside context Hannes Domani
@ 2026-07-12 11:32   ` Hannes Domani
  2026-07-17 14:41     ` Schimpe, Christina
  2026-07-12 11:32   ` [PATCH 6/8] Windows gdb: Get available XState features Hannes Domani
                     ` (2 subsequent siblings)
  6 siblings, 1 reply; 20+ messages in thread
From: Hannes Domani @ 2026-07-12 11:32 UTC (permalink / raw)
  To: gdb-patches

These functions will then be used to access the XState registers.
---
 gdb/nat/windows-nat.c |  31 +++++++++++
 gdb/nat/windows-nat.h | 116 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 147 insertions(+)

diff --git a/gdb/nat/windows-nat.c b/gdb/nat/windows-nat.c
index 689601f3a82..cd1f9e7bc64 100644
--- a/gdb/nat/windows-nat.c
+++ b/gdb/nat/windows-nat.c
@@ -73,6 +73,19 @@ InitializeProcThreadAttributeList_ftype *InitializeProcThreadAttributeList;
 UpdateProcThreadAttribute_ftype *UpdateProcThreadAttribute;
 DeleteProcThreadAttributeList_ftype *DeleteProcThreadAttributeList;
 
+#if defined __i386__ || defined __x86_64__
+GetEnabledXStateFeatures_ftype *GetEnabledXStateFeatures;
+InitializeContext_ftype *InitializeContext;
+GetXStateFeaturesMask_ftype *GetXStateFeaturesMask;
+SetXStateFeaturesMask_ftype *SetXStateFeaturesMask;
+LocateXStateFeature_ftype *LocateXStateFeature;
+#ifdef __x86_64__
+RtlGetExtendedFeaturesMask_ftype *RtlGetExtendedFeaturesMask;
+RtlSetExtendedFeaturesMask_ftype *RtlSetExtendedFeaturesMask;
+RtlLocateExtendedFeature_ftype *RtlLocateExtendedFeature;
+#endif
+#endif
+
 /* Note that 'debug_events' must be locally defined in the relevant
    functions.  */
 #define DEBUG_EVENTS(fmt, ...) \
@@ -1191,6 +1204,14 @@ initialize_loadable ()
       GPA (hm, InitializeProcThreadAttributeList);
       GPA (hm, UpdateProcThreadAttribute);
       GPA (hm, DeleteProcThreadAttributeList);
+
+#if defined __i386__ || defined __x86_64__
+      GPA (hm, GetEnabledXStateFeatures);
+      GPA (hm, InitializeContext);
+      GPA (hm, GetXStateFeaturesMask);
+      GPA (hm, SetXStateFeaturesMask);
+      GPA (hm, LocateXStateFeature);
+#endif
     }
 
   /* Set variables to dummy versions of these processes if the function
@@ -1256,6 +1277,16 @@ initialize_loadable ()
 	GPA (hm, GetThreadDescription);
     }
 
+#ifdef __x86_64__
+  hm = LoadLibrary (TEXT ("ntdll.dll"));
+  if (hm)
+    {
+      GPA (hm, RtlGetExtendedFeaturesMask);
+      GPA (hm, RtlSetExtendedFeaturesMask);
+      GPA (hm, RtlLocateExtendedFeature);
+    }
+#endif
+
 #undef GPA
 
   return result;
diff --git a/gdb/nat/windows-nat.h b/gdb/nat/windows-nat.h
index 76688fa90da..a344b0a966f 100644
--- a/gdb/nat/windows-nat.h
+++ b/gdb/nat/windows-nat.h
@@ -35,6 +35,9 @@
 #define CONTEXT_EXTENDED_REGISTERS 0
 #endif
 
+#define CONTEXT_EXTENDED_REGISTERS_FLAG	0x20
+#define CONTEXT_XSTATE_FLAG		0x40
+
 namespace windows_nat
 {
 
@@ -456,6 +459,14 @@ extern BOOL create_process (const wchar_t *image, wchar_t *command_line,
 #define InitializeProcThreadAttributeList dyn_InitializeProcThreadAttributeList
 #define UpdateProcThreadAttribute dyn_UpdateProcThreadAttribute
 #define DeleteProcThreadAttributeList dyn_DeleteProcThreadAttributeList
+#define GetEnabledXStateFeatures	dyn_GetEnabledXStateFeatures
+#define InitializeContext		dyn_InitializeContext
+#define GetXStateFeaturesMask		dyn_GetXStateFeaturesMask
+#define SetXStateFeaturesMask		dyn_SetXStateFeaturesMask
+#define LocateXStateFeature		dyn_LocateXStateFeature
+#define RtlGetExtendedFeaturesMask	dyn_RtlGetExtendedFeaturesMask
+#define RtlSetExtendedFeaturesMask	dyn_RtlSetExtendedFeaturesMask
+#define RtlLocateExtendedFeature	dyn_RtlLocateExtendedFeature
 
 typedef BOOL WINAPI (AdjustTokenPrivileges_ftype) (HANDLE, BOOL,
 						   PTOKEN_PRIVILEGES,
@@ -550,6 +561,35 @@ extern DeleteProcThreadAttributeList_ftype *DeleteProcThreadAttributeList;
 
 extern bool disable_randomization_available ();
 
+#if defined __i386__ || defined __x86_64__
+typedef DWORD64 (WINAPI GetEnabledXStateFeatures_ftype) ();
+extern GetEnabledXStateFeatures_ftype *GetEnabledXStateFeatures;
+
+typedef BOOL (WINAPI InitializeContext_ftype) (PVOID, DWORD,
+					       PCONTEXT*, PDWORD);
+extern InitializeContext_ftype *InitializeContext;
+
+typedef BOOL (WINAPI GetXStateFeaturesMask_ftype) (PCONTEXT, PDWORD64);
+extern GetXStateFeaturesMask_ftype *GetXStateFeaturesMask;
+
+typedef BOOL (WINAPI SetXStateFeaturesMask_ftype) (PCONTEXT, DWORD64);
+extern SetXStateFeaturesMask_ftype *SetXStateFeaturesMask;
+
+typedef PVOID (WINAPI LocateXStateFeature_ftype) (PCONTEXT, DWORD, PDWORD);
+extern LocateXStateFeature_ftype *LocateXStateFeature;
+
+#ifdef __x86_64__
+typedef DWORD64 (WINAPI RtlGetExtendedFeaturesMask_ftype) (PVOID);
+extern RtlGetExtendedFeaturesMask_ftype *RtlGetExtendedFeaturesMask;
+
+typedef VOID (WINAPI RtlSetExtendedFeaturesMask_ftype) (PVOID, DWORD64);
+extern RtlSetExtendedFeaturesMask_ftype *RtlSetExtendedFeaturesMask;
+
+typedef PVOID (WINAPI RtlLocateExtendedFeature_ftype) (PVOID, DWORD, PDWORD);
+extern RtlLocateExtendedFeature_ftype *RtlLocateExtendedFeature;
+#endif
+#endif
+
 /* Helper classes to get the correct ContextFlags values based on the
    used type (CONTEXT or WOW64_CONTEXT).  */
 
@@ -615,16 +655,69 @@ enum_process_modules (CONTEXT *, HANDLE process,
   return EnumProcessModules (process, modules, size, needed);
 }
 
+#if defined __i386__ || defined __x86_64__
+static inline BOOL
+get_xstate_features_mask (CONTEXT *context, DWORD64 *mask)
+{
+  return GetXStateFeaturesMask (context, mask);
+}
+
+static inline BOOL
+set_xstate_features_mask (CONTEXT *context, DWORD64 mask)
+{
+  return SetXStateFeaturesMask (context, mask);
+}
+
+static inline PVOID
+locate_xstate_feature (CONTEXT *context, DWORD feature, DWORD *length)
+{
+  return LocateXStateFeature (context, feature, length);
+}
+#endif
+
 #ifdef __x86_64__
 static inline BOOL
 get_thread_context (HANDLE h, WOW64_CONTEXT *context)
 {
+  if ((context->ContextFlags & CONTEXT_XSTATE_FLAG) != 0)
+    {
+      /* Wow64GetThreadContext doesn't handle CONTEXT_EXTENDED_REGISTERS and
+	 CONTEXT_XSTATE combined correctly, but separate they work fine.  */
+      DWORD flags = context->ContextFlags;
+      context->ContextFlags &= ~CONTEXT_EXTENDED_REGISTERS_FLAG;
+      BOOL ret = Wow64GetThreadContext (h, context);
+      context->ContextFlags = flags;
+      if (!ret)
+	return FALSE;
+
+      context->ContextFlags &= ~CONTEXT_XSTATE_FLAG;
+      ret = Wow64GetThreadContext (h, context);
+      context->ContextFlags = flags;
+      return ret;
+    }
+
   return Wow64GetThreadContext (h, context);
 }
 
 static inline BOOL
 set_thread_context (HANDLE h, WOW64_CONTEXT *context)
 {
+  if ((context->ContextFlags & CONTEXT_XSTATE_FLAG) != 0)
+    {
+      /* Same limitation as Wow64GetThreadContext above.  */
+      DWORD flags = context->ContextFlags;
+      context->ContextFlags &= ~CONTEXT_EXTENDED_REGISTERS_FLAG;
+      BOOL ret = Wow64SetThreadContext (h, context);
+      context->ContextFlags = flags;
+      if (!ret)
+	return FALSE;
+
+      context->ContextFlags &= ~CONTEXT_XSTATE_FLAG;
+      ret = Wow64SetThreadContext (h, context);
+      context->ContextFlags = flags;
+      return ret;
+    }
+
   return Wow64SetThreadContext (h, context);
 }
 
@@ -642,6 +735,29 @@ enum_process_modules (WOW64_CONTEXT *, HANDLE process,
   return EnumProcessModulesEx (process, modules, size, needed,
 			       LIST_MODULES_32BIT);
 }
+
+static inline BOOL
+get_xstate_features_mask (WOW64_CONTEXT *context, DWORD64 *mask)
+{
+  /* Use lower level function, since there is no Wow64GetXStateFeaturesMask.  */
+  *mask = RtlGetExtendedFeaturesMask (context + 1);
+  return TRUE;
+}
+
+static inline BOOL
+set_xstate_features_mask (WOW64_CONTEXT *context, DWORD64 mask)
+{
+  /* Use lower level function, since there is no Wow64SetXStateFeaturesMask.  */
+  RtlSetExtendedFeaturesMask (context + 1, mask);
+  return TRUE;
+}
+
+static inline PVOID
+locate_xstate_feature (WOW64_CONTEXT *context, DWORD feature, DWORD *length)
+{
+  /* Use lower level function, since there is no Wow64LocateXStateFeature.  */
+  return RtlLocateExtendedFeature (context + 1, feature, length);
+}
 #endif
 
 /* This is available starting with Windows 10.  */
-- 
2.54.0


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

* [PATCH 6/8] Windows gdb: Get available XState features
  2026-07-12 11:32 ` [PATCH 1/8] gdb/testsuite: Add Windows replacement for aligned_alloc Hannes Domani
                     ` (3 preceding siblings ...)
  2026-07-12 11:32   ` [PATCH 5/8] Windows gdb: Prepare XState functions Hannes Domani
@ 2026-07-12 11:32   ` Hannes Domani
  2026-07-12 11:32   ` [PATCH 7/8] Windows gdb: Implement XState (Intel AVX) support Hannes Domani
  2026-07-12 11:32   ` [PATCH 8/8] Windows gdbserver: " Hannes Domani
  6 siblings, 0 replies; 20+ messages in thread
From: Hannes Domani @ 2026-07-12 11:32 UTC (permalink / raw)
  To: gdb-patches

Also prepares the thread context for the additional registers.
---
 gdb/nat/windows-nat.c | 54 ++++++++++++++++++++++++++++++++++++++++++-
 gdb/nat/windows-nat.h |  5 ++++
 2 files changed, 58 insertions(+), 1 deletion(-)

diff --git a/gdb/nat/windows-nat.c b/gdb/nat/windows-nat.c
index cd1f9e7bc64..96c7eb54a45 100644
--- a/gdb/nat/windows-nat.c
+++ b/gdb/nat/windows-nat.c
@@ -20,6 +20,7 @@
 #include "gdbsupport/common-debug.h"
 #include "gdbsupport/gdb_signals.h"
 #include "gdbsupport/gdb_wait.h"
+#include "gdbsupport/x86-xstate.h"
 #include "target/target.h"
 
 #undef GetModuleFileNameEx
@@ -84,6 +85,8 @@ RtlGetExtendedFeaturesMask_ftype *RtlGetExtendedFeaturesMask;
 RtlSetExtendedFeaturesMask_ftype *RtlSetExtendedFeaturesMask;
 RtlLocateExtendedFeature_ftype *RtlLocateExtendedFeature;
 #endif
+
+DWORD64 xstate_features;
 #endif
 
 /* Note that 'debug_events' must be locally defined in the relevant
@@ -308,12 +311,38 @@ windows_process_info::pid_to_exec_file (int pid)
 
 void windows_process_info::initialize_context (windows_thread_info *th)
 {
+#if defined __i386__ || defined __x86_64__
+  if (xstate_features != 0)
+    {
+      DWORD context_flags = with_context (nullptr, [] (auto *context)
+	{
+	  return WindowsContext<decltype(context)>::all;
+	});
+      context_flags |= CONTEXT_XSTATE_FLAG;
+      DWORD xstate_size = 0;
+      InitializeContext (NULL, context_flags, NULL, &xstate_size);
+      th->context_buffer.reset (xmalloc (xstate_size));
+      CONTEXT *context = nullptr;
+      if (!InitializeContext (th->context_buffer.get (),
+			      context_flags, &context, &xstate_size))
+	error ("InitializeContext failure %lu\n", GetLastError ());
 #ifdef __x86_64__
-  if (wow64_process)
+      /* InitializeContext actually initializes a WOW64_CONTEXT when
+	 context_flags contains a WOW64_CONTEXT_* value, so a cast is needed.
+	 */
+      if (wow64_process)
+	th->wow64_context = (WOW64_CONTEXT *) context;
+      else
+#endif
+	th->context = context;
+    }
+#ifdef __x86_64__
+  else if (wow64_process)
     {
       th->context_buffer.reset (xmalloc (sizeof (WOW64_CONTEXT)));
       th->wow64_context = (WOW64_CONTEXT *) th->context_buffer.get ();
     }
+#endif
   else
 #endif
     {
@@ -1289,6 +1318,29 @@ initialize_loadable ()
 
 #undef GPA
 
+#if defined __i386__ || defined __x86_64__
+  if (GetEnabledXStateFeatures != nullptr
+      && InitializeContext != nullptr
+      && GetXStateFeaturesMask != nullptr
+      && SetXStateFeaturesMask != nullptr
+      && LocateXStateFeature != nullptr
+#ifdef __x86_64__
+      && RtlGetExtendedFeaturesMask != nullptr
+      && RtlSetExtendedFeaturesMask != nullptr
+      && RtlLocateExtendedFeature != nullptr
+#endif
+  )
+    {
+      /* Available XState features masked with implemented features.  */
+      xstate_features = GetEnabledXStateFeatures ()
+	& (X86_XSTATE_AVX_AVX512_PKU_MASK | X86_XSTATE_CET_U);
+      /* The extended XState functions are only needed if the available
+	 features exceed SSE.  */
+      if ((xstate_features & ~X86_XSTATE_SSE_MASK) == 0)
+	xstate_features = 0;
+    }
+#endif
+
   return result;
 }
 
diff --git a/gdb/nat/windows-nat.h b/gdb/nat/windows-nat.h
index a344b0a966f..8fcf5e339cb 100644
--- a/gdb/nat/windows-nat.h
+++ b/gdb/nat/windows-nat.h
@@ -760,6 +760,11 @@ locate_xstate_feature (WOW64_CONTEXT *context, DWORD feature, DWORD *length)
 }
 #endif
 
+#if defined __i386__ || defined __x86_64__
+/* Available XState features.  */
+extern DWORD64 xstate_features;
+#endif
+
 /* This is available starting with Windows 10.  */
 #ifndef DBG_REPLY_LATER
 # define DBG_REPLY_LATER 0x40010001L
-- 
2.54.0


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

* [PATCH 7/8] Windows gdb: Implement XState (Intel AVX) support
  2026-07-12 11:32 ` [PATCH 1/8] gdb/testsuite: Add Windows replacement for aligned_alloc Hannes Domani
                     ` (4 preceding siblings ...)
  2026-07-12 11:32   ` [PATCH 6/8] Windows gdb: Get available XState features Hannes Domani
@ 2026-07-12 11:32   ` Hannes Domani
  2026-07-17 12:54     ` Schimpe, Christina
  2026-07-12 11:32   ` [PATCH 8/8] Windows gdbserver: " Hannes Domani
  6 siblings, 1 reply; 20+ messages in thread
From: Hannes Domani @ 2026-07-12 11:32 UTC (permalink / raw)
  To: gdb-patches

---
 gdb/NEWS              |   2 +
 gdb/x86-windows-nat.c | 112 ++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 111 insertions(+), 3 deletions(-)

diff --git a/gdb/NEWS b/gdb/NEWS
index ec9b5a33787..759c544d3b6 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -116,6 +116,8 @@
   intent to remove it in a future release.
   The s390 64-bit target (s390x-*) remains supported.
 
+* Support for Intel AVX variables on Windows.
+
 * Configure changes
 
 ** --with-babeltrace has been removed.  The babeltrace library was
diff --git a/gdb/x86-windows-nat.c b/gdb/x86-windows-nat.c
index 065c551298e..d69081cd912 100644
--- a/gdb/x86-windows-nat.c
+++ b/gdb/x86-windows-nat.c
@@ -27,6 +27,9 @@
 
 #include "i386-tdep.h"
 #include "i387-tdep.h"
+#ifdef __x86_64__
+#include "amd64-tdep.h"
+#endif
 
 using namespace windows_nat;
 
@@ -70,6 +73,8 @@ struct x86_windows_nat_target final : public x86_nat_target<windows_nat_target>
 			   windows_thread_info *th, int r) override;
 
   bool is_sw_breakpoint (const EXCEPTION_RECORD *er) const override;
+
+  const struct target_desc *read_description () override;
 };
 
 /* The current process.  */
@@ -109,7 +114,31 @@ x86_windows_per_inferior::fill_thread_context (windows_thread_info *th)
       if (context->ContextFlags == 0)
 	{
 	  context->ContextFlags = WindowsContext<decltype(context)>::all;
+	  if (xstate_features != 0)
+	    {
+	      context->ContextFlags |= CONTEXT_XSTATE_FLAG;
+	      set_xstate_features_mask (context, xstate_features);
+	    }
 	  CHECK (get_thread_context (th->h, context));
+
+	  if (xstate_features != 0)
+	    {
+	      DWORD64 features = 0;
+	      CHECK (get_xstate_features_mask (context, &features));
+	      DWORD64 zeroed_features = xstate_features & ~features;
+
+	      for (int f = X86_XSTATE_AVX_ID; f <= X86_XSTATE_CET_U_ID; f++)
+		{
+		  DWORD64 flag = 1ULL << f;
+		  if ((zeroed_features & flag) != 0)
+		    {
+		      DWORD size = 0;
+		      void *loc = locate_xstate_feature (context, f, &size);
+		      if (loc != nullptr && size > 0)
+			memset (loc, 0, size);
+		    }
+		}
+	    }
 	}
     });
 }
@@ -198,6 +227,14 @@ x86_windows_nat_target::thread_context_continue (windows_thread_info *th,
 	  if (GetExitCodeThread (th->h, &ec)
 	      && ec == STILL_ACTIVE)
 	    {
+	      DWORD debug_registers = WindowsContext<decltype(context)>::debug;
+	      if (xstate_features != 0
+		  && (context->ContextFlags & ~debug_registers) != 0)
+		{
+		  context->ContextFlags |= CONTEXT_XSTATE_FLAG;
+		  set_xstate_features_mask (context, xstate_features);
+		}
+
 	      BOOL status = set_thread_context (th->h, context);
 
 	      if (!killed)
@@ -227,7 +264,7 @@ x86_windows_nat_target::thread_context_step (windows_thread_info *th,
 
 template<typename Context>
 static char *
-get_context_reg_ptr (Context *context, int r)
+get_context_reg_ptr (Context *context, int r, i386_gdbarch_tdep *tdep)
 {
   const int *mappings;
   int mappings_count;
@@ -247,6 +284,58 @@ get_context_reg_ptr (Context *context, int r)
   char *context_offset;
   if (r < mappings_count)
     context_offset = (char *) context + mappings[r];
+  else if (I387_PKRU_REGNUM (tdep) > 0 && r >= I387_PKRU_REGNUM (tdep)
+      && r < I387_PKEYSEND_REGNUM (tdep))
+    {
+      context_offset = (char *) locate_xstate_feature
+	(context, X86_XSTATE_PKRU_ID, NULL);
+      context_offset += 8 * (r - I387_PKRU_REGNUM (tdep));
+    }
+  else if (I387_ZMM0H_REGNUM (tdep) > 0 && r >= I387_ZMM0H_REGNUM (tdep)
+	   && r < I387_ZMM16H_REGNUM (tdep) && r < I387_ZMMENDH_REGNUM (tdep))
+    {
+      context_offset = (char *) locate_xstate_feature
+	(context, X86_XSTATE_ZMM_H_ID, NULL);
+      context_offset += 32 * (r - I387_ZMM0H_REGNUM (tdep));
+    }
+  else if (I387_ZMM0H_REGNUM (tdep) > 0 && r >= I387_ZMM16H_REGNUM (tdep)
+	   && r < I387_ZMMENDH_REGNUM (tdep))
+    {
+      context_offset = (char *) locate_xstate_feature
+	(context, X86_XSTATE_ZMM_ID, NULL);
+      context_offset += 32 + 64 * (r - I387_ZMM16H_REGNUM (tdep));
+    }
+  else if (I387_K0_REGNUM (tdep) > 0 && r >= I387_K0_REGNUM (tdep)
+	   && r < I387_KEND_REGNUM (tdep))
+    {
+      context_offset = (char *) locate_xstate_feature
+	(context, X86_XSTATE_K_ID, NULL);
+      context_offset += 8 * (r - I387_K0_REGNUM (tdep));
+    }
+  else if (I387_YMM16H_REGNUM (tdep) > 0 && r >= I387_YMM16H_REGNUM (tdep)
+	   && r < I387_YMMH_AVX512_END_REGNUM (tdep))
+    {
+      context_offset = (char *) locate_xstate_feature
+	(context, X86_XSTATE_ZMM_ID, NULL);
+      context_offset += 16 + 64 * (r - I387_YMM16H_REGNUM (tdep));
+    }
+  else if (I387_XMM16_REGNUM (tdep) > 0 && r >= I387_XMM16_REGNUM (tdep)
+	   && r < I387_XMM_AVX512_END_REGNUM (tdep))
+    {
+      context_offset = (char *) locate_xstate_feature
+	(context, X86_XSTATE_ZMM_ID, NULL);
+      context_offset += 64 * (r - I387_XMM16_REGNUM (tdep));
+    }
+  else if (I387_YMM0H_REGNUM (tdep) > 0 && r >= I387_YMM0H_REGNUM (tdep)
+	   && r < I387_YMMENDH_REGNUM (tdep))
+    {
+      context_offset = (char *) locate_xstate_feature
+	(context, X86_XSTATE_AVX_ID, NULL);
+      context_offset += 16 * (r - I387_YMM0H_REGNUM (tdep));
+    }
+  else if (tdep->ssp_regnum > 0 && r == tdep->ssp_regnum)
+    context_offset = (char *) locate_xstate_feature
+      (context, X86_XSTATE_CET_U_ID, NULL);
   else
     gdb_assert_not_reached ("invalid register number %d", r);
 
@@ -267,7 +356,7 @@ x86_windows_nat_target::fetch_one_register (struct regcache *regcache,
   char *context_offset
     = x86_windows_process.with_context (th, [&] (auto *context)
     {
-      return get_context_reg_ptr (context, r);
+      return get_context_reg_ptr (context, r, tdep);
     });
 
   gdb_assert (!gdbarch_read_pc_p (gdbarch));
@@ -333,7 +422,7 @@ x86_windows_nat_target::store_one_register (const struct regcache *regcache,
     = x86_windows_process.with_context (th, [&] (auto *context)
     {
       gdb_assert (context->ContextFlags != 0);
-      return get_context_reg_ptr (context, r);
+      return get_context_reg_ptr (context, r, tdep);
     });
 
   /* GDB treats some registers as 32-bit, where they are in fact only
@@ -368,6 +457,23 @@ x86_windows_nat_target::is_sw_breakpoint (const EXCEPTION_RECORD *er) const
 	  || er->ExceptionCode == STATUS_WX86_BREAKPOINT);
 }
 
+const struct target_desc *
+x86_windows_nat_target::read_description ()
+{
+  if (inferior_ptid == null_ptid)
+    return this->beneath ()->read_description ();
+
+  if (xstate_features == 0)
+    return nullptr;
+
+#ifdef __x86_64__
+  if (!x86_windows_process.wow64_process)
+    return amd64_target_description (xstate_features, false);
+  else
+#endif
+    return i386_target_description (xstate_features, false);
+}
+
 /* Hardware watchpoint support, adapted from go32-nat.c code.  */
 
 /* Pass the address ADDR to the inferior in the I'th debug register.
-- 
2.54.0


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

* [PATCH 8/8] Windows gdbserver: Implement XState (Intel AVX) support
  2026-07-12 11:32 ` [PATCH 1/8] gdb/testsuite: Add Windows replacement for aligned_alloc Hannes Domani
                     ` (5 preceding siblings ...)
  2026-07-12 11:32   ` [PATCH 7/8] Windows gdb: Implement XState (Intel AVX) support Hannes Domani
@ 2026-07-12 11:32   ` Hannes Domani
  6 siblings, 0 replies; 20+ messages in thread
From: Hannes Domani @ 2026-07-12 11:32 UTC (permalink / raw)
  To: gdb-patches

---
 gdbserver/win32-i386-low.cc | 120 ++++++++++++++++++++++++++++++++++--
 gdbserver/win32-low.cc      |  15 +++--
 2 files changed, 124 insertions(+), 11 deletions(-)

diff --git a/gdbserver/win32-i386-low.cc b/gdbserver/win32-i386-low.cc
index b77f6adc6ed..212081e0170 100644
--- a/gdbserver/win32-i386-low.cc
+++ b/gdbserver/win32-i386-low.cc
@@ -253,6 +253,11 @@ i386_get_thread_context (windows_thread_info *th)
 			       | WindowsContext<decltype(context)>::floating
 			       | WindowsContext<decltype(context)>::debug
 			       | extended_registers);
+      if (xstate_features != 0)
+	{
+	  context->ContextFlags |= CONTEXT_XSTATE_FLAG;
+	  set_xstate_features_mask (context, xstate_features);
+	}
 
       BOOL ret = get_thread_context (th->h, context);
       if (!ret)
@@ -267,6 +272,24 @@ i386_get_thread_context (windows_thread_info *th)
 
 	  error (_("GetThreadContext failure %ld\n"), (long) e);
 	}
+
+      DWORD64 features = 0;
+      if (xstate_features != 0
+	  && get_xstate_features_mask (context, &features))
+	{
+	  DWORD64 zeroed_features = xstate_features & ~features;
+	  for (int f = X86_XSTATE_AVX_ID; f <= X86_XSTATE_CET_U_ID; f++)
+	    {
+	      DWORD64 flag = 1ULL << f;
+	      if ((zeroed_features & flag) != 0)
+		{
+		  DWORD size = 0;
+		  void *loc = locate_xstate_feature (context, f, &size);
+		  if (loc != nullptr && size > 0)
+		    memset (loc, 0, size);
+		}
+	    }
+	}
     });
 }
 
@@ -292,6 +315,17 @@ i386_prepare_to_resume (windows_thread_info *th)
 
       th->debug_registers_changed = false;
     }
+
+  windows_process.with_context (th, [&] (auto *context)
+    {
+      DWORD debug_registers = WindowsContext<decltype(context)>::debug;
+      if (xstate_features != 0
+	  && (context->ContextFlags & ~debug_registers) != 0)
+	{
+	  context->ContextFlags |= CONTEXT_XSTATE_FLAG;
+	  set_xstate_features_mask (context, xstate_features);
+	}
+    });
 }
 
 static void
@@ -477,7 +511,7 @@ is_segment_register (int r)
 
 template<typename Context>
 static char *
-get_context_reg_ptr (Context *context, int r)
+get_context_reg_ptr (Context *context, int r, const target_desc *tdesc)
 {
   const int *mappings;
   int mappings_count;
@@ -494,9 +528,80 @@ get_context_reg_ptr (Context *context, int r)
       mappings_count = sizeof (i386_mappings) / sizeof (i386_mappings[0]);
     }
 
+  bool amd64 = register_size (tdesc, 0) == 8;
+  int pkru_regnum, ymm0h_regnum, zmm0h_regnum, k0_regnum;
+  int xmm16_regnum, ymm16h_regnum, zmm16h_regnum;
+  const int num_pkeys_registers = 1;
+  const int num_xmm_registers = amd64 ? 16 : 8;
+  const int num_zmm_high_registers = amd64 ? 16 : 0;
+  const int num_avx512_k_registers = 8;
+
   char *context_offset;
   if (r < mappings_count)
     context_offset = (char *) context + mappings[r];
+  else if ((xstate_features & X86_XSTATE_PKRU) != 0
+	   && r >= (pkru_regnum = find_regno (tdesc, "pkru"))
+	   && r < pkru_regnum + num_pkeys_registers)
+    {
+      context_offset = (char *) locate_xstate_feature
+	(context, X86_XSTATE_PKRU_ID, NULL);
+      context_offset += 8 * (r - pkru_regnum);
+    }
+  else if ((xstate_features & X86_XSTATE_ZMM_H) != 0
+	   && r >= (zmm0h_regnum = find_regno (tdesc, "zmm0h"))
+	   && r < zmm0h_regnum + num_xmm_registers)
+    {
+      context_offset = (char *) locate_xstate_feature
+	(context, X86_XSTATE_ZMM_H_ID, NULL);
+      context_offset += 32 * (r - zmm0h_regnum);
+    }
+  else if ((xstate_features & X86_XSTATE_ZMM) != 0
+	   && num_zmm_high_registers != 0
+	   && r >= (zmm16h_regnum = find_regno (tdesc, "zmm16h"))
+	   && r < zmm16h_regnum + num_zmm_high_registers)
+    {
+      context_offset = (char *) locate_xstate_feature
+	(context, X86_XSTATE_ZMM_ID, NULL);
+      context_offset += 32 + 64 * (r - zmm16h_regnum);
+    }
+  else if ((xstate_features & X86_XSTATE_K) != 0
+	   && r >= (k0_regnum = find_regno (tdesc, "k0"))
+	   && r < k0_regnum + num_avx512_k_registers)
+    {
+      context_offset = (char *) locate_xstate_feature
+	(context, X86_XSTATE_K_ID, NULL);
+      context_offset += 8 * (r - k0_regnum);
+    }
+  else if ((xstate_features & X86_XSTATE_ZMM) != 0
+	   && num_zmm_high_registers != 0
+	   && r >= (ymm16h_regnum = find_regno (tdesc, "ymm16h"))
+	   && r < ymm16h_regnum + num_zmm_high_registers)
+    {
+      context_offset = (char *) locate_xstate_feature
+	(context, X86_XSTATE_ZMM_ID, NULL);
+      context_offset += 16 + 64 * (r - ymm16h_regnum);
+    }
+  else if ((xstate_features & X86_XSTATE_ZMM) != 0
+	   && num_zmm_high_registers != 0
+	   && r >= (xmm16_regnum = find_regno (tdesc, "xmm16"))
+	   && r < xmm16_regnum + num_zmm_high_registers)
+    {
+      context_offset = (char *) locate_xstate_feature
+	(context, X86_XSTATE_ZMM_ID, NULL);
+      context_offset += 64 * (r - xmm16_regnum);
+    }
+  else if ((xstate_features & X86_XSTATE_AVX) != 0
+	   && r >= (ymm0h_regnum = find_regno (tdesc, "ymm0h"))
+	   && r < ymm0h_regnum + num_xmm_registers)
+    {
+      context_offset = (char *) locate_xstate_feature
+	(context, X86_XSTATE_AVX_ID, NULL);
+      context_offset += 16 * (r - ymm0h_regnum);
+    }
+  else if ((xstate_features & X86_XSTATE_CET_U) != 0
+	   && r == find_regno (tdesc, "pl3_ssp"))
+    context_offset = (char *) locate_xstate_feature
+      (context, X86_XSTATE_CET_U_ID, NULL);
   else
     gdb_assert_not_reached ("invalid register number %d", r);
 
@@ -510,7 +615,7 @@ i386_fetch_inferior_register (struct regcache *regcache,
 {
   char *context_offset = windows_process.with_context (th, [&] (auto *context)
     {
-      return get_context_reg_ptr (context, r);
+      return get_context_reg_ptr (context, r, regcache->tdesc);
     });
 
   /* GDB treats some registers as 32-bit, where they are in fact only
@@ -538,7 +643,7 @@ i386_store_inferior_register (struct regcache *regcache,
 {
   char *context_offset = windows_process.with_context (th, [&] (auto *context)
     {
-      return get_context_reg_ptr (context, r);
+      return get_context_reg_ptr (context, r, regcache->tdesc);
     });
 
   /* GDB treats some registers as 32-bit, where they are in fact only
@@ -571,14 +676,17 @@ i386_arch_setup (void)
 {
  target_desc_up tdesc;
 
+  DWORD64 xcr0 = xstate_features;
+  if (xcr0 == 0)
+    xcr0 = X86_XSTATE_SSE_MASK;
+
 #ifdef __x86_64__
-  tdesc = amd64_create_target_description (X86_XSTATE_SSE_MASK, false,
-					   false, false);
+  tdesc = amd64_create_target_description (xcr0, false, false, false);
   init_target_desc (tdesc.get (), amd64_expedite_regs, WINDOWS_OSABI);
   win32_tdesc = std::move (tdesc);
 #endif
 
-  tdesc = i386_create_target_description (X86_XSTATE_SSE_MASK, false, false);
+  tdesc = i386_create_target_description (xcr0, false, false);
   init_target_desc (tdesc.get (), i386_expedite_regs, WINDOWS_OSABI);
 #ifdef __x86_64__
   wow64_win32_tdesc = std::move (tdesc);
diff --git a/gdbserver/win32-low.cc b/gdbserver/win32-low.cc
index 3d85faf0785..ea5b6f8900e 100644
--- a/gdbserver/win32-low.cc
+++ b/gdbserver/win32-low.cc
@@ -33,6 +33,7 @@
 #include <process.h>
 #include "gdbsupport/gdb_tilde_expand.h"
 #include "gdbsupport/common-inferior.h"
+#include "tdesc.h"
 
 using namespace windows_nat;
 
@@ -427,8 +428,9 @@ child_fetch_inferior_registers (struct regcache *regcache, int r)
   int regno;
   windows_thread_info *th = windows_process.find_thread (current_thread->id);
   win32_require_context (th);
-  if (r == -1 || r > NUM_REGS)
-    child_fetch_inferior_registers (regcache, NUM_REGS);
+  if (r == -1)
+    child_fetch_inferior_registers (regcache,
+				    regcache->tdesc->reg_defs.size ());
   else
     for (regno = 0; regno < r; regno++)
       (*the_low_target.fetch_inferior_register) (regcache, th, regno);
@@ -442,8 +444,9 @@ child_store_inferior_registers (struct regcache *regcache, int r)
   int regno;
   windows_thread_info *th = windows_process.find_thread (current_thread->id);
   win32_require_context (th);
-  if (r == -1 || r == 0 || r > NUM_REGS)
-    child_store_inferior_registers (regcache, NUM_REGS);
+  if (r == -1)
+    child_store_inferior_registers (regcache,
+				    regcache->tdesc->reg_defs.size ());
   else
     for (regno = 0; regno < r; regno++)
       (*the_low_target.store_inferior_register) (regcache, th, regno);
@@ -1350,7 +1353,9 @@ void
 initialize_low (void)
 {
   set_target_ops (&the_win32_target);
-  the_low_target.arch_setup ();
 
   initialize_loadable ();
+  /* Has to be done after initialize_loadable, because it uses the xstate
+     functions if available.  */
+  the_low_target.arch_setup ();
 }
-- 
2.54.0


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

* RE: [PATCH 7/8] Windows gdb: Implement XState (Intel AVX) support
  2026-07-12 11:32   ` [PATCH 7/8] Windows gdb: Implement XState (Intel AVX) support Hannes Domani
@ 2026-07-17 12:54     ` Schimpe, Christina
  2026-07-17 13:46       ` Hannes Domani
  0 siblings, 1 reply; 20+ messages in thread
From: Schimpe, Christina @ 2026-07-17 12:54 UTC (permalink / raw)
  To: Hannes Domani, gdb-patches

Hi Hannes, 

Thank you for working on this.
It appears that this patch uses the same commit message header as patch #8. Is it
intentional that these are separate commits?

In any case, IMO, commit messages should not have identical headers. Also, this
patch seems big enough for a commit message which is not header only. :)

Do any AVX-* specific tests pass on Windows now? If so, it would be helpful to
mention that in the commit message as well.
I have not looked at the code yet, but I have one additional comment regarding
the NEWS entry.

> -----Original Message-----
> From: Hannes Domani <ssbssa@yahoo.de>
> Sent: Sonntag, 12. Juli 2026 13:32
> To: gdb-patches@sourceware.org
> Subject: [PATCH 7/8] Windows gdb: Implement XState (Intel AVX) support
> 
> ---
>  gdb/NEWS              |   2 +
>  gdb/x86-windows-nat.c | 112
> ++++++++++++++++++++++++++++++++++++++++--
>  2 files changed, 111 insertions(+), 3 deletions(-)
> 
> diff --git a/gdb/NEWS b/gdb/NEWS
> index ec9b5a33787..759c544d3b6 100644
> --- a/gdb/NEWS
> +++ b/gdb/NEWS
> @@ -116,6 +116,8 @@
>    intent to remove it in a future release.
>    The s390 64-bit target (s390x-*) remains supported.
> 
> +* Support for Intel AVX variables on Windows.

What do you mean with variables? I think it could be helpful if you are
a bit more specific here. For linux there are several examples in the NEWS file,
for instance:

* Support for Intel AVX-512 registers on GNU/Linux.
  Support displaying and modifying Intel AVX-512 registers
  $zmm0 - $zmm31 and $k0 - $k7 on GNU/Linux.

Have you also considered to add some documentation in gdb.texinfo ? 

Regards,
Christina

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

* Re: [PATCH 7/8] Windows gdb: Implement XState (Intel AVX) support
  2026-07-17 12:54     ` Schimpe, Christina
@ 2026-07-17 13:46       ` Hannes Domani
  2026-07-17 14:16         ` Schimpe, Christina
  0 siblings, 1 reply; 20+ messages in thread
From: Hannes Domani @ 2026-07-17 13:46 UTC (permalink / raw)
  To: gdb-patches, Schimpe, Christina

 Am Freitag, 17. Juli 2026 um 14:54:59 MESZ hat Schimpe, Christina <christina.schimpe@intel.com> Folgendes geschrieben:

> Hi Hannes,
> 
> Thank you for working on this.
> It appears that this patch uses the same commit message header as patch #8. Is it
> intentional that these are separate commits?

This one is the gdb part, and #8 is the gdbserver part, that is stated in the title.


> In any case, IMO, commit messages should not have identical headers. Also, this
> patch seems big enough for a commit message which is not header only. :)
> 
> Do any AVX-* specific tests pass on Windows now? If so, it would be helpful to
> mention that in the commit message as well.

I actually planned to add that info, but forgot.

These tests then pass on Windows:
gdb.arch/i386-avx.exp
gdb.arch/i386-avx512.exp


> I have not looked at the code yet, but I have one additional comment regarding
> the NEWS entry.
> 
> > -----Original Message-----
> > From: Hannes Domani <ssbssa@yahoo.de>
> > Sent: Sonntag, 12. Juli 2026 13:32
> > To: gdb-patches@sourceware.org
> > Subject: [PATCH 7/8] Windows gdb: Implement XState (Intel AVX) support
> >
> > ---
> >  gdb/NEWS              |  2 +
> >  gdb/x86-windows-nat.c | 112
> > ++++++++++++++++++++++++++++++++++++++++--
> >  2 files changed, 111 insertions(+), 3 deletions(-)
> >
> > diff --git a/gdb/NEWS b/gdb/NEWS
> > index ec9b5a33787..759c544d3b6 100644
> > --- a/gdb/NEWS
> > +++ b/gdb/NEWS
> > @@ -116,6 +116,8 @@
> >    intent to remove it in a future release.
> >    The s390 64-bit target (s390x-*) remains supported.
> >
> > +* Support for Intel AVX variables on Windows.
> 
> What do you mean with variables? I think it could be helpful if you are
> a bit more specific here. For linux there are several examples in the NEWS file,
> for instance:
> 
> * Support for Intel AVX-512 registers on GNU/Linux.
>   Support displaying and modifying Intel AVX-512 registers
>   $zmm0 - $zmm31 and $k0 - $k7 on GNU/Linux.

That's a good point.
I also wonder why I said variables instead of registers.

These registers are working then:
$xmm0 - $xmm31
$ymm0 - $ymm31
$zmm0 - $zmm31
$k0 - $k7


> Have you also considered to add some documentation in gdb.texinfo ?

Not really.
And I just looked, and couldn't find similar info in there for Linux.


Hannes

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

* RE: [PATCH 7/8] Windows gdb: Implement XState (Intel AVX) support
  2026-07-17 13:46       ` Hannes Domani
@ 2026-07-17 14:16         ` Schimpe, Christina
  2026-07-17 14:49           ` Hannes Domani
  0 siblings, 1 reply; 20+ messages in thread
From: Schimpe, Christina @ 2026-07-17 14:16 UTC (permalink / raw)
  To: Hannes Domani, gdb-patches

> -----Original Message-----
> From: Hannes Domani <ssbssa@yahoo.de>
> Sent: Freitag, 17. Juli 2026 15:47
> To: gdb-patches@sourceware.org; Schimpe, Christina
> <christina.schimpe@intel.com>
> Subject: Re: [PATCH 7/8] Windows gdb: Implement XState (Intel AVX) support
> 
>  Am Freitag, 17. Juli 2026 um 14:54:59 MESZ hat Schimpe, Christina
> <christina.schimpe@intel.com> Folgendes geschrieben:
> 
> > Hi Hannes,
> >
> > Thank you for working on this.
> > It appears that this patch uses the same commit message header as
> > patch #8. Is it intentional that these are separate commits?
> 
> This one is the gdb part, and #8 is the gdbserver part, that is stated in the
> title.

Oups, I wonder how I came to that conclusion.  Sorry for that.

> 
> > In any case, IMO, commit messages should not have identical headers.
> > Also, this patch seems big enough for a commit message which is not
> > header only. :)

This part still stands for the commit message. Since it's not only avx registers,
I believe it makes sense to share more details here.

> > Do any AVX-* specific tests pass on Windows now? If so, it would be
> > helpful to mention that in the commit message as well.
> 
> I actually planned to add that info, but forgot.
> 
> These tests then pass on Windows:
> gdb.arch/i386-avx.exp
> gdb.arch/i386-avx512.exp

What's the state for SSE  (gdb.arch/i386-sse.exp) ?

I also saw you introduced some code for PKRU and the shadow stack pointer. 
We have GDB tests for those registers, too:
- gdb.arch/i386-pkru.exp
- gdb.arch/amd64-shadow-stack*.exp

> 
> > I have not looked at the code yet, but I have one additional comment
> > regarding the NEWS entry.
> >
> > > -----Original Message-----
> > > From: Hannes Domani <ssbssa@yahoo.de>
> > > Sent: Sonntag, 12. Juli 2026 13:32
> > > To: gdb-patches@sourceware.org
> > > Subject: [PATCH 7/8] Windows gdb: Implement XState (Intel AVX)
> > > support
> > >
> > > ---
> > >  gdb/NEWS              |  2 +
> > >  gdb/x86-windows-nat.c | 112
> > > ++++++++++++++++++++++++++++++++++++++++--
> > >  2 files changed, 111 insertions(+), 3 deletions(-)
> > >
> > > diff --git a/gdb/NEWS b/gdb/NEWS
> > > index ec9b5a33787..759c544d3b6 100644
> > > --- a/gdb/NEWS
> > > +++ b/gdb/NEWS
> > > @@ -116,6 +116,8 @@
> > >    intent to remove it in a future release.
> > >    The s390 64-bit target (s390x-*) remains supported.
> > >
> > > +* Support for Intel AVX variables on Windows.
> >
> > What do you mean with variables? I think it could be helpful if you
> > are a bit more specific here. For linux there are several examples in
> > the NEWS file, for instance:
> >
> > * Support for Intel AVX-512 registers on GNU/Linux.
> >   Support displaying and modifying Intel AVX-512 registers
> >   $zmm0 - $zmm31 and $k0 - $k7 on GNU/Linux.
> 
> That's a good point.
> I also wonder why I said variables instead of registers.
> 
> These registers are working then:
> $xmm0 - $xmm31
> $ymm0 - $ymm31
> $zmm0 - $zmm31
> $k0 - $k7
> 
> 
> > Have you also considered to add some documentation in gdb.texinfo ?
> 
> Not really.
> And I just looked, and couldn't find similar info in there for Linux.
> 
> 
> Hannes

Thanks,
Christina
Intel Deutschland GmbH

Registered Address: Dornacher Strasse 1, 85622 Feldkirchen, Germany
Tel: +49 89 991 430, www.intel.de
Managing Directors: Harry Demas, Jeffrey Schneiderman, Yin Chong Sorrell
Chairperson of the Supervisory Board: Nicole Lau
Registered Seat: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928

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

* RE: [PATCH 5/8] Windows gdb: Prepare XState functions
  2026-07-12 11:32   ` [PATCH 5/8] Windows gdb: Prepare XState functions Hannes Domani
@ 2026-07-17 14:41     ` Schimpe, Christina
  2026-07-17 15:04       ` Hannes Domani
  0 siblings, 1 reply; 20+ messages in thread
From: Schimpe, Christina @ 2026-07-17 14:41 UTC (permalink / raw)
  To: Hannes Domani, gdb-patches

> -----Original Message-----
> From: Hannes Domani <ssbssa@yahoo.de>
> Sent: Sonntag, 12. Juli 2026 13:32
> To: gdb-patches@sourceware.org
> Subject: [PATCH 5/8] Windows gdb: Prepare XState functions
> 
> These functions will then be used to access the XState registers.
> ---
>  gdb/nat/windows-nat.c |  31 +++++++++++  gdb/nat/windows-nat.h | 116
> ++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 147 insertions(+)
> 
> diff --git a/gdb/nat/windows-nat.c b/gdb/nat/windows-nat.c index
> 689601f3a82..cd1f9e7bc64 100644
> --- a/gdb/nat/windows-nat.c
> +++ b/gdb/nat/windows-nat.c
> @@ -73,6 +73,19 @@ InitializeProcThreadAttributeList_ftype
> *InitializeProcThreadAttributeList;
>  UpdateProcThreadAttribute_ftype *UpdateProcThreadAttribute;
> DeleteProcThreadAttributeList_ftype *DeleteProcThreadAttributeList;
> 
> +#if defined __i386__ || defined __x86_64__
> +GetEnabledXStateFeatures_ftype *GetEnabledXStateFeatures;
> +InitializeContext_ftype *InitializeContext; GetXStateFeaturesMask_ftype
> +*GetXStateFeaturesMask; SetXStateFeaturesMask_ftype
> +*SetXStateFeaturesMask; LocateXStateFeature_ftype *LocateXStateFeature;
> +#ifdef __x86_64__ RtlGetExtendedFeaturesMask_ftype
> +*RtlGetExtendedFeaturesMask; RtlSetExtendedFeaturesMask_ftype
> +*RtlSetExtendedFeaturesMask; RtlLocateExtendedFeature_ftype
> +*RtlLocateExtendedFeature; #endif #endif
> +
>  /* Note that 'debug_events' must be locally defined in the relevant
>     functions.  */
>  #define DEBUG_EVENTS(fmt, ...) \
> @@ -1191,6 +1204,14 @@ initialize_loadable ()
>        GPA (hm, InitializeProcThreadAttributeList);
>        GPA (hm, UpdateProcThreadAttribute);
>        GPA (hm, DeleteProcThreadAttributeList);
> +
> +#if defined __i386__ || defined __x86_64__
> +      GPA (hm, GetEnabledXStateFeatures);
> +      GPA (hm, InitializeContext);
> +      GPA (hm, GetXStateFeaturesMask);
> +      GPA (hm, SetXStateFeaturesMask);
> +      GPA (hm, LocateXStateFeature);
> +#endif
>      }
> 
>    /* Set variables to dummy versions of these processes if the function @@ -
> 1256,6 +1277,16 @@ initialize_loadable ()
>  	GPA (hm, GetThreadDescription);
>      }
> 
> +#ifdef __x86_64__
> +  hm = LoadLibrary (TEXT ("ntdll.dll"));
> +  if (hm)
> +    {
> +      GPA (hm, RtlGetExtendedFeaturesMask);
> +      GPA (hm, RtlSetExtendedFeaturesMask);
> +      GPA (hm, RtlLocateExtendedFeature);
> +    }
> +#endif
> +
>  #undef GPA
> 
>    return result;
> diff --git a/gdb/nat/windows-nat.h b/gdb/nat/windows-nat.h index
> 76688fa90da..a344b0a966f 100644
> --- a/gdb/nat/windows-nat.h
> +++ b/gdb/nat/windows-nat.h
> @@ -35,6 +35,9 @@
>  #define CONTEXT_EXTENDED_REGISTERS 0
>  #endif
> 
> +#define CONTEXT_EXTENDED_REGISTERS_FLAG	0x20
> +#define CONTEXT_XSTATE_FLAG		0x40
> +
>  namespace windows_nat
>  {
> 
> @@ -456,6 +459,14 @@ extern BOOL create_process (const wchar_t
> *image, wchar_t *command_line,  #define InitializeProcThreadAttributeList
> dyn_InitializeProcThreadAttributeList
>  #define UpdateProcThreadAttribute dyn_UpdateProcThreadAttribute
> #define DeleteProcThreadAttributeList dyn_DeleteProcThreadAttributeList
> +#define GetEnabledXStateFeatures	dyn_GetEnabledXStateFeatures
> +#define InitializeContext		dyn_InitializeContext
> +#define GetXStateFeaturesMask		dyn_GetXStateFeaturesMask
> +#define SetXStateFeaturesMask		dyn_SetXStateFeaturesMask
> +#define LocateXStateFeature		dyn_LocateXStateFeature
> +#define RtlGetExtendedFeaturesMask	dyn_RtlGetExtendedFeaturesMask
> +#define RtlSetExtendedFeaturesMask	dyn_RtlSetExtendedFeaturesMask
> +#define RtlLocateExtendedFeature	dyn_RtlLocateExtendedFeature
> 
>  typedef BOOL WINAPI (AdjustTokenPrivileges_ftype) (HANDLE, BOOL,
>  						   PTOKEN_PRIVILEGES,
> @@ -550,6 +561,35 @@ extern DeleteProcThreadAttributeList_ftype
> *DeleteProcThreadAttributeList;
> 
>  extern bool disable_randomization_available ();
> 
> +#if defined __i386__ || defined __x86_64__ typedef DWORD64 (WINAPI
> +GetEnabledXStateFeatures_ftype) (); extern
> +GetEnabledXStateFeatures_ftype *GetEnabledXStateFeatures;
> +
> +typedef BOOL (WINAPI InitializeContext_ftype) (PVOID, DWORD,
> +					       PCONTEXT*, PDWORD);
> +extern InitializeContext_ftype *InitializeContext;
> +
> +typedef BOOL (WINAPI GetXStateFeaturesMask_ftype) (PCONTEXT,
> PDWORD64);
> +extern GetXStateFeaturesMask_ftype *GetXStateFeaturesMask;
> +
> +typedef BOOL (WINAPI SetXStateFeaturesMask_ftype) (PCONTEXT,
> DWORD64);
> +extern SetXStateFeaturesMask_ftype *SetXStateFeaturesMask;
> +
> +typedef PVOID (WINAPI LocateXStateFeature_ftype) (PCONTEXT, DWORD,
> +PDWORD); extern LocateXStateFeature_ftype *LocateXStateFeature;
> +
> +#ifdef __x86_64__
> +typedef DWORD64 (WINAPI RtlGetExtendedFeaturesMask_ftype) (PVOID);
> +extern RtlGetExtendedFeaturesMask_ftype *RtlGetExtendedFeaturesMask;
> +
> +typedef VOID (WINAPI RtlSetExtendedFeaturesMask_ftype) (PVOID,
> +DWORD64); extern RtlSetExtendedFeaturesMask_ftype
> +*RtlSetExtendedFeaturesMask;
> +
> +typedef PVOID (WINAPI RtlLocateExtendedFeature_ftype) (PVOID, DWORD,
> +PDWORD); extern RtlLocateExtendedFeature_ftype
> +*RtlLocateExtendedFeature; #endif #endif
> +
>  /* Helper classes to get the correct ContextFlags values based on the
>     used type (CONTEXT or WOW64_CONTEXT).  */
> 
> @@ -615,16 +655,69 @@ enum_process_modules (CONTEXT *, HANDLE
> process,
>    return EnumProcessModules (process, modules, size, needed);  }
> 
> +#if defined __i386__ || defined __x86_64__ static inline BOOL
> +get_xstate_features_mask (CONTEXT *context, DWORD64 *mask) {
> +  return GetXStateFeaturesMask (context, mask); }
> +
> +static inline BOOL
> +set_xstate_features_mask (CONTEXT *context, DWORD64 mask) {
> +  return SetXStateFeaturesMask (context, mask); }
> +
> +static inline PVOID
> +locate_xstate_feature (CONTEXT *context, DWORD feature, DWORD
> *length)
> +{
> +  return LocateXStateFeature (context, feature, length); } #endif
> +
>  #ifdef __x86_64__
>  static inline BOOL
>  get_thread_context (HANDLE h, WOW64_CONTEXT *context)  {
> +  if ((context->ContextFlags & CONTEXT_XSTATE_FLAG) != 0)
> +    {
> +      /* Wow64GetThreadContext doesn't handle
> CONTEXT_EXTENDED_REGISTERS and
> +	 CONTEXT_XSTATE combined correctly, but separate they work fine.
> */
> +      DWORD flags = context->ContextFlags;
> +      context->ContextFlags &= ~CONTEXT_EXTENDED_REGISTERS_FLAG;
> +      BOOL ret = Wow64GetThreadContext (h, context);
> +      context->ContextFlags = flags;
> +      if (!ret)
> +	return FALSE;
> +
> +      context->ContextFlags &= ~CONTEXT_XSTATE_FLAG;
> +      ret = Wow64GetThreadContext (h, context);
> +      context->ContextFlags = flags;
> +      return ret;
> +    }
> +
>    return Wow64GetThreadContext (h, context);  }
> 
>  static inline BOOL
>  set_thread_context (HANDLE h, WOW64_CONTEXT *context)  {
> +  if ((context->ContextFlags & CONTEXT_XSTATE_FLAG) != 0)
> +    {
> +      /* Same limitation as Wow64GetThreadContext above.  */
> +      DWORD flags = context->ContextFlags;
> +      context->ContextFlags &= ~CONTEXT_EXTENDED_REGISTERS_FLAG;
> +      BOOL ret = Wow64SetThreadContext (h, context);
> +      context->ContextFlags = flags;
> +      if (!ret)
> +	return FALSE;
> +
> +      context->ContextFlags &= ~CONTEXT_XSTATE_FLAG;
> +      ret = Wow64SetThreadContext (h, context);
> +      context->ContextFlags = flags;
> +      return ret;
> +    }
> +
>    return Wow64SetThreadContext (h, context);  }
> 
> @@ -642,6 +735,29 @@ enum_process_modules (WOW64_CONTEXT *,
> HANDLE process,
>    return EnumProcessModulesEx (process, modules, size, needed,
>  			       LIST_MODULES_32BIT);
>  }
> +
> +static inline BOOL
> +get_xstate_features_mask (WOW64_CONTEXT *context, DWORD64 *mask)
> {
> +  /* Use lower level function, since there is no
> +Wow64GetXStateFeaturesMask.  */
> +  *mask = RtlGetExtendedFeaturesMask (context + 1);
> +  return TRUE;
> +}
> +
> +static inline BOOL
> +set_xstate_features_mask (WOW64_CONTEXT *context, DWORD64 mask) {
> +  /* Use lower level function, since there is no
> +Wow64SetXStateFeaturesMask.  */
> +  RtlSetExtendedFeaturesMask (context + 1, mask);
> +  return TRUE;
> +}
> +
> +static inline PVOID
> +locate_xstate_feature (WOW64_CONTEXT *context, DWORD feature,
> DWORD
> +*length) {
> +  /* Use lower level function, since there is no
> +Wow64LocateXStateFeature.  */
> +  return RtlLocateExtendedFeature (context + 1, feature, length); }
>  #endif
> 
>  /* This is available starting with Windows 10.  */
> --
> 2.54.0
> 

For this and the following patch:  I can see that you introduced x86 specific code,
but used the generic windows-nat.c/.h files for it. In gdb linux code we try to keep
arch specific details in separate files. 

In an earlier patch you tried to keep it separate for windows, too:
"Move x86 register code into x86-windows-nat.c ". 

I am not familiar with windows specific code, but do you think moving this to an arch
specific file (for instance gdb/x86-windows-nat.c) is an option?

Thanks,
Christina

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

* Re: [PATCH 7/8] Windows gdb: Implement XState (Intel AVX) support
  2026-07-17 14:16         ` Schimpe, Christina
@ 2026-07-17 14:49           ` Hannes Domani
  2026-07-17 15:26             ` Schimpe, Christina
  0 siblings, 1 reply; 20+ messages in thread
From: Hannes Domani @ 2026-07-17 14:49 UTC (permalink / raw)
  To: gdb-patches, Schimpe, Christina

 Am Freitag, 17. Juli 2026 um 16:16:31 MESZ hat Schimpe, Christina <christina.schimpe@intel.com> Folgendes geschrieben:

> > -----Original Message-----
> > From: Hannes Domani <ssbssa@yahoo.de>
> > Sent: Freitag, 17. Juli 2026 15:47
> > To: gdb-patches@sourceware.org; Schimpe, Christina
> > <christina.schimpe@intel.com>
> > Subject: Re: [PATCH 7/8] Windows gdb: Implement XState (Intel AVX) support
> >
> >  Am Freitag, 17. Juli 2026 um 14:54:59 MESZ hat Schimpe, Christina
> > <christina.schimpe@intel.com> Folgendes geschrieben:
> >
> > > Hi Hannes,
> > >
> > > Thank you for working on this.
> > > It appears that this patch uses the same commit message header as
> > > patch #8. Is it intentional that these are separate commits?
> >
> > This one is the gdb part, and #8 is the gdbserver part, that is stated in the
> > title.
> 
> Oups, I wonder how I came to that conclusion.  Sorry for that.
> 
> >
> > > In any case, IMO, commit messages should not have identical headers.
> > > Also, this patch seems big enough for a commit message which is not
> > > header only. :)
> 
> This part still stands for the commit message. Since it's not only avx registers,
> I believe it makes sense to share more details here.

Yes, I will do that.


> > > Do any AVX-* specific tests pass on Windows now? If so, it would be
> > > helpful to mention that in the commit message as well.
> >
> > I actually planned to add that info, but forgot.
> >
> > These tests then pass on Windows:
> > gdb.arch/i386-avx.exp
> > gdb.arch/i386-avx512.exp
> 
> What's the state for SSE  (gdb.arch/i386-sse.exp) ?

i386-sse.exp works since patch #1, it was only a compile issue of the test itself.
I will mention this in the patch as well.


> I also saw you introduced some code for PKRU and the shadow stack pointer.
> We have GDB tests for those registers, too:
> - gdb.arch/i386-pkru.exp
> - gdb.arch/amd64-shadow-stack*.exp

For these I just added the equivalent code as is done on Linux, without really
knowing what they are for.

i386-pkru.exp tells me:

(gdb) print have_pkru()
$1 = 0
(gdb) PASS: gdb.arch/i386-pkru.exp: probe PKRU support
UNSUPPORTED: gdb.arch/i386-pkru.exp: processor does not support protection key feature.

Do only certain CPU's have this register?

And amd64-shadow-stack.exp:

(gdb) print $pl3_ssp
$1 = (void *) 0x0
(gdb) FAIL: gdb.arch/amd64-shadow-stack.exp: test shadow stack support

No idea if that should work, since Windows is supplying data for the $pl3_ssp register.


Hannes

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

* Re: [PATCH 5/8] Windows gdb: Prepare XState functions
  2026-07-17 14:41     ` Schimpe, Christina
@ 2026-07-17 15:04       ` Hannes Domani
  2026-07-17 15:07         ` Hannes Domani
  0 siblings, 1 reply; 20+ messages in thread
From: Hannes Domani @ 2026-07-17 15:04 UTC (permalink / raw)
  To: gdb-patches, Schimpe, Christina

 Am Freitag, 17. Juli 2026 um 16:41:54 MESZ hat Schimpe, Christina <christina.schimpe@intel.com> Folgendes geschrieben:

> > -----Original Message-----
> > From: Hannes Domani <ssbssa@yahoo.de>
> > Sent: Sonntag, 12. Juli 2026 13:32
> > To: gdb-patches@sourceware.org
> > Subject: [PATCH 5/8] Windows gdb: Prepare XState functions
> >
> > These functions will then be used to access the XState registers.
> > ---
> >  gdb/nat/windows-nat.c |  31 +++++++++++  gdb/nat/windows-nat.h | 116
> > ++++++++++++++++++++++++++++++++++++++++++
> 
> For this and the following patch:  I can see that you introduced x86 specific code,
> but used the generic windows-nat.c/.h files for it. In gdb linux code we try to keep
> arch specific details in separate files.
> 
> In an earlier patch you tried to keep it separate for windows, too:
> "Move x86 register code into x86-windows-nat.c ".
> 
> I am not familiar with windows specific code, but do you think moving this to an arch
> specific file (for instance gdb/x86-windows-nat.c) is an option?

Yes, I tried keeping them separate, but these functions are also used by
gdbserver, so they have to be in a nat/ header, which makes this a bit
more complicated.

But I recently found out that Windows apparently also provides SVE registers
for ARM64 with these same XState functions [1], so if we plan to support that,
we would probably just move them back here anyways.


Hannes

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

* Re: [PATCH 5/8] Windows gdb: Prepare XState functions
  2026-07-17 15:04       ` Hannes Domani
@ 2026-07-17 15:07         ` Hannes Domani
  2026-07-17 16:22           ` Schimpe, Christina
  0 siblings, 1 reply; 20+ messages in thread
From: Hannes Domani @ 2026-07-17 15:07 UTC (permalink / raw)
  To: gdb-patches, Schimpe, Christina

 Am Freitag, 17. Juli 2026 um 17:04:51 MESZ hat Hannes Domani <ssbssa@yahoo.de> Folgendes geschrieben:

> Am Freitag, 17. Juli 2026 um 16:41:54 MESZ hat Schimpe, Christina <christina.schimpe@intel.com> Folgendes geschrieben:
> 
> > > -----Original Message-----
> > > From: Hannes Domani <ssbssa@yahoo.de>
> > > Sent: Sonntag, 12. Juli 2026 13:32
> > > To: gdb-patches@sourceware.org
> > > Subject: [PATCH 5/8] Windows gdb: Prepare XState functions
> > >
> > > These functions will then be used to access the XState registers.
> > > ---
> > >  gdb/nat/windows-nat.c |  31 +++++++++++  gdb/nat/windows-nat.h | 116
> > > ++++++++++++++++++++++++++++++++++++++++++
> > 
> > For this and the following patch:  I can see that you introduced x86 specific code,
> > but used the generic windows-nat.c/.h files for it. In gdb linux code we try to keep
> > arch specific details in separate files.
> > 
> > In an earlier patch you tried to keep it separate for windows, too:
> > "Move x86 register code into x86-windows-nat.c ".
> > 
> > I am not familiar with windows specific code, but do you think moving this to an arch
> > specific file (for instance gdb/x86-windows-nat.c) is an option?
> 
> Yes, I tried keeping them separate, but these functions are also used by
> gdbserver, so they have to be in a nat/ header, which makes this a bit
> more complicated.
> 
> But I recently found out that Windows apparently also provides SVE registers
> for ARM64 with these same XState functions [1], so if we plan to support that,
> we would probably just move them back here anyways.

Of course I had to forget to include the link...

[1] https://github.com/llvm/llvm-project/pull/205906


Hannes

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

* RE: [PATCH 7/8] Windows gdb: Implement XState (Intel AVX) support
  2026-07-17 14:49           ` Hannes Domani
@ 2026-07-17 15:26             ` Schimpe, Christina
  2026-07-17 16:26               ` Hannes Domani
  0 siblings, 1 reply; 20+ messages in thread
From: Schimpe, Christina @ 2026-07-17 15:26 UTC (permalink / raw)
  To: Hannes Domani, gdb-patches

> -----Original Message-----
> From: Hannes Domani <ssbssa@yahoo.de>
> Sent: Freitag, 17. Juli 2026 16:50
> To: gdb-patches@sourceware.org; Schimpe, Christina
> <christina.schimpe@intel.com>
> Subject: Re: [PATCH 7/8] Windows gdb: Implement XState (Intel AVX) support
> 
>  Am Freitag, 17. Juli 2026 um 16:16:31 MESZ hat Schimpe, Christina
> <christina.schimpe@intel.com> Folgendes geschrieben:
> 
> > > -----Original Message-----
> > > From: Hannes Domani <ssbssa@yahoo.de>
> > > Sent: Freitag, 17. Juli 2026 15:47
> > > To: gdb-patches@sourceware.org; Schimpe, Christina
> > > <christina.schimpe@intel.com>
> > > Subject: Re: [PATCH 7/8] Windows gdb: Implement XState (Intel AVX)
> > > support
> > >
> > >  Am Freitag, 17. Juli 2026 um 14:54:59 MESZ hat Schimpe, Christina
> > ><christina.schimpe@intel.com> Folgendes geschrieben:
> > >
> > > > Hi Hannes,
> > > >
> > > > Thank you for working on this.
> > > > It appears that this patch uses the same commit message header as
> > > > patch #8. Is it intentional that these are separate commits?
> > >
> > > This one is the gdb part, and #8 is the gdbserver part, that is
> > > stated in the title.
> >
> > Oups, I wonder how I came to that conclusion.  Sorry for that.
> >
> > >
> > > > In any case, IMO, commit messages should not have identical headers.
> > > > Also, this patch seems big enough for a commit message which is
> > > > not header only. :)
> >
> > This part still stands for the commit message. Since it's not only avx
> > registers, I believe it makes sense to share more details here.
> 
> Yes, I will do that.
> 
> 
> > > > Do any AVX-* specific tests pass on Windows now? If so, it would
> > > > be helpful to mention that in the commit message as well.
> > >
> > > I actually planned to add that info, but forgot.
> > >
> > > These tests then pass on Windows:
> > > gdb.arch/i386-avx.exp
> > > gdb.arch/i386-avx512.exp
> >
> > What's the state for SSE  (gdb.arch/i386-sse.exp) ?
> 
> i386-sse.exp works since patch #1, it was only a compile issue of the test
> itself.
> I will mention this in the patch as well.

Thanks.

> 
> > I also saw you introduced some code for PKRU and the shadow stack
> pointer.
> > We have GDB tests for those registers, too:
> > - gdb.arch/i386-pkru.exp
> > - gdb.arch/amd64-shadow-stack*.exp
> 
> For these I just added the equivalent code as is done on Linux, without really
> knowing what they are for.
> 
> i386-pkru.exp tells me:
> 
> (gdb) print have_pkru()
> $1 = 0
> (gdb) PASS: gdb.arch/i386-pkru.exp: probe PKRU support
> UNSUPPORTED: gdb.arch/i386-pkru.exp: processor does not support
> protection key feature.
> 
> Do only certain CPU's have this register?

Most recent CPUs should have it. To be sure you can check if the corresponding bit
is configured in xcr0.
I believe for windows this should be the mask returned by get_xstate_features_mask.

If your cpu does have it, I think you must look at the test in more detail to find out why it's
unsupported. It might need some adaptions for windows.

> 
> And amd64-shadow-stack.exp:
> 
> (gdb) print $pl3_ssp
> $1 = (void *) 0x0
> (gdb) FAIL: gdb.arch/amd64-shadow-stack.exp: test shadow stack support
> 
> No idea if that should work, since Windows is supplying data for the $pl3_ssp
> register.
> 
> 
> Hannes

Without knowing any of the details in windows I believe adding full support for CET shadow
stack might need some more changes. At least for linux, this was the case:
https://inbox.sourceware.org/gdb-patches/20250821171029.1555603-1-christina.schimpe@intel.com/

I believe it would be better to handle this in a separate patch-(series).
This also applies for any other register that you add and whose dedicated test does not pass.

Does that make sense to you?

Christina 
Intel Deutschland GmbH

Registered Address: Dornacher Strasse 1, 85622 Feldkirchen, Germany
Tel: +49 89 991 430, www.intel.de
Managing Directors: Harry Demas, Jeffrey Schneiderman, Yin Chong Sorrell
Chairperson of the Supervisory Board: Nicole Lau
Registered Seat: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928

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

* RE: [PATCH 5/8] Windows gdb: Prepare XState functions
  2026-07-17 15:07         ` Hannes Domani
@ 2026-07-17 16:22           ` Schimpe, Christina
  0 siblings, 0 replies; 20+ messages in thread
From: Schimpe, Christina @ 2026-07-17 16:22 UTC (permalink / raw)
  To: Hannes Domani, gdb-patches

> -----Original Message-----
> From: Hannes Domani <ssbssa@yahoo.de>
> Sent: Freitag, 17. Juli 2026 17:07
> To: gdb-patches@sourceware.org; Schimpe, Christina
> <christina.schimpe@intel.com>
> Subject: Re: [PATCH 5/8] Windows gdb: Prepare XState functions
> 
>  Am Freitag, 17. Juli 2026 um 17:04:51 MESZ hat Hannes Domani
> <ssbssa@yahoo.de> Folgendes geschrieben:
> 
> > Am Freitag, 17. Juli 2026 um 16:41:54 MESZ hat Schimpe, Christina
> <christina.schimpe@intel.com> Folgendes geschrieben:
> >
> > > > -----Original Message-----
> > > > From: Hannes Domani <ssbssa@yahoo.de>
> > > > Sent: Sonntag, 12. Juli 2026 13:32
> > > > To: gdb-patches@sourceware.org
> > > > Subject: [PATCH 5/8] Windows gdb: Prepare XState functions
> > > >
> > > > These functions will then be used to access the XState registers.
> > > > ---
> > > >  gdb/nat/windows-nat.c |  31 +++++++++++  gdb/nat/windows-nat.h |
> > > >116
> > > > ++++++++++++++++++++++++++++++++++++++++++
> > >
> > > For this and the following patch:  I can see that you introduced x86
> > > specific code, but used the generic windows-nat.c/.h files for it.
> > > In gdb linux code we try to keep arch specific details in separate files.
> > >
> > > In an earlier patch you tried to keep it separate for windows, too:
> > > "Move x86 register code into x86-windows-nat.c ".
> > >
> > > I am not familiar with windows specific code, but do you think
> > > moving this to an arch specific file (for instance gdb/x86-windows-nat.c) is
> an option?
> >
> > Yes, I tried keeping them separate, but these functions are also used
> > by gdbserver, so they have to be in a nat/ header, which makes this a
> > bit more complicated.

Ok, I understand.

> > But I recently found out that Windows apparently also provides SVE
> > registers for ARM64 with these same XState functions [1], so if we
> > plan to support that, we would probably just move them back here
> anyways.
> 
> Of course I had to forget to include the link...
> 
> [1] https://github.com/llvm/llvm-project/pull/205906

Hm, I am a bit confused about the windows interfaces. If they are meant to be
architecture independent it seems that this and the following patch are almost
arch independent, too. Except for these lines and their corresponding include:

~~~
      /* Available XState features masked with implemented features.  */
      xstate_features = GetEnabledXStateFeatures ()
	& (X86_XSTATE_AVX_AVX512_PKU_MASK | X86_XSTATE_CET_U);
      /* The extended XState functions are only needed if the available
	 features exceed SSE.  */
      if ((xstate_features & ~X86_XSTATE_SSE_MASK) == 0)
	xstate_features = 0;
~~~

In any case, maybe someone else with a bit more windows background has
another opinion on this, too.

Christina

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

* Re: [PATCH 7/8] Windows gdb: Implement XState (Intel AVX) support
  2026-07-17 15:26             ` Schimpe, Christina
@ 2026-07-17 16:26               ` Hannes Domani
  2026-07-17 19:06                 ` Schimpe, Christina
  0 siblings, 1 reply; 20+ messages in thread
From: Hannes Domani @ 2026-07-17 16:26 UTC (permalink / raw)
  To: gdb-patches, Schimpe, Christina

 Am Freitag, 17. Juli 2026 um 17:26:14 MESZ hat Schimpe, Christina <christina.schimpe@intel.com> Folgendes geschrieben:

> > -----Original Message-----
> > From: Hannes Domani <ssbssa@yahoo.de>
> > Sent: Freitag, 17. Juli 2026 16:50
> > To: gdb-patches@sourceware.org; Schimpe, Christina
> > <christina.schimpe@intel.com>
> > Subject: Re: [PATCH 7/8] Windows gdb: Implement XState (Intel AVX) support
> >
> >  Am Freitag, 17. Juli 2026 um 16:16:31 MESZ hat Schimpe, Christina
> > <christina.schimpe@intel.com> Folgendes geschrieben:
> >
> > > > -----Original Message-----
> > > > From: Hannes Domani <ssbssa@yahoo.de>
> > > > Sent: Freitag, 17. Juli 2026 15:47
> > > > To: gdb-patches@sourceware.org; Schimpe, Christina
> > > > <christina.schimpe@intel.com>
> > > > Subject: Re: [PATCH 7/8] Windows gdb: Implement XState (Intel AVX)
> > > > support
> > > >
> > > >  Am Freitag, 17. Juli 2026 um 14:54:59 MESZ hat Schimpe, Christina
> > > ><christina.schimpe@intel.com> Folgendes geschrieben:
> > > >
> > > > > Hi Hannes,
> > > > >
> > > > > Thank you for working on this.
> > > > > It appears that this patch uses the same commit message header as
> > > > > patch #8. Is it intentional that these are separate commits?
> > > >
> > > > This one is the gdb part, and #8 is the gdbserver part, that is
> > > > stated in the title.
> > >
> > > Oups, I wonder how I came to that conclusion.  Sorry for that.
> > >
> > > >
> > > > > In any case, IMO, commit messages should not have identical headers.
> > > > > Also, this patch seems big enough for a commit message which is
> > > > > not header only. :)
> > >
> > > This part still stands for the commit message. Since it's not only avx
> > > registers, I believe it makes sense to share more details here.
> >
> > Yes, I will do that.
> >
> >
> > > > > Do any AVX-* specific tests pass on Windows now? If so, it would
> > > > > be helpful to mention that in the commit message as well.
> > > >
> > > > I actually planned to add that info, but forgot.
> > > >
> > > > These tests then pass on Windows:
> > > > gdb.arch/i386-avx.exp
> > > > gdb.arch/i386-avx512.exp
> > >
> > > What's the state for SSE  (gdb.arch/i386-sse.exp) ?
> >
> > i386-sse.exp works since patch #1, it was only a compile issue of the test
> > itself.
> > I will mention this in the patch as well.
> 
> Thanks.
> 
> >
> > > I also saw you introduced some code for PKRU and the shadow stack
> > pointer.
> > > We have GDB tests for those registers, too:
> > > - gdb.arch/i386-pkru.exp
> > > - gdb.arch/amd64-shadow-stack*.exp
> >
> > For these I just added the equivalent code as is done on Linux, without really
> > knowing what they are for.
> >
> > i386-pkru.exp tells me:
> >
> > (gdb) print have_pkru()
> > $1 = 0
> > (gdb) PASS: gdb.arch/i386-pkru.exp: probe PKRU support
> > UNSUPPORTED: gdb.arch/i386-pkru.exp: processor does not support
> > protection key feature.
> >
> > Do only certain CPU's have this register?
> 
> Most recent CPUs should have it. To be sure you can check if the corresponding bit
> is configured in xcr0.

I thought that's what have_pkru() does, but I might be wrong about that.


> I believe for windows this should be the mask returned by get_xstate_features_mask.

You probably mean GetEnabledXStateFeatures, but yes, it also tells me my CPU
doesn't support this.


> If your cpu does have it, I think you must look at the test in more detail to find out why it's
> unsupported. It might need some adaptions for windows.

Google tells me only not all recent CPUs have this, is mine one of them?:
11th Gen Intel(R) Core(TM) i7-11850H


> > And amd64-shadow-stack.exp:
> >
> > (gdb) print $pl3_ssp
> > $1 = (void *) 0x0
> > (gdb) FAIL: gdb.arch/amd64-shadow-stack.exp: test shadow stack support
> >
> > No idea if that should work, since Windows is supplying data for the $pl3_ssp
> > register.
> >
> >
> > Hannes
> 
> Without knowing any of the details in windows I believe adding full support for CET shadow
> stack might need some more changes. At least for linux, this was the case:
> https://inbox.sourceware.org/gdb-patches/20250821171029.1555603-1-christina.schimpe@intel.com/
> 
> I believe it would be better to handle this in a separate patch-(series).
> This also applies for any other register that you add and whose dedicated test does not pass.
> 
> Does that make sense to you?

I was wondering if it isn't the compiler or linker on windows (or maybe windows itself?)
that doesn't support this -fcf-protection=return stuff.


Hannes

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

* RE: [PATCH 7/8] Windows gdb: Implement XState (Intel AVX) support
  2026-07-17 16:26               ` Hannes Domani
@ 2026-07-17 19:06                 ` Schimpe, Christina
  2026-07-18 16:06                   ` Hannes Domani
  0 siblings, 1 reply; 20+ messages in thread
From: Schimpe, Christina @ 2026-07-17 19:06 UTC (permalink / raw)
  To: Hannes Domani, gdb-patches

> -----Original Message-----
> From: Hannes Domani <ssbssa@yahoo.de>
> Sent: Freitag, 17. Juli 2026 18:27
> To: gdb-patches@sourceware.org; Schimpe, Christina
> <christina.schimpe@intel.com>
> Subject: Re: [PATCH 7/8] Windows gdb: Implement XState (Intel AVX) support
> 
>  Am Freitag, 17. Juli 2026 um 17:26:14 MESZ hat Schimpe, Christina
> <christina.schimpe@intel.com> Folgendes geschrieben:
> 
> > > -----Original Message-----
> > > From: Hannes Domani <ssbssa@yahoo.de>
> > > Sent: Freitag, 17. Juli 2026 16:50
> > > To: gdb-patches@sourceware.org; Schimpe, Christina
> > > <christina.schimpe@intel.com>
> > > Subject: Re: [PATCH 7/8] Windows gdb: Implement XState (Intel AVX)
> > > support
> > >
> > >  Am Freitag, 17. Juli 2026 um 16:16:31 MESZ hat Schimpe, Christina
> > ><christina.schimpe@intel.com> Folgendes geschrieben:
> > >
> > > > > -----Original Message-----
> > > > > From: Hannes Domani <ssbssa@yahoo.de>
> > > > > Sent: Freitag, 17. Juli 2026 15:47
> > > > > To: gdb-patches@sourceware.org; Schimpe, Christina
> > > > > <christina.schimpe@intel.com>
> > > > > Subject: Re: [PATCH 7/8] Windows gdb: Implement XState (Intel
> > > > > AVX) support
> > > > >
> > > > >  Am Freitag, 17. Juli 2026 um 14:54:59 MESZ hat Schimpe,
> > > > >Christina <christina.schimpe@intel.com> Folgendes geschrieben:
> > > > >
> > > > > > Hi Hannes,
> > > > > >
> > > > > > Thank you for working on this.
> > > > > > It appears that this patch uses the same commit message header
> > > > > > as patch #8. Is it intentional that these are separate commits?
> > > > >
> > > > > This one is the gdb part, and #8 is the gdbserver part, that is
> > > > > stated in the title.
> > > >
> > > > Oups, I wonder how I came to that conclusion.  Sorry for that.
> > > >
> > > > >
> > > > > > In any case, IMO, commit messages should not have identical headers.
> > > > > > Also, this patch seems big enough for a commit message which
> > > > > > is not header only. :)
> > > >
> > > > This part still stands for the commit message. Since it's not only
> > > > avx registers, I believe it makes sense to share more details here.
> > >
> > > Yes, I will do that.
> > >
> > >
> > > > > > Do any AVX-* specific tests pass on Windows now? If so, it
> > > > > > would be helpful to mention that in the commit message as well.
> > > > >
> > > > > I actually planned to add that info, but forgot.
> > > > >
> > > > > These tests then pass on Windows:
> > > > > gdb.arch/i386-avx.exp
> > > > > gdb.arch/i386-avx512.exp
> > > >
> > > > What's the state for SSE  (gdb.arch/i386-sse.exp) ?
> > >
> > > i386-sse.exp works since patch #1, it was only a compile issue of
> > > the test itself.
> > > I will mention this in the patch as well.
> >
> > Thanks.
> >
> > >
> > > > I also saw you introduced some code for PKRU and the shadow stack
> > > pointer.
> > > > We have GDB tests for those registers, too:
> > > > - gdb.arch/i386-pkru.exp
> > > > - gdb.arch/amd64-shadow-stack*.exp
> > >
> > > For these I just added the equivalent code as is done on Linux,
> > > without really knowing what they are for.
> > >
> > > i386-pkru.exp tells me:
> > >
> > > (gdb) print have_pkru()
> > > $1 = 0
> > > (gdb) PASS: gdb.arch/i386-pkru.exp: probe PKRU support
> > > UNSUPPORTED: gdb.arch/i386-pkru.exp: processor does not support
> > > protection key feature.
> > >
> > > Do only certain CPU's have this register?
> >
> > Most recent CPUs should have it. To be sure you can check if the
> > corresponding bit is configured in xcr0.
> 
> I thought that's what have_pkru() does, but I might be wrong about that.

Yes, this should work for windows, too.
 
> > I believe for windows this should be the mask returned by
> get_xstate_features_mask.
> 
> You probably mean GetEnabledXStateFeatures, but yes, it also tells me my CPU
> doesn't support this.
>
> 
> > If your cpu does have it, I think you must look at the test in more
> > detail to find out why it's unsupported. It might need some adaptions for
> windows.
> Google tells me only not all recent CPUs have this, is mine one of them?:
> 11th Gen Intel(R) Core(TM) i7-11850H

I would have expected this but cannot say for sure.  And I don't know the state for
Memory Protection Keys windows support. 

> > > And amd64-shadow-stack.exp:
> > >
> > > (gdb) print $pl3_ssp
> > > $1 = (void *) 0x0
> > > (gdb) FAIL: gdb.arch/amd64-shadow-stack.exp: test shadow stack
> > > support
> > >
> > > No idea if that should work, since Windows is supplying data for the
> > > $pl3_ssp register.
> > >
> > >
> > > Hannes
> >
> > Without knowing any of the details in windows I believe adding full
> > support for CET shadow stack might need some more changes. At least for
> linux, this was the case:
> > https://inbox.sourceware.org/gdb-patches/20250821171029.1555603-1-chri
> > stina.schimpe@intel.com/
> >
> > I believe it would be better to handle this in a separate patch-(series).
> > This also applies for any other register that you add and whose dedicated
> test does not pass.
> >
> > Does that make sense to you?
> 
> I was wondering if it isn't the compiler or linker on windows (or maybe
> windows itself?) that doesn't support this -fcf-protection=return stuff.

I don't know the state for windows but would be curious about it. :-)
At least for Kernel Mode, I could find some documentation for it.

Christina
Intel Deutschland GmbH

Registered Address: Dornacher Strasse 1, 85622 Feldkirchen, Germany
Tel: +49 89 991 430, www.intel.de
Managing Directors: Harry Demas, Jeffrey Schneiderman, Yin Chong Sorrell
Chairperson of the Supervisory Board: Nicole Lau
Registered Seat: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928

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

* Re: [PATCH 7/8] Windows gdb: Implement XState (Intel AVX) support
  2026-07-17 19:06                 ` Schimpe, Christina
@ 2026-07-18 16:06                   ` Hannes Domani
  0 siblings, 0 replies; 20+ messages in thread
From: Hannes Domani @ 2026-07-18 16:06 UTC (permalink / raw)
  To: gdb-patches, Schimpe, Christina

 Am Freitag, 17. Juli 2026 um 21:06:16 MESZ hat Schimpe, Christina <christina.schimpe@intel.com> Folgendes geschrieben:

> > -----Original Message-----
> > From: Hannes Domani <ssbssa@yahoo.de>
> > Sent: Freitag, 17. Juli 2026 18:27
> > To: gdb-patches@sourceware.org; Schimpe, Christina
> > <christina.schimpe@intel.com>
> > Subject: Re: [PATCH 7/8] Windows gdb: Implement XState (Intel AVX) support
> >
> >  Am Freitag, 17. Juli 2026 um 17:26:14 MESZ hat Schimpe, Christina
> > <christina.schimpe@intel.com> Folgendes geschrieben:
> >
> > > > -----Original Message-----
> > > > From: Hannes Domani <ssbssa@yahoo.de>
> > > > Sent: Freitag, 17. Juli 2026 16:50
> > > > To: gdb-patches@sourceware.org; Schimpe, Christina
> > > > <christina.schimpe@intel.com>
> > > > Subject: Re: [PATCH 7/8] Windows gdb: Implement XState (Intel AVX)
> > > > support
> > > >
> > > >  Am Freitag, 17. Juli 2026 um 16:16:31 MESZ hat Schimpe, Christina
> > > ><christina.schimpe@intel.com> Folgendes geschrieben:
> > > >
> > > > > > -----Original Message-----
> > > > > > From: Hannes Domani <ssbssa@yahoo.de>
> > > > > > Sent: Freitag, 17. Juli 2026 15:47
> > > > > > To: gdb-patches@sourceware.org; Schimpe, Christina
> > > > > > <christina.schimpe@intel.com>
> > > > > > Subject: Re: [PATCH 7/8] Windows gdb: Implement XState (Intel
> > > > > > AVX) support
> > > > > >
> > > > > >  Am Freitag, 17. Juli 2026 um 14:54:59 MESZ hat Schimpe,
> > > > > >Christina <christina.schimpe@intel.com> Folgendes geschrieben:
> > > > > >
> > > > > > > Hi Hannes,
> > > > > > >
> > > > > > > Thank you for working on this.
> > > > > > > It appears that this patch uses the same commit message header
> > > > > > > as patch #8. Is it intentional that these are separate commits?
> > > > > >
> > > > > > This one is the gdb part, and #8 is the gdbserver part, that is
> > > > > > stated in the title.
> > > > >
> > > > > Oups, I wonder how I came to that conclusion.  Sorry for that.
> > > > >
> > > > > >
> > > > > > > In any case, IMO, commit messages should not have identical headers.
> > > > > > > Also, this patch seems big enough for a commit message which
> > > > > > > is not header only. :)
> > > > >
> > > > > This part still stands for the commit message. Since it's not only
> > > > > avx registers, I believe it makes sense to share more details here.
> > > >
> > > > Yes, I will do that.
> > > >
> > > >
> > > > > > > Do any AVX-* specific tests pass on Windows now? If so, it
> > > > > > > would be helpful to mention that in the commit message as well.
> > > > > >
> > > > > > I actually planned to add that info, but forgot.
> > > > > >
> > > > > > These tests then pass on Windows:
> > > > > > gdb.arch/i386-avx.exp
> > > > > > gdb.arch/i386-avx512.exp
> > > > >
> > > > > What's the state for SSE  (gdb.arch/i386-sse.exp) ?
> > > >
> > > > i386-sse.exp works since patch #1, it was only a compile issue of
> > > > the test itself.
> > > > I will mention this in the patch as well.
> > >
> > > Thanks.
> > >
> > > >
> > > > > I also saw you introduced some code for PKRU and the shadow stack
> > > > pointer.
> > > > > We have GDB tests for those registers, too:
> > > > > - gdb.arch/i386-pkru.exp
> > > > > - gdb.arch/amd64-shadow-stack*.exp
> > > >
> > > > For these I just added the equivalent code as is done on Linux,
> > > > without really knowing what they are for.
> > > >
> > > > i386-pkru.exp tells me:
> > > >
> > > > (gdb) print have_pkru()
> > > > $1 = 0
> > > > (gdb) PASS: gdb.arch/i386-pkru.exp: probe PKRU support
> > > > UNSUPPORTED: gdb.arch/i386-pkru.exp: processor does not support
> > > > protection key feature.
> > > >
> > > > Do only certain CPU's have this register?
> > >
> > > Most recent CPUs should have it. To be sure you can check if the
> > > corresponding bit is configured in xcr0.
> >
> > I thought that's what have_pkru() does, but I might be wrong about that.
> 
> Yes, this should work for windows, too.
> 
> > > I believe for windows this should be the mask returned by
> > get_xstate_features_mask.
> >
> > You probably mean GetEnabledXStateFeatures, but yes, it also tells me my CPU
> > doesn't support this.
> >
> >
> > > If your cpu does have it, I think you must look at the test in more
> > > detail to find out why it's unsupported. It might need some adaptions for
> > windows.
> > Google tells me only not all recent CPUs have this, is mine one of them?:
> > 11th Gen Intel(R) Core(TM) i7-11850H
> 
> I would have expected this but cannot say for sure.  And I don't know the state for
> Memory Protection Keys windows support.

I have tested this now on another PC, one where have_pkru() returns 1, so
this CPU really should have PKRU.

But GetEnabledXStateFeatures still does not return the PKRU bit, and I can
find no equivalent XSTATE_PKRU define in winnt.h, this makes me believe
that windows just doesn't support this feature.

So I'm fine with removing that part.


> > > > And amd64-shadow-stack.exp:
> > > >
> > > > (gdb) print $pl3_ssp
> > > > $1 = (void *) 0x0
> > > > (gdb) FAIL: gdb.arch/amd64-shadow-stack.exp: test shadow stack
> > > > support
> > > >
> > > > No idea if that should work, since Windows is supplying data for the
> > > > $pl3_ssp register.
> > > >
> > > >
> > > > Hannes
> > >
> > > Without knowing any of the details in windows I believe adding full
> > > support for CET shadow stack might need some more changes. At least for
> > linux, this was the case:
> > > https://inbox.sourceware.org/gdb-patches/20250821171029.1555603-1-chri
> > > stina.schimpe@intel.com/
> > >
> > > I believe it would be better to handle this in a separate patch-(series).
> > > This also applies for any other register that you add and whose dedicated
> > test does not pass.
> > >
> > > Does that make sense to you?
> >
> > I was wondering if it isn't the compiler or linker on windows (or maybe
> > windows itself?) that doesn't support this -fcf-protection=return stuff.
> 
> I don't know the state for windows but would be curious about it. :-)
> At least for Kernel Mode, I could find some documentation for it.

I did some more tests here as well.

It turns out binutils/gcc really don't support this on windows yet.
To enable this in the executable, at least a special marker bit has to be
set in the Extended DLL Characteristics [1].
With msvc you can do that with the /CETCOMPAT linker argument [2].

So I compiled amd64-shadow-stack.c with msvc and /CETCOMPAT, and tried it
out with my gdb build.
Before I always got $pl3_ssp=0, and with this new exe I always get $pl3_ssp=1.

So I had this wrong, because LocateXStateFeature returns for XSTATE_CET_U
this struct:
    typedef struct _XSAVE_CET_U_FORMAT {
      DWORD64 Ia32CetUMsr;
      DWORD64 Ia32Pl3SspMsr;
    } XSAVE_CET_U_FORMAT, *PXSAVE_CET_U_FORMAT;

So $pl3_ssp showed Ia32CetUMsr, when it should have shown Ia32Pl3SspMsr
instead.

With that fixed, I tried again debugging the /CETCOMPAT executable:

(gdb) r
Starting program: C:\qiewer\git\amd64-shadow-stack.exe

Breakpoint 1, 0x00007ff725812e41 in ?? ()
1: $pl3_ssp = (void *) 0x4feff0
(gdb) x/1i $pc
=> 0x7ff725812e41:      jmp    0x7ff725817680
(gdb) x/4a $pl3_ssp
0x4feff0:       0x7ffd62fee957 <KERNEL32!BaseThreadInitThunk+23>        0x7ffd63647c1c <ntdll!RtlUserThreadStart+44>
0x4ff000:       Cannot access memory at address 0x4ff000
(gdb) si
...
(gdb) si
0x00007ff725817684 in ?? ()
1: $pl3_ssp = (void *) 0x4feff0
(gdb) x/1i $pc
=> 0x7ff725817684:      call   0x7ff725812f1d
(gdb) si
0x00007ff725812f1d in ?? ()
1: $pl3_ssp = (void *) 0x4fefe8
(gdb) x/4a $pl3_ssp
0x4fefe8:       0x7ff725817689  0x7ffd62fee957 <KERNEL32!BaseThreadInitThunk+23>
0x4feff8:       0x7ffd63647c1c <ntdll!RtlUserThreadStart+44>    Cannot access memory at address 0x4ff000
(gdb) x/1i $pc
=> 0x7ff725812f1d:      jmp    0x7ff725817c30
(gdb) si
...
(gdb) si
0x00007ff725817cde in ?? ()
1: $pl3_ssp = (void *) 0x4fefe8
(gdb) x/1i $pc
=> 0x7ff725817cde:      ret
(gdb) si
0x00007ff725817689 in ?? ()
1: $pl3_ssp = (void *) 0x4feff0
(gdb) x/1i $pc
=> 0x7ff725817689:      add    $0x28,%rsp
(gdb) x/4a $pl3_ssp
0x4feff0:       0x7ffd62fee957 <KERNEL32!BaseThreadInitThunk+23>        0x7ffd63647c1c <ntdll!RtlUserThreadStart+44>
0x4ff000:       Cannot access memory at address 0x4ff000
(gdb)

call and ret modify the shadow stack which is pointed to by $pl3_ssp, is that
how it's supposed to work?
I'm unsure, because amd64-shadow-stack-cmds.exp makes it look like $pl3_ssp
should change when moving up or down the frames.

Is $pl3_ssp maybe supposed to provide Ia32Pl3SspMsr[$frame] instead?
How does that work on linux?

In any case, I tried modifying $pl3_ssp like it is done in
amd64-shadow-stack.exp.

(gdb) p $pl3_ssp
$10 = (void *) 0x4fefe8
(gdb) p $pl3_ssp=0x12345678
$11 = (void *) 0x12345678
(gdb) ni
error return C:/gdb/src/gdb.git/gdb/x86-windows-nat.c:242 was 1660: The thread context could not be updated because this has been restricted for the process.
0x00007ffd63720574 in ntdll!ZwMapViewOfSection () from C:\WINDOWS\SYSTEM32\ntdll.dll

So windows doesn't allow modifying the shadow stack pointer.

(gdb) p $pl3_ssp
$14 = (void *) 0x4fefe8
(gdb) p ((void**)$pl3_ssp)[0]
$15 = (void *) 0x7ff725817689
(gdb) p ((void**)$pl3_ssp)[0]=0x12345678
Cannot access memory at address 0x4fefe8

And looks like modifying the shadow stack entries is also prohibited.


[1] https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#extended-dll-characteristics
[2] https://learn.microsoft.com/en-us/cpp/build/reference/cetcompat


Hannes

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

end of thread, other threads:[~2026-07-18 16:08 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <20260712113229.3695246-1-ssbssa.ref@yahoo.de>
2026-07-12 11:32 ` [PATCH 1/8] gdb/testsuite: Add Windows replacement for aligned_alloc Hannes Domani
2026-07-12 11:32   ` [PATCH 2/8] Windows gdb: Use allocated buffer for CONTEXT Hannes Domani
2026-07-12 11:32   ` [PATCH 3/8] Windows gdb: Remove mappings member from windows_per_inferior Hannes Domani
2026-07-12 11:32   ` [PATCH 4/8] Windows gdb: Refactor getting pointer to register inside context Hannes Domani
2026-07-12 11:32   ` [PATCH 5/8] Windows gdb: Prepare XState functions Hannes Domani
2026-07-17 14:41     ` Schimpe, Christina
2026-07-17 15:04       ` Hannes Domani
2026-07-17 15:07         ` Hannes Domani
2026-07-17 16:22           ` Schimpe, Christina
2026-07-12 11:32   ` [PATCH 6/8] Windows gdb: Get available XState features Hannes Domani
2026-07-12 11:32   ` [PATCH 7/8] Windows gdb: Implement XState (Intel AVX) support Hannes Domani
2026-07-17 12:54     ` Schimpe, Christina
2026-07-17 13:46       ` Hannes Domani
2026-07-17 14:16         ` Schimpe, Christina
2026-07-17 14:49           ` Hannes Domani
2026-07-17 15:26             ` Schimpe, Christina
2026-07-17 16:26               ` Hannes Domani
2026-07-17 19:06                 ` Schimpe, Christina
2026-07-18 16:06                   ` Hannes Domani
2026-07-12 11:32   ` [PATCH 8/8] Windows gdbserver: " Hannes Domani

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox