Skip to content

Commit 22b96f1

Browse files
committed
Implement access to AVX registers on Windows
1 parent ee18344 commit 22b96f1

8 files changed

Lines changed: 540 additions & 47 deletions

File tree

gdb/amd64-windows-nat.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,9 @@ const int amd64_mappings[] =
8686
};
8787
#undef context_offset
8888

89+
const int amd64_mappings_count
90+
= sizeof (amd64_mappings) / sizeof (amd64_mappings[0]);
91+
8992
/* segment_register_p_ftype implementation for amd64. */
9093

9194
int

gdb/i386-windows-nat.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,9 @@ const int i386_mappings[] =
7474
#undef context_offset
7575
#undef CONTEXT
7676

77+
const int i386_mappings_count
78+
= sizeof (i386_mappings) / sizeof (i386_mappings[0]);
79+
7780
/* segment_register_p_ftype implementation for x86. */
7881

7982
int

gdb/nat/windows-nat.c

Lines changed: 84 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "gdbsupport/common-debug.h"
2121
#include "gdbsupport/xml-utils.h"
2222
#include "target/target.h"
23+
#include "gdbsupport/x86-xstate.h"
2324

2425
#undef GetModuleFileNameEx
2526

@@ -72,6 +73,17 @@ InitializeProcThreadAttributeList_ftype *InitializeProcThreadAttributeList;
7273
UpdateProcThreadAttribute_ftype *UpdateProcThreadAttribute;
7374
DeleteProcThreadAttributeList_ftype *DeleteProcThreadAttributeList;
7475

76+
GetEnabledXStateFeatures_ftype *GetEnabledXStateFeatures;
77+
InitializeContext_ftype *InitializeContext;
78+
GetXStateFeaturesMask_ftype *GetXStateFeaturesMask;
79+
SetXStateFeaturesMask_ftype *SetXStateFeaturesMask;
80+
LocateXStateFeature_ftype *LocateXStateFeature;
81+
#ifdef __x86_64__
82+
RtlGetExtendedFeaturesMask_ftype *RtlGetExtendedFeaturesMask;
83+
RtlSetExtendedFeaturesMask_ftype *RtlSetExtendedFeaturesMask;
84+
RtlLocateExtendedFeature_ftype *RtlLocateExtendedFeature;
85+
#endif
86+
7587
/* Note that 'debug_events' must be locally defined in the relevant
7688
functions. */
7789
#define DEBUG_EVENTS(fmt, ...) \
@@ -241,10 +253,35 @@ windows_process_info::pid_to_exec_file (int pid)
241253
return path;
242254
}
243255

244-
void windows_process_info::initialize_context (windows_thread_info *th)
256+
void windows_process_info::initialize_context (windows_thread_info *th,
257+
DWORD xstate_features)
245258
{
259+
if (xstate_features != 0)
260+
{
261+
DWORD context_flags = with_context (nullptr, [] (auto *context)
262+
{
263+
return WindowsContext<decltype(context)>::control;
264+
});
265+
context_flags |= CONTEXT_XSTATE_FLAG;
266+
DWORD xstate_size = 0;
267+
InitializeContext (NULL, context_flags, NULL, &xstate_size);
268+
th->context_buffer.reset (xmalloc (xstate_size));
269+
CONTEXT *context = nullptr;
270+
if (!InitializeContext (th->context_buffer.get (),
271+
context_flags, &context, &xstate_size))
272+
error ("InitializeContext failure %lu\n", GetLastError ());
246273
#ifdef __x86_64__
247-
if (wow64_process)
274+
/* InitializeContext actually initializes a WOW64_CONTEXT when
275+
context_flags contains a WOW64_CONTEXT_* value, so a cast is needed.
276+
*/
277+
if (wow64_process)
278+
th->wow64_context = (WOW64_CONTEXT *) context;
279+
else
280+
#endif
281+
th->context = context;
282+
}
283+
#ifdef __x86_64__
284+
else if (wow64_process)
248285
{
249286
th->context_buffer.reset (xmalloc (sizeof (WOW64_CONTEXT)));
250287
th->wow64_context = (WOW64_CONTEXT *) th->context_buffer.get ();
@@ -1078,6 +1115,35 @@ disable_randomization_available ()
10781115

10791116
/* See windows-nat.h. */
10801117

1118+
DWORD64
1119+
get_xstate_features ()
1120+
{
1121+
if (GetEnabledXStateFeatures != nullptr
1122+
&& InitializeContext != nullptr
1123+
&& GetXStateFeaturesMask != nullptr
1124+
&& SetXStateFeaturesMask != nullptr
1125+
&& LocateXStateFeature != nullptr
1126+
#ifdef __x86_64__
1127+
&& RtlGetExtendedFeaturesMask != nullptr
1128+
&& RtlSetExtendedFeaturesMask != nullptr
1129+
&& RtlLocateExtendedFeature != nullptr
1130+
#endif
1131+
)
1132+
{
1133+
DWORD64 xstate_features
1134+
= GetEnabledXStateFeatures () & X86_XSTATE_ALL_MASK;
1135+
/* The extended xstate functions are only needed if the available
1136+
features exceed SSE. */
1137+
if ((xstate_features & ~X86_XSTATE_SSE_MASK) == 0)
1138+
xstate_features = 0;
1139+
return xstate_features;
1140+
}
1141+
1142+
return 0;
1143+
}
1144+
1145+
/* See windows-nat.h. */
1146+
10811147
bool
10821148
initialize_loadable ()
10831149
{
@@ -1108,6 +1174,12 @@ initialize_loadable ()
11081174
GPA (hm, InitializeProcThreadAttributeList);
11091175
GPA (hm, UpdateProcThreadAttribute);
11101176
GPA (hm, DeleteProcThreadAttributeList);
1177+
1178+
GPA (hm, GetEnabledXStateFeatures);
1179+
GPA (hm, InitializeContext);
1180+
GPA (hm, GetXStateFeaturesMask);
1181+
GPA (hm, SetXStateFeaturesMask);
1182+
GPA (hm, LocateXStateFeature);
11111183
}
11121184

11131185
/* Set variables to dummy versions of these processes if the function
@@ -1173,6 +1245,16 @@ initialize_loadable ()
11731245
GPA (hm, GetThreadDescription);
11741246
}
11751247

1248+
#ifdef __x86_64__
1249+
hm = LoadLibrary (TEXT ("ntdll.dll"));
1250+
if (hm)
1251+
{
1252+
GPA (hm, RtlGetExtendedFeaturesMask);
1253+
GPA (hm, RtlSetExtendedFeaturesMask);
1254+
GPA (hm, RtlLocateExtendedFeature);
1255+
}
1256+
#endif
1257+
11761258
#undef GPA
11771259

11781260
return result;

gdb/nat/windows-nat.h

Lines changed: 112 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@
3535
#define CONTEXT_EXTENDED_REGISTERS 0
3636
#endif
3737

38+
#define CONTEXT_EXTENDED_REGISTERS_FLAG 0x20
39+
#define CONTEXT_XSTATE_FLAG 0x40
40+
3841
namespace windows_nat
3942
{
4043

@@ -258,7 +261,7 @@ struct windows_process_info
258261

259262
const char *pid_to_exec_file (int);
260263

261-
void initialize_context (windows_thread_info *th);
264+
void initialize_context (windows_thread_info *th, DWORD xstate_features);
262265

263266
template<typename Function>
264267
auto with_context (windows_thread_info *th, Function function)
@@ -371,6 +374,14 @@ extern BOOL create_process (const wchar_t *image, wchar_t *command_line,
371374
#define InitializeProcThreadAttributeList dyn_InitializeProcThreadAttributeList
372375
#define UpdateProcThreadAttribute dyn_UpdateProcThreadAttribute
373376
#define DeleteProcThreadAttributeList dyn_DeleteProcThreadAttributeList
377+
#define GetEnabledXStateFeatures dyn_GetEnabledXStateFeatures
378+
#define InitializeContext dyn_InitializeContext
379+
#define GetXStateFeaturesMask dyn_GetXStateFeaturesMask
380+
#define SetXStateFeaturesMask dyn_SetXStateFeaturesMask
381+
#define LocateXStateFeature dyn_LocateXStateFeature
382+
#define RtlGetExtendedFeaturesMask dyn_RtlGetExtendedFeaturesMask
383+
#define RtlSetExtendedFeaturesMask dyn_RtlSetExtendedFeaturesMask
384+
#define RtlLocateExtendedFeature dyn_RtlLocateExtendedFeature
374385

375386
typedef BOOL WINAPI (AdjustTokenPrivileges_ftype) (HANDLE, BOOL,
376387
PTOKEN_PRIVILEGES,
@@ -465,6 +476,33 @@ extern DeleteProcThreadAttributeList_ftype *DeleteProcThreadAttributeList;
465476

466477
extern bool disable_randomization_available ();
467478

479+
typedef DWORD64 (WINAPI GetEnabledXStateFeatures_ftype) ();
480+
extern GetEnabledXStateFeatures_ftype *GetEnabledXStateFeatures;
481+
482+
typedef BOOL (WINAPI InitializeContext_ftype) (PVOID, DWORD,
483+
PCONTEXT*, PDWORD);
484+
extern InitializeContext_ftype *InitializeContext;
485+
486+
typedef BOOL (WINAPI GetXStateFeaturesMask_ftype) (PCONTEXT, PDWORD64);
487+
extern GetXStateFeaturesMask_ftype *GetXStateFeaturesMask;
488+
489+
typedef BOOL (WINAPI SetXStateFeaturesMask_ftype) (PCONTEXT, DWORD64);
490+
extern SetXStateFeaturesMask_ftype *SetXStateFeaturesMask;
491+
492+
typedef PVOID (WINAPI LocateXStateFeature_ftype) (PCONTEXT, DWORD, PDWORD);
493+
extern LocateXStateFeature_ftype *LocateXStateFeature;
494+
495+
#ifdef __x86_64__
496+
typedef DWORD64 (WINAPI RtlGetExtendedFeaturesMask_ftype) (PVOID);
497+
extern RtlGetExtendedFeaturesMask_ftype *RtlGetExtendedFeaturesMask;
498+
499+
typedef VOID (WINAPI RtlSetExtendedFeaturesMask_ftype) (PVOID, DWORD64);
500+
extern RtlSetExtendedFeaturesMask_ftype *RtlSetExtendedFeaturesMask;
501+
502+
typedef PVOID (WINAPI RtlLocateExtendedFeature_ftype) (PVOID, DWORD, PDWORD);
503+
extern RtlLocateExtendedFeature_ftype *RtlLocateExtendedFeature;
504+
#endif
505+
468506
/* Helper classes to get the correct ContextFlags values based on the
469507
used type (CONTEXT or WOW64_CONTEXT). */
470508

@@ -528,16 +566,64 @@ enum_process_modules (CONTEXT *, HANDLE process,
528566
return EnumProcessModules (process, modules, size, needed);
529567
}
530568

569+
static inline BOOL
570+
get_xstate_features_mask (CONTEXT *context, DWORD64 *mask)
571+
{
572+
return GetXStateFeaturesMask (context, mask);
573+
}
574+
575+
static inline BOOL
576+
set_xstate_features_mask (CONTEXT *context, DWORD64 mask)
577+
{
578+
return SetXStateFeaturesMask (context, mask);
579+
}
580+
581+
static inline PVOID
582+
locate_xstate_feature (CONTEXT *context, DWORD feature, DWORD *length)
583+
{
584+
return LocateXStateFeature (context, feature, length);
585+
}
586+
531587
#ifdef __x86_64__
532588
static inline BOOL
533589
get_thread_context (HANDLE h, WOW64_CONTEXT *context)
534590
{
591+
if ((context->ContextFlags & CONTEXT_XSTATE_FLAG) != 0)
592+
{
593+
DWORD flags = context->ContextFlags;
594+
context->ContextFlags &= ~CONTEXT_EXTENDED_REGISTERS_FLAG;
595+
BOOL ret = Wow64GetThreadContext (h, context);
596+
context->ContextFlags = flags;
597+
if (!ret)
598+
return FALSE;
599+
600+
context->ContextFlags &= ~CONTEXT_XSTATE_FLAG;
601+
ret = Wow64GetThreadContext (h, context);
602+
context->ContextFlags = flags;
603+
return ret;
604+
}
605+
535606
return Wow64GetThreadContext (h, context);
536607
}
537608

538609
static inline BOOL
539610
set_thread_context (HANDLE h, WOW64_CONTEXT *context)
540611
{
612+
if ((context->ContextFlags & CONTEXT_XSTATE_FLAG) != 0)
613+
{
614+
DWORD flags = context->ContextFlags;
615+
context->ContextFlags &= ~CONTEXT_EXTENDED_REGISTERS_FLAG;
616+
BOOL ret = Wow64SetThreadContext (h, context);
617+
context->ContextFlags = flags;
618+
if (!ret)
619+
return FALSE;
620+
621+
context->ContextFlags &= ~CONTEXT_XSTATE_FLAG;
622+
ret = Wow64SetThreadContext (h, context);
623+
context->ContextFlags = flags;
624+
return ret;
625+
}
626+
541627
return Wow64SetThreadContext (h, context);
542628
}
543629

@@ -555,8 +641,33 @@ enum_process_modules (WOW64_CONTEXT *, HANDLE process,
555641
return EnumProcessModulesEx (process, modules, size, needed,
556642
LIST_MODULES_32BIT);
557643
}
644+
645+
static inline BOOL
646+
get_xstate_features_mask (WOW64_CONTEXT *context, DWORD64 *mask)
647+
{
648+
*mask = RtlGetExtendedFeaturesMask (context + 1);
649+
return TRUE;
650+
}
651+
652+
static inline BOOL
653+
set_xstate_features_mask (WOW64_CONTEXT *context, DWORD64 mask)
654+
{
655+
RtlSetExtendedFeaturesMask (context + 1, mask);
656+
return TRUE;
657+
}
658+
659+
static inline PVOID
660+
locate_xstate_feature (WOW64_CONTEXT *context, DWORD feature, DWORD *length)
661+
{
662+
return RtlLocateExtendedFeature (context + 1, feature, length);
663+
}
558664
#endif
559665

666+
/* Return the available xstate features, but only if there is more than SSE
667+
available. */
668+
669+
extern DWORD64 get_xstate_features ();
670+
560671
/* Load any functions which may not be available in ancient versions
561672
of Windows. */
562673

0 commit comments

Comments
 (0)