mirror of https://gitlab.com/basile.b/dexed.git
#97, start asm view
This commit is contained in:
parent
2f0655da97
commit
609303c983
252
src/ce_gdb.lfm
252
src/ce_gdb.lfm
|
@ -1,9 +1,8 @@
|
|||
inherited CEGdbWidget: TCEGdbWidget
|
||||
Left = 640
|
||||
Left = 635
|
||||
Height = 668
|
||||
Top = 213
|
||||
Top = 212
|
||||
Width = 517
|
||||
ActiveControl = Back
|
||||
Caption = 'GDB commander'
|
||||
ClientHeight = 668
|
||||
ClientWidth = 517
|
||||
|
@ -20,27 +19,27 @@ inherited CEGdbWidget: TCEGdbWidget
|
|||
ClientWidth = 517
|
||||
object Panel1: TPanel[0]
|
||||
Left = 0
|
||||
Height = 394
|
||||
Top = 196
|
||||
Height = 385
|
||||
Top = 205
|
||||
Width = 517
|
||||
Align = alClient
|
||||
BevelOuter = bvNone
|
||||
ClientHeight = 394
|
||||
ClientHeight = 385
|
||||
ClientWidth = 517
|
||||
TabOrder = 0
|
||||
object GroupBox3: TGroupBox
|
||||
Left = 0
|
||||
Height = 197
|
||||
Top = 197
|
||||
Height = 179
|
||||
Top = 206
|
||||
Width = 517
|
||||
Align = alClient
|
||||
Caption = 'CPU'
|
||||
ClientHeight = 167
|
||||
ClientHeight = 149
|
||||
ClientWidth = 513
|
||||
TabOrder = 0
|
||||
object cpuVIewer: TTIPropertyGrid
|
||||
Left = 0
|
||||
Height = 167
|
||||
Height = 149
|
||||
Hint = 'cpu registers'
|
||||
Top = 0
|
||||
Width = 513
|
||||
|
@ -55,67 +54,103 @@ inherited CEGdbWidget: TCEGdbWidget
|
|||
ValueFont.Color = clMaroon
|
||||
end
|
||||
end
|
||||
object GroupBox2: TGroupBox
|
||||
Left = 0
|
||||
Height = 191
|
||||
Top = 0
|
||||
Width = 517
|
||||
Align = alTop
|
||||
Caption = 'Variables'
|
||||
ClientHeight = 161
|
||||
ClientWidth = 513
|
||||
TabOrder = 1
|
||||
object varList: TListView
|
||||
Left = 2
|
||||
Height = 135
|
||||
Top = 24
|
||||
Width = 509
|
||||
Align = alClient
|
||||
BorderSpacing.Around = 2
|
||||
Columns = <
|
||||
item
|
||||
AutoSize = True
|
||||
Caption = 'Name'
|
||||
Width = 47
|
||||
end
|
||||
item
|
||||
AutoSize = True
|
||||
Caption = 'Value'
|
||||
Width = 458
|
||||
end>
|
||||
GridLines = True
|
||||
HideSelection = False
|
||||
ReadOnly = True
|
||||
ScrollBars = ssAutoBoth
|
||||
SortColumn = 0
|
||||
SortType = stText
|
||||
TabOrder = 0
|
||||
ViewStyle = vsReport
|
||||
end
|
||||
object varListFlt: TListViewFilterEdit
|
||||
Left = 2
|
||||
Height = 20
|
||||
Hint = 'locate variables'
|
||||
Top = 2
|
||||
Width = 509
|
||||
ButtonWidth = 24
|
||||
NumGlyphs = 1
|
||||
Align = alTop
|
||||
BorderSpacing.Around = 2
|
||||
MaxLength = 0
|
||||
TabOrder = 1
|
||||
OnChange = varListFltChange
|
||||
end
|
||||
end
|
||||
object Splitter4: TSplitter
|
||||
Cursor = crVSplit
|
||||
Left = 0
|
||||
Height = 6
|
||||
Top = 191
|
||||
Top = 0
|
||||
Width = 517
|
||||
Align = alTop
|
||||
ResizeAnchor = akTop
|
||||
end
|
||||
object PageControl2: TPageControl
|
||||
Left = 0
|
||||
Height = 200
|
||||
Top = 6
|
||||
Width = 517
|
||||
ActivePage = TabSheet4
|
||||
Align = alTop
|
||||
TabIndex = 1
|
||||
TabOrder = 2
|
||||
object TabSheet3: TTabSheet
|
||||
Caption = 'Variables'
|
||||
ClientHeight = 164
|
||||
ClientWidth = 509
|
||||
object varList: TListView
|
||||
Left = 2
|
||||
Height = 138
|
||||
Top = 24
|
||||
Width = 505
|
||||
Align = alClient
|
||||
BorderSpacing.Around = 2
|
||||
Columns = <
|
||||
item
|
||||
AutoSize = True
|
||||
Caption = 'Name'
|
||||
Width = 47
|
||||
end
|
||||
item
|
||||
AutoSize = True
|
||||
Caption = 'Value'
|
||||
Width = 454
|
||||
end>
|
||||
GridLines = True
|
||||
HideSelection = False
|
||||
ReadOnly = True
|
||||
ScrollBars = ssAutoBoth
|
||||
SortColumn = 0
|
||||
SortType = stText
|
||||
TabOrder = 0
|
||||
ViewStyle = vsReport
|
||||
end
|
||||
object varListFlt: TListViewFilterEdit
|
||||
Left = 2
|
||||
Height = 20
|
||||
Hint = 'locate variables'
|
||||
Top = 2
|
||||
Width = 505
|
||||
ButtonWidth = 24
|
||||
NumGlyphs = 1
|
||||
Align = alTop
|
||||
BorderSpacing.Around = 2
|
||||
MaxLength = 0
|
||||
TabOrder = 1
|
||||
OnChange = varListFltChange
|
||||
end
|
||||
end
|
||||
object TabSheet4: TTabSheet
|
||||
Caption = 'Assembly'
|
||||
ClientHeight = 164
|
||||
ClientWidth = 509
|
||||
object asmList: TListView
|
||||
Left = 2
|
||||
Height = 160
|
||||
Top = 2
|
||||
Width = 505
|
||||
Align = alClient
|
||||
AutoSort = False
|
||||
BorderSpacing.Around = 2
|
||||
Columns = <
|
||||
item
|
||||
AutoSize = True
|
||||
Caption = 'Address'
|
||||
Width = 60
|
||||
end
|
||||
item
|
||||
AutoSize = True
|
||||
Caption = 'Instruction'
|
||||
Width = 441
|
||||
end>
|
||||
GridLines = True
|
||||
HideSelection = False
|
||||
ReadOnly = True
|
||||
ScrollBars = ssAutoBoth
|
||||
SortColumn = 0
|
||||
TabOrder = 0
|
||||
ViewStyle = vsReport
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
object Panel3: TPanel[1]
|
||||
Left = 4
|
||||
|
@ -152,55 +187,62 @@ inherited CEGdbWidget: TCEGdbWidget
|
|||
TabOrder = 0
|
||||
end
|
||||
end
|
||||
object GroupBox1: TGroupBox[2]
|
||||
Left = 0
|
||||
Height = 191
|
||||
Top = 0
|
||||
Width = 517
|
||||
Align = alTop
|
||||
Caption = 'Call stack'
|
||||
ClientHeight = 161
|
||||
ClientWidth = 513
|
||||
TabOrder = 2
|
||||
object lstCallStack: TListView
|
||||
Left = 0
|
||||
Height = 161
|
||||
Hint = 'call stack'
|
||||
Top = 0
|
||||
Width = 513
|
||||
Align = alClient
|
||||
Columns = <
|
||||
item
|
||||
AutoSize = True
|
||||
Caption = 'function'
|
||||
Width = 62
|
||||
end
|
||||
item
|
||||
AutoSize = True
|
||||
Caption = 'address'
|
||||
Width = 59
|
||||
end
|
||||
item
|
||||
AutoSize = True
|
||||
Caption = 'filename'
|
||||
Width = 371
|
||||
end>
|
||||
GridLines = True
|
||||
ReadOnly = True
|
||||
TabOrder = 0
|
||||
ViewStyle = vsReport
|
||||
OnDblClick = lstCallStackDblClick
|
||||
end
|
||||
end
|
||||
object Splitter3: TSplitter[3]
|
||||
object Splitter3: TSplitter[2]
|
||||
Cursor = crVSplit
|
||||
Left = 0
|
||||
Height = 5
|
||||
Top = 191
|
||||
Top = 200
|
||||
Width = 517
|
||||
Align = alTop
|
||||
ResizeAnchor = akTop
|
||||
end
|
||||
object PageControl1: TPageControl[3]
|
||||
Left = 0
|
||||
Height = 200
|
||||
Top = 0
|
||||
Width = 517
|
||||
ActivePage = TabSheet1
|
||||
Align = alTop
|
||||
TabIndex = 0
|
||||
TabOrder = 3
|
||||
object TabSheet1: TTabSheet
|
||||
Caption = 'Call stack'
|
||||
ClientHeight = 164
|
||||
ClientWidth = 509
|
||||
object lstCallStack: TListView
|
||||
Left = 0
|
||||
Height = 164
|
||||
Hint = 'call stack'
|
||||
Top = 0
|
||||
Width = 509
|
||||
Align = alClient
|
||||
Columns = <
|
||||
item
|
||||
AutoSize = True
|
||||
Caption = 'function'
|
||||
Width = 62
|
||||
end
|
||||
item
|
||||
AutoSize = True
|
||||
Caption = 'address'
|
||||
Width = 59
|
||||
end
|
||||
item
|
||||
AutoSize = True
|
||||
Caption = 'filename'
|
||||
Width = 367
|
||||
end>
|
||||
GridLines = True
|
||||
ReadOnly = True
|
||||
TabOrder = 0
|
||||
ViewStyle = vsReport
|
||||
OnDblClick = lstCallStackDblClick
|
||||
end
|
||||
end
|
||||
object TabSheet2: TTabSheet
|
||||
Caption = 'Thread list'
|
||||
end
|
||||
end
|
||||
end
|
||||
inherited toolbar: TCEToolBar
|
||||
Width = 509
|
||||
|
|
122
src/ce_gdb.pas
122
src/ce_gdb.pas
|
@ -7,7 +7,7 @@ interface
|
|||
uses
|
||||
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, RegExpr, ComCtrls,
|
||||
PropEdits, GraphPropEdits, RTTIGrids, Dialogs, ExtCtrls, Menus, Buttons,
|
||||
StdCtrls, process, fpjson, typinfo, {$IFDEF UNIX}Unix,{$ENDIF} ListViewFilterEdit,
|
||||
StdCtrls, process, fpjson, typinfo, Unix, ListViewFilterEdit, SynEdit,
|
||||
ce_common, ce_interfaces, ce_widget, ce_processes, ce_observer, ce_synmemo,
|
||||
ce_sharedres, ce_stringrange, ce_dsgncontrols, ce_dialogs, ce_dbgitf,
|
||||
ce_ddemangle, ce_writableComponent, EditBtn, strutils;
|
||||
|
@ -330,9 +330,13 @@ type
|
|||
btnWatch: TCEToolButton;
|
||||
button4: TCEToolButton;
|
||||
Edit1: TComboBox;
|
||||
GroupBox1: TGroupBox;
|
||||
GroupBox2: TGroupBox;
|
||||
GroupBox3: TGroupBox;
|
||||
PageControl1: TPageControl;
|
||||
PageControl2: TPageControl;
|
||||
TabSheet1: TTabSheet;
|
||||
TabSheet2: TTabSheet;
|
||||
TabSheet3: TTabSheet;
|
||||
TabSheet4: TTabSheet;
|
||||
varList: TListView;
|
||||
lstCallStack: TListView;
|
||||
mnuReadW: TMenuItem;
|
||||
|
@ -349,6 +353,7 @@ type
|
|||
Splitter2: TSplitter;
|
||||
Splitter3: TSplitter;
|
||||
Splitter4: TSplitter;
|
||||
asmList: TListView;
|
||||
varListFlt: TListViewFilterEdit;
|
||||
procedure btnContClick(Sender: TObject);
|
||||
procedure btnVariablesClick(Sender: TObject);
|
||||
|
@ -396,6 +401,10 @@ type
|
|||
fAddWatchPointKind: TAddWatchPointKind;
|
||||
fBreakPoints: TPersistentBreakPoints;
|
||||
fMenu: TMenuItem;
|
||||
fLastFilename: string;
|
||||
fLastFunction: string;
|
||||
fLastOffset: string;
|
||||
fLastLine: string;
|
||||
procedure updateMenu;
|
||||
procedure optionsChangesApplied(sender: TObject);
|
||||
procedure disableEditor;
|
||||
|
@ -413,6 +422,7 @@ type
|
|||
procedure infoRegs;
|
||||
procedure infoStack;
|
||||
procedure infoVariables;
|
||||
procedure infoAsm(const fname: string);
|
||||
procedure sendCustomCommand;
|
||||
procedure setGpr(reg: TCpuRegister; val: TCpuGprValue);
|
||||
procedure setFpr(reg: TFpuRegister; val: extended);
|
||||
|
@ -1660,6 +1670,18 @@ end;
|
|||
|
||||
procedure TCEGdbWidget.interpretJson;
|
||||
|
||||
procedure selectAsmInstr;
|
||||
var
|
||||
itm: TListItem;
|
||||
begin
|
||||
itm := asmList.FindCaption(0, fLastOffset, false, true, false);
|
||||
if itm.isNotNil then
|
||||
begin
|
||||
itm.Selected:=true;
|
||||
itm.MakeVisible(false);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure autoGetStuff;
|
||||
begin
|
||||
if fOptions.autoGetCallStack then
|
||||
|
@ -1668,6 +1690,7 @@ procedure TCEGdbWidget.interpretJson;
|
|||
infoRegs;
|
||||
if fOptions.autoGetVariables then
|
||||
infoVariables;
|
||||
selectAsmInstr;
|
||||
end;
|
||||
|
||||
var
|
||||
|
@ -1681,7 +1704,6 @@ var
|
|||
nme: string;
|
||||
reason: string;
|
||||
addr: PtrUint = 0;
|
||||
fullname: string = '';
|
||||
func:string = '';
|
||||
line: integer = -1;
|
||||
// registers data
|
||||
|
@ -1726,18 +1748,31 @@ begin
|
|||
obj := TJSONObject(fJson.Find('frame'));
|
||||
if obj.isNotNil and (obj.JSONType = jtObject) then
|
||||
begin
|
||||
val := obj.Find('addr');
|
||||
if val.isNotNil then
|
||||
fLastOffset:=val.AsString;
|
||||
val := obj.Find('fullname');
|
||||
if val.isNotNil then
|
||||
fullname := val.AsString;
|
||||
fLastFilename := val.AsString;
|
||||
val := obj.Find('line');
|
||||
if val.isNotNil then
|
||||
begin
|
||||
line := val.AsInteger;
|
||||
if fDocHandler.findDocument(fullname).isNil and fullname.fileExists then
|
||||
fDocHandler.openDocument(fullname);
|
||||
fLastLine := val.AsString;
|
||||
end;
|
||||
val := obj.Find('func');
|
||||
if val.isNotNil then
|
||||
begin
|
||||
if val.AsString <> fLastFunction then
|
||||
infoAsm(fLastFilename);
|
||||
fLastFunction := val.AsString;
|
||||
end;
|
||||
if fDocHandler.findDocument(fLastFilename).isNil and fLastFilename.fileExists then
|
||||
fDocHandler.openDocument(fLastFilename);
|
||||
setState(gsPaused);
|
||||
autoGetStuff;
|
||||
readOutput;
|
||||
subjDebugBreak(fSubj, fullname, line, brkreason);
|
||||
subjDebugBreak(fSubj, fLastFilename, line, brkreason);
|
||||
end;
|
||||
end
|
||||
|
||||
|
@ -1762,27 +1797,37 @@ begin
|
|||
obj := TJSONObject(fJson.Find('frame'));
|
||||
if obj.isNotNil and (obj.JSONType = jtObject) then
|
||||
begin
|
||||
val := obj.Find('addr');
|
||||
if val.isNotNil then
|
||||
fLastOffset:=val.AsString;
|
||||
val := obj.Find('fullname');
|
||||
if val.isNotNil then
|
||||
fullname := val.AsString;
|
||||
fLastFilename := val.AsString;
|
||||
val := obj.Find('line');
|
||||
if val.isNotNil then
|
||||
line := val.AsInteger;
|
||||
val := obj.Find('func');
|
||||
if val.isNotNil then
|
||||
begin
|
||||
if val.AsString <> fLastFunction then
|
||||
infoAsm(fLastFilename);
|
||||
fLastFunction := val.AsString;
|
||||
end;
|
||||
end;
|
||||
if fCatchPause then
|
||||
begin
|
||||
fCatchPause := false;
|
||||
if fDocHandler.findDocument(fullname).isNil and fullname.fileExists then
|
||||
fDocHandler.openDocument(fullname);
|
||||
if fDocHandler.findDocument(fLastFilename).isNil and fLastFilename.fileExists then
|
||||
fDocHandler.openDocument(fLastFilename);
|
||||
autoGetStuff;
|
||||
setState(gsPaused);
|
||||
readOutput;
|
||||
subjDebugBreak(fSubj, fullname, line, dbSignal);
|
||||
subjDebugBreak(fSubj, fLastFilename, line, dbSignal);
|
||||
end
|
||||
else
|
||||
begin
|
||||
if dlgYesNo(format('The signal %s (%s) was received on line %d of file %s .'
|
||||
+ LineEnding + 'Do you wish to pause execution ?', [signame, sigmean, line, fullname]),
|
||||
+ LineEnding + 'Do you wish to pause execution ?', [signame, sigmean, line, fLastFilename]),
|
||||
'Unexpected signal received') = mrNo then
|
||||
begin
|
||||
gdbCommand('continue', @gdboutJsonize);
|
||||
|
@ -1790,12 +1835,12 @@ begin
|
|||
end
|
||||
else
|
||||
begin
|
||||
if not fDocHandler.findDocument(fullname).isNil and fullname.fileExists then
|
||||
fDocHandler.openDocument(fullname);
|
||||
if not fDocHandler.findDocument(fLastFilename).isNil and fLastFilename.fileExists then
|
||||
fDocHandler.openDocument(fLastFilename);
|
||||
autoGetStuff;
|
||||
setState(gsPaused);
|
||||
readOutput;
|
||||
subjDebugBreak(fSubj, fullname, line, dbSignal);
|
||||
subjDebugBreak(fSubj, fLastFilename, line, dbSignal);
|
||||
end;
|
||||
end;
|
||||
end
|
||||
|
@ -1884,7 +1929,7 @@ begin
|
|||
break;
|
||||
val := obj.Find('fullname');
|
||||
if val.isNotNil then
|
||||
fullname:= val.AsString;
|
||||
fLastFilename:= val.AsString;
|
||||
val := obj.Find('func');
|
||||
if val.isNotNil then
|
||||
begin
|
||||
|
@ -1899,7 +1944,7 @@ begin
|
|||
val := obj.Find('line');
|
||||
if val.isNotNil then
|
||||
line := val.AsInteger;
|
||||
fStackItems.addItem(addr, fullname, func, line);
|
||||
fStackItems.addItem(addr, fLastFilename, func, line);
|
||||
end;
|
||||
fStackItems.assignToList(lstCallStack);
|
||||
end;
|
||||
|
@ -1935,6 +1980,38 @@ begin
|
|||
varList.EndUpdate;
|
||||
end;
|
||||
|
||||
val := fJson.Find('asm_insns');
|
||||
if val.isNotNil and (val.JSONType = jtArray) then
|
||||
begin
|
||||
asmList.Clear;
|
||||
asmList.BeginUpdate;
|
||||
arr := TJSONArray(val);
|
||||
for i := 0 to arr.Count-1 do
|
||||
begin
|
||||
obj := arr.Objects[i];
|
||||
val := obj.Find('address');
|
||||
if val.isNotNil then
|
||||
nme := val.AsString;
|
||||
//val := obj.Find('func-name');
|
||||
//val := obj.Find('offset');
|
||||
val := obj.Find('inst');
|
||||
if val.isNotNil then
|
||||
begin
|
||||
asmList.AddItem(nme, nil);
|
||||
if nme = fLastOffset then
|
||||
asmList.Selected := asmList.Items[asmList.Items.Count-1];
|
||||
if fOptions.autoDemangle then
|
||||
asmList.Items[asmList.Items.Count-1].SubItems.Add(demangle(val.AsString))
|
||||
else
|
||||
asmList.Items[asmList.Items.Count-1].SubItems.Add(val.AsString);
|
||||
end;
|
||||
end;
|
||||
if asmList.Selected.isNotNil then
|
||||
asmList.Selected.MakeVisible(false);
|
||||
asmList.EndUpdate;
|
||||
selectAsmInstr;
|
||||
end;
|
||||
|
||||
if fOptions.showGdbOutput or fShowFromCustomCommand then
|
||||
begin
|
||||
fShowFromCustomCommand := false;
|
||||
|
@ -2042,6 +2119,15 @@ begin
|
|||
gdbCommand('-stack-list-variables --skip-unavailable --simple-values');
|
||||
end;
|
||||
|
||||
procedure TCEGdbWidget.infoAsm(const fname: string);
|
||||
var
|
||||
cmd: string;
|
||||
begin
|
||||
cmd := format('-data-disassemble -f %s -l %s -n -1 -- 0', [fname, fLastLine]);
|
||||
//cmd := format('-data-disassemble -s %s -e $pc -- 0', [fLastOffset]);
|
||||
gdbCommand(cmd, @gdboutJsonize);
|
||||
end;
|
||||
|
||||
procedure TCEGdbWidget.btnStartClick(Sender: TObject);
|
||||
begin
|
||||
startDebugging;
|
||||
|
|
Loading…
Reference in New Issue