mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-07 22:58:14 +02:00
FpDebug: Windows, Ymm register
This commit is contained in:
parent
114c136702
commit
7cf389203d
@ -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 }
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user