mirror of https://gitlab.com/basile.b/dexed.git
#97, add support for the FPU
This commit is contained in:
parent
6daf51bb9c
commit
b8f0338c18
130
src/ce_gdb.pas
130
src/ce_gdb.pas
|
@ -17,13 +17,22 @@ type
|
||||||
{$IFDEF CPU64}
|
{$IFDEF CPU64}
|
||||||
TCpuRegister = (rax, rbx, rcx, rdx, rsi, rdi, rbp, rsp, r8, r9, r10, r11, r12, r13,
|
TCpuRegister = (rax, rbx, rcx, rdx, rsi, rdi, rbp, rsp, r8, r9, r10, r11, r12, r13,
|
||||||
r14, r15, rip);
|
r14, r15, rip);
|
||||||
|
|
||||||
|
const stOffset = 24;
|
||||||
|
type
|
||||||
|
TFpuRegister = (st0, st1, st2, st3, st4, st5, st6, st7);
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
|
|
||||||
{$IFDEF CPU32}
|
{$IFDEF CPU32}
|
||||||
TCpuRegister = (eax, ebx, ecx, edx, esi, edi, ebp, esp, eip);
|
TCpuRegister = (eax, ebx, ecx, edx, esi, edi, ebp, esp, eip);
|
||||||
|
|
||||||
|
const stOffset = 16;
|
||||||
|
type
|
||||||
|
TFpuRegister = (st0, st1, st2, st3, st4, st5, st6, st7);
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
|
|
||||||
TFpuRegister = (st0, st1, st2, st3, st4, st5, st6, st7);
|
|
||||||
|
|
||||||
|
|
||||||
TFLAG = (CS, PF, AF, ZF, SF, TF, IF_, DF, OF_, NT, RF, VM, AC, VIF, VIP, ID);
|
TFLAG = (CS, PF, AF, ZF, SF, TF, IF_, DF, OF_, NT, RF, VM, AC, VIF, VIP, ID);
|
||||||
TEFLAG = set of TFLAG;
|
TEFLAG = set of TFLAG;
|
||||||
|
@ -79,25 +88,30 @@ type
|
||||||
property EIP: TCpuRegValue index TCpuRegister.eip read fRegisters[TCpuRegister.eip] write setRegister;
|
property EIP: TCpuRegValue index TCpuRegister.eip read fRegisters[TCpuRegister.eip] write setRegister;
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
public
|
public
|
||||||
constructor create(event: TSetGprEvent);
|
constructor create(eventGPR: TSetGprEvent);
|
||||||
procedure setInspectableRegister(index: TCpuRegister; value: PtrUInt);
|
procedure setInspectableRegister(index: TCpuRegister; value: PtrUInt);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// Makes a category for the floating point coprocessor registers in a object inspector
|
TSetFprEvent = procedure(reg: TFpuRegister; val: extended) of object;
|
||||||
|
|
||||||
|
// Makes a category for the floating point unit registers in a object inspector
|
||||||
TInspectableFPR = class(TPersistent)
|
TInspectableFPR = class(TPersistent)
|
||||||
private
|
private
|
||||||
fRegisters: array[TFpuRegister] of double;
|
fRegisters: array[TFpuRegister] of extended;
|
||||||
|
fSetFprEvent: TSetFprEvent;
|
||||||
|
procedure setRegister(index: TFpuRegister; value: extended);
|
||||||
published
|
published
|
||||||
property ST0: double read fRegisters[TFpuRegister.st0];
|
property ST0: extended index TFpuRegister.st0 read fRegisters[TFpuRegister.st0] write setRegister;
|
||||||
property ST1: double read fRegisters[TFpuRegister.st1];
|
property ST1: extended index TFpuRegister.st1 read fRegisters[TFpuRegister.st1] write setRegister;
|
||||||
property ST2: double read fRegisters[TFpuRegister.st2];
|
property ST2: extended index TFpuRegister.st2 read fRegisters[TFpuRegister.st2] write setRegister;
|
||||||
property ST3: double read fRegisters[TFpuRegister.st3];
|
property ST3: extended index TFpuRegister.st3 read fRegisters[TFpuRegister.st3] write setRegister;
|
||||||
property ST4: double read fRegisters[TFpuRegister.st4];
|
property ST4: extended index TFpuRegister.st4 read fRegisters[TFpuRegister.st4] write setRegister;
|
||||||
property ST5: double read fRegisters[TFpuRegister.st5];
|
property ST5: extended index TFpuRegister.st5 read fRegisters[TFpuRegister.st5] write setRegister;
|
||||||
property ST6: double read fRegisters[TFpuRegister.st6];
|
property ST6: extended index TFpuRegister.st6 read fRegisters[TFpuRegister.st6] write setRegister;
|
||||||
property ST7: double read fRegisters[TFpuRegister.st7];
|
property ST7: extended index TFpuRegister.st7 read fRegisters[TFpuRegister.st7] write setRegister;
|
||||||
public
|
public
|
||||||
procedure setInspectableRegister(index: TFpuRegister; value: double);
|
constructor create(event: TSetFprEvent);
|
||||||
|
procedure setInspectableRegister(index: TFpuRegister; value: extended);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// Makes a category for the SSE registers in a object inspector
|
// Makes a category for the SSE registers in a object inspector
|
||||||
|
@ -106,7 +120,6 @@ type
|
||||||
// 4 int ? 2 double ? 4 single ? ...
|
// 4 int ? 2 double ? 4 single ? ...
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
// Makes a category for the local variables in an object inspector
|
// Makes a category for the local variables in an object inspector
|
||||||
TInspectableLocals= class(TPersistent)
|
TInspectableLocals= class(TPersistent)
|
||||||
private
|
private
|
||||||
|
@ -136,17 +149,18 @@ type
|
||||||
published
|
published
|
||||||
property Locals: TInspectableLocals read fLocals;
|
property Locals: TInspectableLocals read fLocals;
|
||||||
property CPU: TInspectableGPR read fGpr;
|
property CPU: TInspectableGPR read fGpr;
|
||||||
|
property FPU: TInspectableFPR read fFpr;
|
||||||
//
|
//
|
||||||
property EFLAGS: TEFLAG read fFlags;
|
property EFLAGS: TEFLAG read fFlags;
|
||||||
//
|
//
|
||||||
property CS: byte read fSegment[TSegmentRegister.S_CS];
|
(*property CS: byte read fSegment[TSegmentRegister.S_CS];
|
||||||
property DS: byte read fSegment[TSegmentRegister.S_DS];
|
property DS: byte read fSegment[TSegmentRegister.S_DS];
|
||||||
property ES: byte read fSegment[TSegmentRegister.S_ES];
|
property ES: byte read fSegment[TSegmentRegister.S_ES];
|
||||||
property FS: byte read fSegment[TSegmentRegister.S_FS];
|
property FS: byte read fSegment[TSegmentRegister.S_FS];
|
||||||
property GS: byte read fSegment[TSegmentRegister.S_GS];
|
property GS: byte read fSegment[TSegmentRegister.S_GS];
|
||||||
property SS: byte read fSegment[TSegmentRegister.S_SS];
|
property SS: byte read fSegment[TSegmentRegister.S_SS];*)
|
||||||
public
|
public
|
||||||
constructor create(setGprEvent: TSetGprEvent);
|
constructor create(setGprEvent: TSetGprEvent; setFprEvent: TSetFprEvent);
|
||||||
destructor destroy; override;
|
destructor destroy; override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -299,6 +313,7 @@ type
|
||||||
procedure menuDeclare(item: TMenuItem);
|
procedure menuDeclare(item: TMenuItem);
|
||||||
procedure menuUpdate(item: TMenuItem);
|
procedure menuUpdate(item: TMenuItem);
|
||||||
//
|
//
|
||||||
|
procedure disableEditor;
|
||||||
procedure setState(value: TGdbState);
|
procedure setState(value: TGdbState);
|
||||||
procedure updateButtonsState;
|
procedure updateButtonsState;
|
||||||
procedure startDebugging;
|
procedure startDebugging;
|
||||||
|
@ -315,6 +330,7 @@ type
|
||||||
procedure infoVariables;
|
procedure infoVariables;
|
||||||
procedure sendCustomCommand;
|
procedure sendCustomCommand;
|
||||||
procedure setGpr(reg: TCpuRegister; val: TCpuRegValue);
|
procedure setGpr(reg: TCpuRegister; val: TCpuRegValue);
|
||||||
|
procedure setFpr(reg: TFpuRegister; val: extended);
|
||||||
//
|
//
|
||||||
procedure projNew(project: ICECommonProject);
|
procedure projNew(project: ICECommonProject);
|
||||||
procedure projChanged(project: ICECommonProject);
|
procedure projChanged(project: ICECommonProject);
|
||||||
|
@ -592,9 +608,9 @@ begin
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
constructor TInspectableGPR.create(event: TSetGprEvent);
|
constructor TInspectableGPR.create(eventGPR: TSetGprEvent);
|
||||||
begin
|
begin
|
||||||
fSetGprEvent:=event;
|
fSetGprEvent:=eventGPR;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TInspectableGPR.setInspectableRegister(index: TCpuRegister; value: PtrUInt);
|
procedure TInspectableGPR.setInspectableRegister(index: TCpuRegister; value: PtrUInt);
|
||||||
|
@ -608,8 +624,19 @@ begin
|
||||||
fRegisters[index] := value;
|
fRegisters[index] := value;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TInspectableFPR.setInspectableRegister(index: TFpuRegister; value: double);
|
constructor TInspectableFPR.create(event: TSetFprEvent);
|
||||||
begin
|
begin
|
||||||
|
fSetFprEvent:=event;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TInspectableFPR.setInspectableRegister(index: TFpuRegister; value: extended);
|
||||||
|
begin
|
||||||
|
fRegisters[index] := value;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TInspectableFPR.setRegister(index: TFpuRegister; value: extended);
|
||||||
|
begin
|
||||||
|
fSetFprEvent(index, value);
|
||||||
fRegisters[index] := value;
|
fRegisters[index] := value;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -660,15 +687,17 @@ begin
|
||||||
fLocals.Values[name] := value;
|
fLocals.Values[name] := value;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
constructor TInspectableState.create(setGprEvent: TSetGprEvent);
|
constructor TInspectableState.create(setGprEvent: TSetGprEvent; setFprEvent: TSetFprEvent);
|
||||||
begin
|
begin
|
||||||
fGpr := TInspectableGPR.Create(setGprEvent);
|
fGpr := TInspectableGPR.create(setGprEvent);
|
||||||
|
fFpr := TInspectableFPR.create(setFprEvent);
|
||||||
fLocals := TInspectableLocals.create;
|
fLocals := TInspectableLocals.create;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
destructor TInspectableState.destroy;
|
destructor TInspectableState.destroy;
|
||||||
begin
|
begin
|
||||||
fGpr.Free;
|
fGpr.Free;
|
||||||
|
fFPr.Free;
|
||||||
fLocals.Free;
|
fLocals.Free;
|
||||||
inherited;
|
inherited;
|
||||||
end;
|
end;
|
||||||
|
@ -684,14 +713,14 @@ begin
|
||||||
fMsg:= getMessageDisplay;
|
fMsg:= getMessageDisplay;
|
||||||
fFileLineBrks:= TStringList.Create;
|
fFileLineBrks:= TStringList.Create;
|
||||||
fLog := TStringList.Create;
|
fLog := TStringList.Create;
|
||||||
fInspState := TInspectableState.Create(@setGpr);
|
fInspState := TInspectableState.Create(@setGpr, @setFpr);
|
||||||
stateViewer.TIObject := fInspState;
|
stateViewer.TIObject := fInspState;
|
||||||
fJson := TJsonObject.Create;
|
fJson := TJsonObject.Create;
|
||||||
fStackItems := TStackItems.create;
|
fStackItems := TStackItems.create;
|
||||||
fSubj:= TCEDebugObserverSubject.Create;
|
fSubj:= TCEDebugObserverSubject.Create;
|
||||||
fOptions:= TCEDebugOptions.create(self);
|
fOptions:= TCEDebugOptions.create(self);
|
||||||
Edit1.Items.Assign(fOptions.commandsHistory);
|
|
||||||
fOptions.onChangesApplied:=@optionsChangesApplied;
|
fOptions.onChangesApplied:=@optionsChangesApplied;
|
||||||
|
Edit1.Items.Assign(fOptions.commandsHistory);
|
||||||
//
|
//
|
||||||
AssignPng(btnSendCom, 'ACCEPT');
|
AssignPng(btnSendCom, 'ACCEPT');
|
||||||
setState(gsNone);
|
setState(gsNone);
|
||||||
|
@ -1046,6 +1075,11 @@ begin
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TCEGdbWidget.disableEditor;
|
||||||
|
begin
|
||||||
|
stateViewer.ItemIndex:=-1;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TCEGdbWidget.startDebugging;
|
procedure TCEGdbWidget.startDebugging;
|
||||||
var
|
var
|
||||||
str: string;
|
str: string;
|
||||||
|
@ -1366,6 +1400,9 @@ var
|
||||||
sigmean: string;
|
sigmean: string;
|
||||||
signame: string;
|
signame: string;
|
||||||
brkreason: TCEDebugBreakReason;
|
brkreason: TCEDebugBreakReason;
|
||||||
|
// FPU
|
||||||
|
fFpuExtended: extended;
|
||||||
|
fFpuRaw: array[0..9] of Byte absolute fFpuExtended;
|
||||||
begin
|
begin
|
||||||
|
|
||||||
val := fJson.Find('reason');
|
val := fJson.Find('reason');
|
||||||
|
@ -1478,19 +1515,34 @@ begin
|
||||||
if val.isNotNil then
|
if val.isNotNil then
|
||||||
number := val.AsInteger;
|
number := val.AsInteger;
|
||||||
val := obj.Find('value');
|
val := obj.Find('value');
|
||||||
if val.isNotNil then
|
if val.isNotNil then case number of
|
||||||
|
0..integer(high(TCpuRegister)):
|
||||||
begin
|
begin
|
||||||
if (0 <= number) and (TCpuRegister(number) <= high(TCpuRegister)) then
|
fInspState.CPU.setInspectableRegister
|
||||||
fInspState.CPU.setInspectableRegister(TCpuRegister(number),
|
(TCpuRegister(number), {$IFDEF CPU64}val.AsInt64{$ELSE}val.AsInteger{$ENDIF});
|
||||||
{$IFDEF CPU64}val.AsInt64{$ELSE}val.AsInteger{$ENDIF});
|
|
||||||
end;
|
end;
|
||||||
|
stOffset..stOffset+7:
|
||||||
|
begin
|
||||||
//else
|
fFpuRaw[9] := StrToInt('$' + val.AsString[3..4]);
|
||||||
// TODO-cGDB: FPU and SSE regs are in a sub object
|
fFpuRaw[8] := StrToInt('$' + val.AsString[5..6]);
|
||||||
// break;
|
fFpuRaw[7] := StrToInt('$' + val.AsString[7..8]);
|
||||||
|
fFpuRaw[6] := StrToInt('$' + val.AsString[9..10]);
|
||||||
|
fFpuRaw[5] := StrToInt('$' + val.AsString[11..12]);
|
||||||
|
fFpuRaw[4] := StrToInt('$' + val.AsString[13..14]);
|
||||||
|
fFpuRaw[3] := StrToInt('$' + val.AsString[15..16]);
|
||||||
|
fFpuRaw[2] := StrToInt('$' + val.AsString[17..18]);
|
||||||
|
fFpuRaw[1] := StrToInt('$' + val.AsString[19..20]);
|
||||||
|
fFpuRaw[0] := StrToInt('$' + val.AsString[21..22]);
|
||||||
|
fInspState.FPU.setInspectableRegister
|
||||||
|
(TFpuRegister(number - stOffset), fFpuExtended);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
// TODO-cGDB: get SSE registers
|
||||||
|
// TODO-cGDB: get Segment registers
|
||||||
|
// TODO-cGDB: get EFLAGS
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
stateViewer.RefreshPropertyValues;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
val := fJson.Find('stack');
|
val := fJson.Find('stack');
|
||||||
|
@ -1619,7 +1671,8 @@ end;
|
||||||
|
|
||||||
procedure TCEGdbWidget.infoRegs;
|
procedure TCEGdbWidget.infoRegs;
|
||||||
begin
|
begin
|
||||||
gdbCommand('-data-list-register-values d', @gdboutJsonize);
|
disableEditor;
|
||||||
|
gdbCommand('-data-list-register-values r', @gdboutJsonize);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCEGdbWidget.infoStack;
|
procedure TCEGdbWidget.infoStack;
|
||||||
|
@ -1721,6 +1774,15 @@ begin
|
||||||
gdbCommand(cmd);
|
gdbCommand(cmd);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TCEGdbWidget.setFpr(reg: TFpuRegister; val: extended);
|
||||||
|
const
|
||||||
|
spec = 'set $%s = %.18g';
|
||||||
|
var
|
||||||
|
cmd : string;
|
||||||
|
begin
|
||||||
|
cmd := format(spec, [GetEnumName(typeinfo(TFpuRegister),integer(reg)), val]);
|
||||||
|
gdbCommand(cmd);
|
||||||
|
end;
|
||||||
{$ENDREGION}
|
{$ENDREGION}
|
||||||
|
|
||||||
initialization
|
initialization
|
||||||
|
|
Loading…
Reference in New Issue