Re: [PATCH v2 7/8] Windows gdb: Implement XState (Intel AVX) support

Hannes Domani <[email protected]>
Newsgroups gmane.comp.gdb.patches
Message-ID <[email protected]>
Ping for this series.


Am Montag, 27. Juli 2026 um 19:47:52 MESZ hat Hannes Domani <[email protected]> Folgendes geschrieben:

> This adds support for the Intel AVX and AVX-512 registers on Windows.
> It enables accessing registers $ymm0 - $ymm31, $zmm0 - $zmm31, and
> $k0 - $k7 where they are available.
> 
> It also enables reading the shadow stack pointer register $pl3_ssp (for
> executables marked compatible with CET shadow stack [1]), but modifying
> it seems to be restricted restricted by windows.
> 
> After this patch the tests gdb.arch/i386-avx.exp and gdb.arch/i386-avx512.exp
> pass on windows.
> 
> [1] https://learn.microsoft.com/en-us/cpp/build/reference/cetcompat
> ---
> v2:
>   - Extended commit message and NEWS entry
>   - Remove PKRU support
>   - Fixed context offset of $pl3_ssp
> ---
> gdb/NEWS              |  6 +++
> gdb/x86-windows-nat.c | 108 ++++++++++++++++++++++++++++++++++++++++--
> 2 files changed, 111 insertions(+), 3 deletions(-)
> 
> diff --git a/gdb/NEWS b/gdb/NEWS
> index 8f40ca5cb11..71ff5508d6d 100644
> --- a/gdb/NEWS
> +++ b/gdb/NEWS
> @@ -116,6 +116,12 @@
>   intent to remove it in a future release.
>   The s390 64-bit target (s390x-*) remains supported.
> 
> +* Support for Intel AVX registers on Windows.
> +  Support displaying and modifying Intel AVX registers $ymm0 - $ymm31.
> +  Support displaying and modifying Intel AVX-512 registers $zmm0 - $zmm31
> +  and $k0 - $k7.
> +  Support displaying the shadow stack pointer register $pl3_ssp.
> +
> * 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 3af5ef4dae0..270f9eae8e7 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,54 @@ get_context_reg_ptr (Context *context, int r)
>   char *context_offset;
>   if (r < mappings_count)
>     context_offset = (char *) context + mappings[r];
> +  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);
> +      context_offset += 8;
> +    }
>   else
>     gdb_assert_not_reached ("invalid register number %d", r);
> 
> @@ -267,7 +352,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 +418,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 +453,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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.