FpDebug: Windows, Ymm register

This commit is contained in:
Martin 2024-07-11 16:25:31 +02:00
parent 114c136702
commit 7cf389203d
2 changed files with 166 additions and 5 deletions

View File

@ -238,7 +238,8 @@ type
{$ENDIF}
PM128A = ^M128A;
function XmmToString(xmm: M128A): String;
function XmmToString(const xmm: M128A): String;
function YmmToString(const Xmm, Ymm: M128A): String;
var
ProcessMessagesProc: procedure of object; // Application.ProcessMessages, if needed. To be called while waiting.
@ -464,7 +465,7 @@ begin
Result := Result + HexStr(i, ASize * 2);
end;
function XmmToString(xmm: M128A): String;
function XmmToString(const xmm: M128A): String;
begin
Result := format('{"D": [%s, %s], "S": [%s, %s, %s, %s], "I64": [%s, %s], "I32": [%s, %s, %s, %s], "I16": [%s, %s, %s, %s, %s, %s, %s, %s], "I8": [%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s]}', [
FloatToStr(PDouble(@xmm+0)^), FloatToStr(PDouble(@xmm+8)^),
@ -493,6 +494,54 @@ begin
]);
end;
function YmmToString(const Xmm, Ymm: M128A): String;
begin
Result := format('{"D": [%s, %s, %s, %s], "S": [%s, %s, %s, %s, %s, %s, %s, %s], "I64": [%s, %s, %s, %s], "I32": [%s, %s, %s, %s, %s, %s, %s, %s], "I16": [%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s], "I8": [%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s]}', [
FloatToStr(PDouble(@xmm+0)^), FloatToStr(PDouble(@xmm+8)^),
FloatToStr(PDouble(@ymm+0)^), FloatToStr(PDouble(@ymm+8)^),
FloatToStr(PSingle(@xmm+0)^), FloatToStr(PSingle(@xmm+4)^),
FloatToStr(PSingle(@xmm+8)^), FloatToStr(PSingle(@xmm+12)^),
FloatToStr(PSingle(@ymm+0)^), FloatToStr(PSingle(@ymm+4)^),
FloatToStr(PSingle(@ymm+8)^), FloatToStr(PSingle(@ymm+12)^),
IntToStr(PInt64(@xmm+0)^), IntToStr(PInt64(@xmm+8)^),
IntToStr(PInt64(@ymm+0)^), IntToStr(PInt64(@ymm+8)^),
IntToStr(PInt32(@xmm+0)^), IntToStr(PInt32(@xmm+4)^),
IntToStr(PInt32(@xmm+8)^), IntToStr(PInt32(@xmm+12)^),
IntToStr(PInt32(@ymm+0)^), IntToStr(PInt32(@ymm+4)^),
IntToStr(PInt32(@ymm+8)^), IntToStr(PInt32(@ymm+12)^),
IntToStr(Pint16(@xmm+ 0)^), IntToStr(Pint16(@xmm+ 2)^),
IntToStr(Pint16(@xmm+ 4)^), IntToStr(Pint16(@xmm+ 6)^),
IntToStr(Pint16(@xmm+ 8)^), IntToStr(Pint16(@xmm+10)^),
IntToStr(Pint16(@xmm+12)^), IntToStr(Pint16(@xmm+14)^),
IntToStr(Pint16(@ymm+ 0)^), IntToStr(Pint16(@ymm+ 2)^),
IntToStr(Pint16(@ymm+ 4)^), IntToStr(Pint16(@ymm+ 6)^),
IntToStr(Pint16(@ymm+ 8)^), IntToStr(Pint16(@ymm+10)^),
IntToStr(Pint16(@ymm+12)^), IntToStr(Pint16(@ymm+14)^),
IntToStr(PInt8(@xmm+ 0)^), IntToStr(PInt8(@xmm+ 1)^),
IntToStr(PInt8(@xmm+ 2)^), IntToStr(PInt8(@xmm+ 3)^),
IntToStr(PInt8(@xmm+ 4)^), IntToStr(PInt8(@xmm+ 5)^),
IntToStr(PInt8(@xmm+ 6)^), IntToStr(PInt8(@xmm+ 7)^),
IntToStr(PInt8(@xmm+ 8)^), IntToStr(PInt8(@xmm+ 9)^),
IntToStr(PInt8(@xmm+10)^), IntToStr(PInt8(@xmm+11)^),
IntToStr(PInt8(@xmm+12)^), IntToStr(PInt8(@xmm+13)^),
IntToStr(PInt8(@xmm+14)^), IntToStr(PInt8(@xmm+15)^),
IntToStr(PInt8(@ymm+ 0)^), IntToStr(PInt8(@ymm+ 1)^),
IntToStr(PInt8(@ymm+ 2)^), IntToStr(PInt8(@ymm+ 3)^),
IntToStr(PInt8(@ymm+ 4)^), IntToStr(PInt8(@ymm+ 5)^),
IntToStr(PInt8(@ymm+ 6)^), IntToStr(PInt8(@ymm+ 7)^),
IntToStr(PInt8(@ymm+ 8)^), IntToStr(PInt8(@ymm+ 9)^),
IntToStr(PInt8(@ymm+10)^), IntToStr(PInt8(@ymm+11)^),
IntToStr(PInt8(@ymm+12)^), IntToStr(PInt8(@ymm+13)^),
IntToStr(PInt8(@ymm+14)^), IntToStr(PInt8(@ymm+15)^)
]);
end;
type
{ TFpThreadWorkerTerminateItem }

View File

@ -349,6 +349,35 @@ begin
end;
const
{$ifdef cpux86_64}
CONTEXT_XSTATE = $00100040; // 64bit // Early Win-7-SP1 needs $00100020
{$else}
CONTEXT_XSTATE = $00010040; // 32 bit
{$endif}
XSTATE_LEGACY_FLOATING_POINT = 0;
XSTATE_LEGACY_SSE = 1;
XSTATE_GSSE = 2;
XSTATE_AVX = XSTATE_GSSE;
XSTATE_MPX_BNDREGS = 3;
XSTATE_MPX_BNDCSR = 4;
XSTATE_AVX512_KMASK = 5;
XSTATE_AVX512_ZMM_H = 6;
XSTATE_AVX512_ZMM = 7;
XSTATE_IPT = 8;
XSTATE_CET_U = 11;
XSTATE_LWP = 62;
MAXIMUM_XSTATE_FEATURES = 64;
XSTATE_MASK_LEGACY_FLOATING_POINT = DWORD64(1 << XSTATE_LEGACY_FLOATING_POINT);
XSTATE_MASK_LEGACY_SSE = DWORD64(1 << XSTATE_LEGACY_SSE);
XSTATE_MASK_LEGACY = (XSTATE_MASK_LEGACY_FLOATING_POINT or XSTATE_MASK_LEGACY_SSE);
XSTATE_MASK_GSSE = DWORD64(1 << XSTATE_GSSE);
XSTATE_MASK_AVX = XSTATE_MASK_GSSE;
type
PPCONTEXT = ^PCONTEXT;
var
DebugBreakAddr: Pointer = nil;
_CreateRemoteThread: function(hProcess: THandle; lpThreadAttributes: Pointer; dwStackSize: DWORD; lpStartAddress: TFNThreadStartRoutine; lpParameter: Pointer; dwCreationFlags: DWORD; var lpThreadId: DWORD): THandle; stdcall = nil;
@ -363,6 +392,13 @@ var
_DebugBreakProcess: function(Process:HANDLE): WINBOOL; stdcall = nil;
_GetThreadDescription: function(hThread: THandle; ppszThreadDescription: PPWSTR): HResult; stdcall = nil;
_WaitForDebugEventEx: function(var lpDebugEvent: TDebugEvent; dwMilliseconds: DWORD): BOOL; stdcall = nil;
// XState
_GetEnabledXStateFeatures: function(): DWORD64; stdcall = nil;
_InitializeContext: function(Buffer: Pointer; ContextFlags: DWORD; Context: PPCONTEXT; ContextLength: PDWORD): BOOL; stdcall = nil;
_GetXStateFeaturesMask: function(Context: PCONTEXT; FeatureMask: PDWORD64): BOOL; stdcall = nil;
_LocateXStateFeature: function(Context: PCONTEXT; FeatureId: DWORD; Length: PDWORD): PM128A; stdcall = nil;
_SetXStateFeaturesMask: function(Context: PCONTEXT; FeatureMask: DWORD64): BOOL; stdcall = nil;
_xstate_FeatureMask: DWORD64;
procedure LoadKernelEntryPoints;
var
@ -388,6 +424,22 @@ begin
Pointer(_Wow64SuspendThread) := GetProcAddress(hMod, 'Wow64SuspendThread');
{$endif}
Pointer(_WaitForDebugEventEx) := GetProcAddress(hMod, 'WaitForDebugEventEx');
// xstate
Pointer(_GetEnabledXStateFeatures) := GetProcAddress(hMod, 'GetEnabledXStateFeatures');
Pointer(_InitializeContext) := GetProcAddress(hMod, 'InitializeContext');
Pointer(_GetXStateFeaturesMask) := GetProcAddress(hMod, 'GetXStateFeaturesMask');
Pointer(_LocateXStateFeature) := GetProcAddress(hMod, 'LocateXStateFeature');
Pointer(_SetXStateFeaturesMask) := GetProcAddress(hMod, 'SetXStateFeaturesMask');
if (_GetEnabledXStateFeatures=nil) or (_InitializeContext=nil) or (_GetXStateFeaturesMask=nil) or
(_LocateXStateFeature=nil) or (_SetXStateFeaturesMask=nil)
then begin
_GetEnabledXStateFeatures := nil;
end
else begin
_xstate_FeatureMask := _GetEnabledXStateFeatures();
if (_xstate_FeatureMask and XSTATE_MASK_GSSE) = 0 then
_GetEnabledXStateFeatures := nil;
end;
DebugLn(DBG_WARNINGS and (DebugBreakAddr = nil), ['WARNING: Failed to get DebugBreakAddr']);
DebugLn(DBG_WARNINGS and (_CreateRemoteThread = nil), ['WARNING: Failed to get CreateRemoteThread']);
@ -1728,7 +1780,16 @@ procedure TDbgWinThread.LoadRegisterValues;
type
PExtended = ^floatx80;
{$endif}{$ENDIF}
const
M128A_NULL: M128A = (Low: 0; High: 0; );
var
Context: PCONTEXT;
ContextSize: DWord;
Buffer, Buffer2: Pointer;
FeatureMask: DWORD64;
Xmm, Ymm: PM128A;
FeatureLength, FeatureLength2: DWORD;
i: Integer;
EM, SEM: TFPUExceptionMask;
begin
{$IFDEF FPDEBUG_THREAD_CHECK}AssertFpDebugThreadId('TDbgWinThread.LoadRegisterValues');{$ENDIF}
@ -1931,16 +1992,67 @@ begin
FRegisterValueList.DbgRegisterAutoCreate['MxCsr'].SetValue(FltSave.MxCsr, IntToStr(FltSave.MxCsr),4,620);
FRegisterValueList.DbgRegisterAutoCreate['MxCsrM'].SetValue(FltSave.MxCsr_Mask, IntToStr(FltSave.MxCsr_Mask),4,621);
end;
{$endif}
{$endif} // 64bit
if _GetEnabledXStateFeatures <> nil then begin
ContextSize := 0;
if _InitializeContext(nil, CONTEXT_ALL or CONTEXT_XSTATE, nil, @ContextSize) or
(GetLastError <> ERROR_INSUFFICIENT_BUFFER)
then
exit;
Buffer := AllocMem(ContextSize+$40);
if Buffer = nil then
exit;
Buffer2 := AlignPtr(Buffer, $40);
try
if not _InitializeContext(Buffer2, CONTEXT_ALL or CONTEXT_XSTATE, @Context, @ContextSize) then
exit;
if not _SetXStateFeaturesMask(Context, XSTATE_MASK_AVX) then
exit;
if not GetThreadContext(Handle, Context^) then // context is VAR PARAM
exit;
Xmm := _LocateXStateFeature(Context, XSTATE_LEGACY_SSE, @FeatureLength);
Ymm := _LocateXStateFeature(Context, XSTATE_AVX, @FeatureLength2);
if (Xmm = nil) or (Ymm = nil) or (FeatureLength2 = 0) then
exit;
{$ifdef cpux86_64}
if (TDbgWinProcess(Process).FBitness = b32) and (FeatureLength > 8 * SizeOf(M128A)) then
FeatureLength := 8 * SizeOf(M128A);
{$endif}
if (_GetXStateFeaturesMask(Context, @FeatureMask)) and
((FeatureMask and XSTATE_MASK_AVX) = 0)
then begin
// AVX not init yet // upper half must be 0
for i := 0 to FeatureLength div SizeOf(M128A) - 1 do begin
FRegisterValueList.DbgRegisterAutoCreate['Ymm'+IntToStr(i)].SetValue
(0, YmmToString(Xmm[i], M128A_NULL),32,700+i);
end;
end
else begin
for i := 0 to FeatureLength div SizeOf(M128A) - 1 do begin
FRegisterValueList.DbgRegisterAutoCreate['Ymm'+IntToStr(i)].SetValue
(0, YmmToString(Xmm[i], Ymm[i]),32,700+i);
end;
end;
finally
Freemem(Buffer);
end;
end;
finally
FRegisterValueListValid:=true;
SetExceptionMask(EM);
{$IF FPC_Fullversion>30202}{$ifNdef cpui386}
softfloat_exception_mask := SEM;
{$endif}{$ENDIF}
end;
FRegisterValueListValid:=true;
end;
function TDbgWinThread.GetFpThreadContext(var AStorage: TFpContext; out