FPDebug: clean up / refactor

git-svn-id: trunk@43292 -
This commit is contained in:
martin 2013-10-20 16:12:51 +00:00
parent 0d547128bd
commit 718a99efdd
9 changed files with 155 additions and 67 deletions

View File

@ -37,9 +37,9 @@ interface
uses
{$ifdef windows}
Windows, FpImgReaderWinPE,
Windows,
{$endif}
Classes, Maps, FpDbgUtil, FpDbgWinExtra, FpDbgLoader, LazLoggerBase, LazClasses;
Classes, SysUtils, Maps, FpDbgUtil, FpDbgWinExtra, FpDbgLoader, LazLoggerBase, LazClasses;
type
TDbgPtr = QWord; // PtrUInt;
@ -68,6 +68,12 @@ type
end;
{$endif}
TDbgSymbolType = (
stNone,
stValue, // The symbol has a value (var, field, function, procedure (value is address of func/proc, so it can be called)
stType // The Symbol is a type (including proc/func declaration / without DW_AT_low_pc)
);
TDbgSymbolKind = (
skNone, // undefined type
// skUser, // userdefined type, this sym refers to another sym defined elswhere
@ -113,7 +119,7 @@ type
TDbgSymbolFlags = set of TDbgSymbolFlag;
TDbgSymbolField = (
sfName, sfKind
sfiName, sfiKind, sfiSymType, sfiAddress, sfiSize
);
TDbgSymbolFields = set of TDbgSymbolField;
@ -121,14 +127,22 @@ type
TDbgSymbol = class(TRefCountedObject)
private
FEvaluatedFields: TDbgSymbolFields;
// Cached fields
FName: String;
FKind: TDbgSymbolKind;
FSymbolType: TDbgSymbolType;
FAddress: TDbgPtr;
FSize: Integer;
FEvaluatedFields: TDbgSymbolFields;
function GetKind: TDbgSymbolKind;
function GetSymbolType: TDbgSymbolType; inline;
function GetKind: TDbgSymbolKind; inline;
function GetName: String;
function GetSize: Integer;
function GetAddress: TDbgPtr;
protected
// NOT cached fields
function GetPointedToType: TDbgSymbol; virtual;
function GetChild(AIndex: Integer): TDbgSymbol; virtual;
@ -139,23 +153,31 @@ type
function GetLine: Cardinal; virtual;
function GetParent: TDbgSymbol; virtual;
function GetReference: TDbgSymbol; virtual;
function GetSize: Integer; virtual;
protected
// Cached fields
procedure SetName(AValue: String);
procedure SetKind(AValue: TDbgSymbolKind);
procedure SetSymbolType(AValue: TDbgSymbolType);
procedure SetAddress(AValue: TDbgPtr);
procedure SetSize(AValue: Integer);
procedure KindNeeded; virtual;
procedure NameNeeded; virtual;
procedure SymbolTypeNeeded; virtual;
procedure AddressNeeded; virtual;
procedure SizeNeeded; virtual;
//procedure Needed; virtual;
public
constructor Create(const AName: String);
constructor Create(const AName: String; AKind: TDbgSymbolKind; AAddress: TDbgPtr);
destructor Destroy; override;
// Basic info
property Name: String read GetName;
property Kind: TDbgSymbolKind read GetKind;
property Name: String read GetName;
property SymbolType: TDbgSymbolType read GetSymbolType;
property Kind: TDbgSymbolKind read GetKind;
// Memory; Size is also part of type (byte vs word vs ...)
property Address: TDbgPtr read FAddress;
property Size: Integer read GetSize;
property Address: TDbgPtr read GetAddress;
property Size: Integer read GetSize; // In Bytes
// Location
property FileName: String read GetFile;
property Line: Cardinal read GetLine;
@ -305,8 +327,8 @@ function dbgs(ADbgSymbolKind: TDbgSymbolKind): String; overload;
implementation
uses
SysUtils, FpDbgDwarf;
//uses
// FpDbgDwarf;
procedure LogLastError;
begin
@ -416,8 +438,9 @@ end;
procedure TDbgInstance.LoadInfo;
begin
FLoader := TDbgImageLoader.Create(FModuleHandle);
FDbgInfo := TDbgDwarf.Create(FLoader);
TDbgDwarf(FDbgInfo).LoadCompilationUnits;
assert(false, 'fpc will not compile this');
//FDbgInfo := TDbgDwarf.Create(FLoader);
//TDbgDwarf(FDbgInfo).LoadCompilationUnits;
end;
function TDbgInstance.RemoveBreak(const AFileName: String; ALine: Cardinal): Boolean;
@ -905,35 +928,74 @@ begin
inherited Destroy;
end;
function TDbgSymbol.GetAddress: TDbgPtr;
begin
if not(sfiAddress in FEvaluatedFields) then
AddressNeeded;
Result := FAddress;
end;
function TDbgSymbol.GetKind: TDbgSymbolKind;
begin
if not(sfKind in FEvaluatedFields) then
if not(sfiKind in FEvaluatedFields) then
KindNeeded;
Result := FKind;
end;
function TDbgSymbol.GetName: String;
begin
if not(sfName in FEvaluatedFields) then
if not(sfiName in FEvaluatedFields) then
NameNeeded;
Result := FName;
end;
function TDbgSymbol.GetSize: Integer;
begin
if not(sfiSize in FEvaluatedFields) then
SizeNeeded;
Result := FSize;
end;
function TDbgSymbol.GetSymbolType: TDbgSymbolType;
begin
if not(sfiSymType in FEvaluatedFields) then
SymbolTypeNeeded;
Result := FSymbolType;
end;
function TDbgSymbol.GetPointedToType: TDbgSymbol;
begin
Result := nil;
end;
procedure TDbgSymbol.SetAddress(AValue: TDbgPtr);
begin
FAddress := AValue;
Include(FEvaluatedFields, sfiAddress);
end;
procedure TDbgSymbol.SetKind(AValue: TDbgSymbolKind);
begin
FKind := AValue;
Include(FEvaluatedFields, sfKind);
Include(FEvaluatedFields, sfiKind);
end;
procedure TDbgSymbol.SetSymbolType(AValue: TDbgSymbolType);
begin
FSymbolType := AValue;
Include(FEvaluatedFields, sfiSymType);
end;
procedure TDbgSymbol.SetSize(AValue: Integer);
begin
FSize := AValue;
Include(FEvaluatedFields, sfiSize);
end;
procedure TDbgSymbol.SetName(AValue: String);
begin
FName := AValue;
Include(FEvaluatedFields, sfName);
Include(FEvaluatedFields, sfiName);
end;
function TDbgSymbol.GetChild(AIndex: Integer): TDbgSymbol;
@ -976,11 +1038,6 @@ begin
Result := nil;
end;
function TDbgSymbol.GetSize: Integer;
begin
Result := 0;
end;
procedure TDbgSymbol.KindNeeded;
begin
SetKind(skNone);
@ -991,6 +1048,21 @@ begin
SetName('');
end;
procedure TDbgSymbol.SymbolTypeNeeded;
begin
SetSymbolType(stNone);
end;
procedure TDbgSymbol.AddressNeeded;
begin
SetAddress(0);
end;
procedure TDbgSymbol.SizeNeeded;
begin
SetSize(0);
end;
{$ifdef windows}
{ TDbgBreak }

View File

@ -43,7 +43,7 @@ uses
{$ifdef windows}
Windows,
{$endif}
FpDbgUtil, FpDbgWinExtra, FpDbgClasses;
FpDbgUtil, FpDbgClasses;
{
The function Disassemble decodes the instruction at the given address.

View File

@ -42,7 +42,7 @@ interface
uses
Classes, Types, SysUtils, FpDbgClasses, FpDbgDwarfConst, Maps, Math,
FpDbgLoader, FpDbgWinExtra, FpImgReaderBase, LazLoggerBase, LazClasses, contnrs;
FpDbgLoader, FpImgReaderBase, LazLoggerBase, LazClasses, contnrs;
type
// compilation unit header
@ -526,6 +526,8 @@ type
//function GetSize: Integer; override;
property TypeInfo: TDbgDwarfTypeIdentifier read GetTypeInfo;
property InformationEntry: TDwarfInformationEntry read FInformationEntry;
procedure Init; virtual;
class function GetSubClass(ATag: Cardinal): TDbgDwarfIdentifierClass;
public
class function CreateSubClass(AName: String; AnInformationEntry: TDwarfInformationEntry): TDbgDwarfIdentifier;
@ -540,6 +542,7 @@ type
TDbgDwarfValueIdentifier = class(TDbgDwarfIdentifier) // var, const, member, ...
protected
procedure KindNeeded; override;
procedure Init; override;
public
property TypeInfo;
end;
@ -595,6 +598,7 @@ DECL = DW_AT_decl_column, DW_AT_decl_file, DW_AT_decl_line
function GetIsPointerType: Boolean; virtual;
function GetIsStructType: Boolean; virtual;
function GetStructTypeInfo: TDbgDwarfIdentifierStructure; virtual;
procedure Init; override;
public
class function CreateTybeSubClass(AName: String; AnInformationEntry: TDwarfInformationEntry): TDbgDwarfTypeIdentifier;
property TypeInfo;
@ -685,6 +689,8 @@ DECL = DW_AT_decl_column, DW_AT_decl_file, DW_AT_decl_line
function StateMachineValid: Boolean;
protected
procedure KindNeeded; override;
procedure SizeNeeded; override;
function GetChild(AIndex: Integer): TDbgSymbol; override;
function GetColumn: Cardinal; override;
function GetCount: Integer; override;
@ -693,7 +699,6 @@ DECL = DW_AT_decl_column, DW_AT_decl_file, DW_AT_decl_line
function GetLine: Cardinal; override;
function GetParent: TDbgSymbol; override;
// function GetReference: TDbgSymbol; override;
function GetSize: Integer; override;
public
constructor Create(ACompilationUnit: TDwarfCompilationUnit; AInfo: PDwarfAddressInfo; AAddress: TDbgPtr); overload;
destructor Destroy; override;
@ -1218,6 +1223,12 @@ begin
SetKind(t.Kind);
end;
procedure TDbgDwarfValueIdentifier.Init;
begin
inherited Init;
SetSymbolType(stValue);
end;
{ TDbgDwarfIdentifierArray }
procedure TDbgDwarfIdentifierArray.KindNeeded;
@ -1473,6 +1484,12 @@ begin
Result := nil;
end;
procedure TDbgDwarfTypeIdentifier.Init;
begin
inherited Init;
SetSymbolType(stType);
end;
function TDbgDwarfTypeIdentifier.GetIsBaseType: Boolean;
begin
Result := False;
@ -1636,8 +1653,6 @@ begin
end;
function TDwarfInformationEntry.FindNamedChild(AName: String): TDwarfInformationEntry;
var
ScopeEntryName: String;
begin
Result := nil;
if (not FScope.IsValid) and (FInformationEntry <> nil) then
@ -1654,7 +1669,6 @@ end;
function TDwarfInformationEntry.FindChildByTag(ATag: Cardinal): TDwarfInformationEntry;
var
Scope: TDwarfScopeInfo;
EntryName: String;
AbbrList: TDwarfAbbrevList;
Abbr: TDwarfAbbrev;
begin
@ -1869,6 +1883,11 @@ begin
SetName(AName);
end;
procedure TDbgDwarfIdentifier.Init;
begin
//
end;
class function TDbgDwarfIdentifier.GetSubClass(ATag: Cardinal): TDbgDwarfIdentifierClass;
begin
case ATag of
@ -1910,6 +1929,7 @@ begin
FInformationEntry.AddReference;
inherited Create(AName);
Init;
end;
constructor TDbgDwarfIdentifier.Create(AName: String;
@ -1920,6 +1940,7 @@ begin
FInformationEntry.AddReference;
inherited Create(AName, AKind, AAddress);
Init;
end;
destructor TDbgDwarfIdentifier.Destroy;
@ -2774,11 +2795,6 @@ begin
Result:=inherited GetParent;
end;
function TDbgDwarfProcSymbol.GetSize: Integer;
begin
Result := FAddressInfo^.EndPC - FAddressInfo^.StartPC;
end;
function TDbgDwarfProcSymbol.StateMachineValid: Boolean;
var
SM1, SM2: TDwarfLineInfoStateMachine;
@ -2830,6 +2846,11 @@ begin
SetKind(skProcedure);
end;
procedure TDbgDwarfProcSymbol.SizeNeeded;
begin
SetSize(FAddressInfo^.EndPC - FAddressInfo^.StartPC);
end;
{ TDbgDwarf }
constructor TDbgDwarf.Create(ALoader: TDbgImageLoader);
@ -2923,14 +2944,8 @@ var
SubRoutine: TDbgDwarfProcSymbol; // TDbgSymbol;
CU: TDwarfCompilationUnit;
//Scope,
Scope2: TDwarfScopeInfo;
Form: Cardinal;
Attrib: Pointer;
SubName, EntryName: String;
StartScopeIdx: Integer;
AtTypeAddr: Pointer;
InfoEntry, InfoEntry2: TDwarfInformationEntry;
AtTypeCU: TDwarfCompilationUnit;
InfoEntry: TDwarfInformationEntry;
begin
Result := nil;
SubRoutine := TDbgDwarfProcSymbol(FindSymbol(AAddress));
@ -2970,7 +2985,6 @@ begin
finally
ReleaseRefAndNil(SubRoutine);
ReleaseRefAndNil(InfoEntry);
ReleaseRefAndNil(InfoEntry2);
end;
end;
@ -3632,7 +3646,6 @@ function TDwarfCompilationUnit.GetLineAddressMap(const AFileName: String): PDWar
end;
var
idx: Integer;
Map: TMap;
begin
Result := nil;
if not Valid then Exit;
@ -3689,7 +3702,6 @@ end;
function TDwarfCompilationUnit.LocateAttribute(AEntry: Pointer; AAttribute: Cardinal; out
AAttribPtr: Pointer; out AForm: Cardinal): Boolean;
var
Abbrev: Cardinal;
Def: TDwarfAbbrev;
n: Integer;
ADefs: PDwarfAbbrevEntry;
@ -3784,7 +3796,6 @@ var
BuildList: Boolean; // set once if we need to fill the list
Searching: Boolean; // set as long as we need searching for a tag.
p2: Pointer;
Def2: TDwarfAbbrev;
ni: Integer;
// we cannot use result for this, since we might want a topnode search while we need to be continuable
begin

View File

@ -42,7 +42,7 @@ interface
uses
LCLType,
FpImgReaderBase, FpImgReaderWinPE, FpImgReaderElf, FpImgReaderMacho,
Classes, SysUtils, FpDbgPETypes, LazUTF8Classes;
Classes, SysUtils;
type

View File

@ -8,7 +8,7 @@ uses
{$ifdef windows}
Windows, // After LCLType
{$endif}
Classes, SysUtils, LazUTF8Classes;
Classes, SysUtils;
type
TDbgImageSection = record

View File

@ -139,7 +139,6 @@ procedure TPEFileSource.LoadSections;
var
DosHeader: TImageDosHeader;
ModulePtr: Pointer;
NtHeaders: record
case integer of
1: (Sys: TImageNtHeaders;);
@ -148,7 +147,6 @@ var
end;
SectionHeader: PImageSectionHeader;
n, i: Integer;
p: Pointer;
SectionName: array[0..IMAGE_SIZEOF_SHORT_NAME] of Char;
SectionMax: QWord;
s: string[255];

View File

@ -598,13 +598,11 @@ begin
if FDbgType = nil then
exit;
if FDbgType is TDbgDwarfValueIdentifier then
Result := TDbgDwarfValueIdentifier(FDbgType).TypeInfo
else
if FDbgType is TDbgDwarfTypeIdentifier then
Result := FDbgType
else
Result := nil; // Todo handled by typecast operator // maybe wrap in TTypeOf class?
case FDbgType.SymbolType of
stValue: Result := TDbgDwarfValueIdentifier(FDbgType).TypeInfo;
stType: Result := FDbgType;
else Result := nil;
end;
if Result <> nil then
Result.AddReference;
@ -614,7 +612,7 @@ function TFpPascalExpressionPartIdentifer.DoGetIsTypeCast: Boolean;
begin
if FDbgType = nil then
FDbgType := FExpression.GetDbgTyeForIdentifier(GetText);
Result := (FDbgType <> nil) and (FDbgType is TDbgDwarfTypeIdentifier);
Result := (FDbgType <> nil) and (FDbgType.SymbolType = stType);
end;
destructor TFpPascalExpressionPartIdentifer.Destroy;
@ -1446,13 +1444,13 @@ begin
tmp := Items[0].ResultType;
// Todo unit
if (tmp <> nil) and (tmp is TDbgDwarfTypeIdentifier) and
if (tmp <> nil) and (tmp.SymbolType = stType) and
(TDbgDwarfTypeIdentifier(tmp).IsStructType)
then begin
struct := TDbgDwarfTypeIdentifier(tmp).StructTypeInfo;
tmp := struct.MemberByName[Items[1].GetText];
if (tmp <> nil) and (tmp is TDbgDwarfValueIdentifier) then begin
if (tmp <> nil) and (tmp.SymbolType = stValue) then begin
Result := TDbgDwarfValueIdentifier(tmp).TypeInfo;
Result.AddReference;
end;

View File

@ -376,6 +376,22 @@ begin
TestExpr([0,0,0], TFpPascalExpressionPartIdentifer, 'f', 0);
TestExpr([0,1], TFpPascalExpressionPartIdentifer, 'a', 0);
CreateExpr('@f(a)(b)', True);
TestExpr([], TFpPascalExpressionPartOperatorAddressOf, '@', 1);
TestExpr([0], TFpPascalExpressionPartBracketArgumentList, '(', 2);
TestExpr([0,0], TFpPascalExpressionPartBracketArgumentList, '(', 2);
TestExpr([0,0,0], TFpPascalExpressionPartIdentifer, 'f', 0);
TestExpr([0,0,1], TFpPascalExpressionPartIdentifer, 'a', 0);
TestExpr([0,1], TFpPascalExpressionPartIdentifer, 'b', 0);
CreateExpr('f(a)(b)^', True);
TestExpr([], TFpPascalExpressionPartOperatorDeRef, '^', 1);
TestExpr([0], TFpPascalExpressionPartBracketArgumentList, '(', 2);
TestExpr([0,0], TFpPascalExpressionPartBracketArgumentList, '(', 2);
TestExpr([0,0,0], TFpPascalExpressionPartIdentifer, 'f', 0);
TestExpr([0,0,1], TFpPascalExpressionPartIdentifer, 'a', 0);
TestExpr([0,1], TFpPascalExpressionPartIdentifer, 'b', 0);
finally
CurrentTestExprObj.Free;
end;

View File

@ -205,10 +205,7 @@ const
var
IdentName: String;
Loc: TDBGPtr;
Ident: TDbgSymbol;
PasExpr: TFpGDBMIPascalExpression;
TypeIdent: TDbgDwarfTypeIdentifier;
begin
Result := inherited IndexOf(AThreadId, AStackFrame, ARequest);
@ -383,10 +380,6 @@ end;
function TFpGDBMIDebugger.RequestCommand(const ACommand: TDBGCommand;
const AParams: array of const): Boolean;
var
Ident: TDbgSymbol;
Loc: TDBGPtr;
CurThread, CurStack: Integer;
begin
if HasDwarf and (ACommand = dcEvaluate) then begin
// String(AParams[0].VAnsiString)