[5/8] Windows gdb: Prepare XState functions

Message ID 20260712113229.3695246-5-ssbssa@yahoo.de
State New
Headers
Series [1/8] gdb/testsuite: Add Windows replacement for aligned_alloc |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gdb_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_gdb_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_gdb_check--master-arm success Test passed
linaro-tcwg-bot/tcwg_gdb_check--master-aarch64 success Test passed

Commit Message

Hannes Domani July 12, 2026, 11:32 a.m. UTC
  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(+)
  

Comments

Schimpe, Christina July 17, 2026, 2:41 p.m. UTC | #1
> -----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
  
Hannes Domani July 17, 2026, 3:04 p.m. UTC | #2
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
  
Hannes Domani July 17, 2026, 3:07 p.m. UTC | #3
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
  
Schimpe, Christina July 17, 2026, 4:22 p.m. UTC | #4
> -----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
  

Patch

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.  */