mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-07 20:56:31 +02:00
fpdebug: refactor
git-svn-id: trunk@43075 -
This commit is contained in:
parent
30c8902002
commit
1c207fad5d
@ -181,7 +181,7 @@ type
|
|||||||
"Next Sibling" is either CurrentIndex + 1 (no children), or can be found via
|
"Next Sibling" is either CurrentIndex + 1 (no children), or can be found via
|
||||||
the first childs link.
|
the first childs link.
|
||||||
A Sibling has the same Parent. (If there is no child, and CurrentIndex+1 has
|
A Sibling has the same Parent. (If there is no child, and CurrentIndex+1 has
|
||||||
a diff parent, then there is no Nexn)
|
a diff parent, then there is no Next)
|
||||||
|
|
||||||
TopLevel Scopes have Link=-1
|
TopLevel Scopes have Link=-1
|
||||||
*)
|
*)
|
||||||
@ -204,14 +204,13 @@ type
|
|||||||
private
|
private
|
||||||
FScopeList: PDwarfScopeList;
|
FScopeList: PDwarfScopeList;
|
||||||
FIndex: Integer;
|
FIndex: Integer;
|
||||||
FIsValid: Boolean;
|
|
||||||
//FData: PDwarfScopeInfoRec;
|
|
||||||
function GetChild: TDwarfScopeInfo; inline;
|
function GetChild: TDwarfScopeInfo; inline;
|
||||||
function GetChildIndex: Integer; inline;
|
function GetChildIndex: Integer; inline;
|
||||||
function GetEntry: Pointer; inline;
|
function GetEntry: Pointer; inline;
|
||||||
function GetNext: TDwarfScopeInfo; inline;
|
function GetNext: TDwarfScopeInfo; inline;
|
||||||
function GetNextIndex: Integer; inline;
|
function GetNextIndex: Integer; inline;
|
||||||
function GetParent: TDwarfScopeInfo; inline;
|
function GetParent: TDwarfScopeInfo; inline;
|
||||||
|
function GetParentIndex: Integer;
|
||||||
procedure SetIndex(AIndex: Integer);
|
procedure SetIndex(AIndex: Integer);
|
||||||
function CreateScopeForEntry(AEntry: Pointer; ALink: Integer): Integer;
|
function CreateScopeForEntry(AEntry: Pointer; ALink: Integer): Integer;
|
||||||
public
|
public
|
||||||
@ -219,7 +218,7 @@ type
|
|||||||
function CreateNextForEntry(AEntry: Pointer): Integer;
|
function CreateNextForEntry(AEntry: Pointer): Integer;
|
||||||
function CreateChildForEntry(AEntry: Pointer): Integer;
|
function CreateChildForEntry(AEntry: Pointer): Integer;
|
||||||
|
|
||||||
property IsValid: Boolean read FIsValid;
|
function IsValid: Boolean; inline;
|
||||||
property Index: Integer read FIndex write SetIndex;
|
property Index: Integer read FIndex write SetIndex;
|
||||||
property Entry: Pointer read GetEntry;
|
property Entry: Pointer read GetEntry;
|
||||||
|
|
||||||
@ -232,6 +231,7 @@ type
|
|||||||
procedure GoChild; inline;
|
procedure GoChild; inline;
|
||||||
|
|
||||||
property Parent: TDwarfScopeInfo read GetParent;
|
property Parent: TDwarfScopeInfo read GetParent;
|
||||||
|
property ParentIndex: Integer read GetParentIndex;
|
||||||
property Next: TDwarfScopeInfo read GetNext;
|
property Next: TDwarfScopeInfo read GetNext;
|
||||||
property NextIndex: Integer read GetNextIndex;
|
property NextIndex: Integer read GetNextIndex;
|
||||||
property Child: TDwarfScopeInfo read GetChild;
|
property Child: TDwarfScopeInfo read GetChild;
|
||||||
@ -293,7 +293,8 @@ type
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
TDwarfLocateEntryFlag = (
|
TDwarfLocateEntryFlag = (
|
||||||
lefCreateAttribList,
|
lefCreateAttribList, // Build a list of pointers into the debug_info for the found entry.
|
||||||
|
// For each Abbreviation-attribute, point to the data in the Entry
|
||||||
lefContinuable, // forces the located scope or the startscope to be contuniable
|
lefContinuable, // forces the located scope or the startscope to be contuniable
|
||||||
// meaning that tree traversion can continue from a scope
|
// meaning that tree traversion can continue from a scope
|
||||||
lefSearchChild,
|
lefSearchChild,
|
||||||
@ -372,7 +373,9 @@ type
|
|||||||
procedure BuildLineInfo(AAddressInfo: PDwarfAddressInfo; ADoAll: Boolean);
|
procedure BuildLineInfo(AAddressInfo: PDwarfAddressInfo; ADoAll: Boolean);
|
||||||
function MakeAddress(AData: Pointer): QWord;
|
function MakeAddress(AData: Pointer): QWord;
|
||||||
protected
|
protected
|
||||||
function LocateEntry(ATag: Cardinal; AStartScope: TDwarfScopeInfo; AFlags: TDwarfLocateEntryFlags; out AResultScope: TDwarfScopeInfo; out AList: TPointerDynArray): Boolean;
|
function LocateEntry(ATag: Cardinal; AStartScope: TDwarfScopeInfo;
|
||||||
|
AFlags: TDwarfLocateEntryFlags;
|
||||||
|
out AResultScope: TDwarfScopeInfo; out AList: TPointerDynArray): Boolean;
|
||||||
function LocateAttribute(AEntry: Pointer; AAttribute: Cardinal; const AList: TPointerDynArray; out AAttribPtr: Pointer; out AForm: Cardinal): Boolean;
|
function LocateAttribute(AEntry: Pointer; AAttribute: Cardinal; const AList: TPointerDynArray; out AAttribPtr: Pointer; out AForm: Cardinal): Boolean;
|
||||||
|
|
||||||
function ReadValue(AAttribute: Pointer; AForm: Cardinal; out AValue: Integer): Boolean;
|
function ReadValue(AAttribute: Pointer; AForm: Cardinal; out AValue: Integer): Boolean;
|
||||||
@ -567,6 +570,58 @@ begin
|
|||||||
then Result := Result or (Int64(-1) shl n);
|
then Result := Result or (Int64(-1) shl n);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function SkipEntryDataForForm(var AEntryData: Pointer; AForm: Cardinal; AddrSize: Byte): Boolean; inline;
|
||||||
|
var
|
||||||
|
UValue: QWord;
|
||||||
|
begin
|
||||||
|
Result := True;
|
||||||
|
case AForm of
|
||||||
|
DW_FORM_addr : Inc(AEntryData, AddrSize);
|
||||||
|
DW_FORM_block : begin
|
||||||
|
UValue := ULEB128toOrdinal(AEntryData);
|
||||||
|
Inc(AEntryData, UValue);
|
||||||
|
end;
|
||||||
|
DW_FORM_block1 : Inc(AEntryData, PByte(AEntryData)^ + 1);
|
||||||
|
DW_FORM_block2 : Inc(AEntryData, PWord(AEntryData)^ + 2);
|
||||||
|
DW_FORM_block4 : Inc(AEntryData, PLongWord(AEntryData)^ + 4);
|
||||||
|
DW_FORM_data1 : Inc(AEntryData, 1);
|
||||||
|
DW_FORM_data2 : Inc(AEntryData, 2);
|
||||||
|
DW_FORM_data4 : Inc(AEntryData, 4);
|
||||||
|
DW_FORM_data8 : Inc(AEntryData, 8);
|
||||||
|
DW_FORM_sdata : begin
|
||||||
|
while (PByte(AEntryData)^ and $80) <> 0 do Inc(AEntryData);
|
||||||
|
Inc(AEntryData);
|
||||||
|
end;
|
||||||
|
DW_FORM_udata : begin
|
||||||
|
while (PByte(AEntryData)^ and $80) <> 0 do Inc(AEntryData);
|
||||||
|
Inc(AEntryData);
|
||||||
|
end;
|
||||||
|
DW_FORM_flag : Inc(AEntryData, 1);
|
||||||
|
DW_FORM_ref1 : Inc(AEntryData, 1);
|
||||||
|
DW_FORM_ref2 : Inc(AEntryData, 2);
|
||||||
|
DW_FORM_ref4 : Inc(AEntryData, 4);
|
||||||
|
DW_FORM_ref8 : Inc(AEntryData, 8);
|
||||||
|
DW_FORM_ref_udata: begin
|
||||||
|
while (PByte(AEntryData)^ and $80) <> 0 do Inc(AEntryData);
|
||||||
|
Inc(AEntryData);
|
||||||
|
end;
|
||||||
|
DW_FORM_ref_addr : Inc(AEntryData, AddrSize);
|
||||||
|
DW_FORM_string : begin
|
||||||
|
while PByte(AEntryData)^ <> 0 do Inc(AEntryData);
|
||||||
|
Inc(AEntryData);
|
||||||
|
end;
|
||||||
|
DW_FORM_strp : Inc(AEntryData, AddrSize);
|
||||||
|
DW_FORM_indirect : begin
|
||||||
|
while AForm = DW_FORM_indirect do AForm := ULEB128toOrdinal(AEntryData);
|
||||||
|
Result := SkipEntryDataForForm(AEntryData, AForm, AddrSize);
|
||||||
|
end;
|
||||||
|
else begin
|
||||||
|
DebugLn(FPDBG_DWARF_WARNINGS, ['Error: Unknown Form: ', AForm]);
|
||||||
|
Result := False;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
end;
|
||||||
|
|
||||||
function DwarfTagToString(AValue: Integer): String;
|
function DwarfTagToString(AValue: Integer): String;
|
||||||
begin
|
begin
|
||||||
@ -1451,6 +1506,11 @@ end;
|
|||||||
|
|
||||||
{ TDwarfScopeInfo }
|
{ TDwarfScopeInfo }
|
||||||
|
|
||||||
|
function TDwarfScopeInfo.IsValid: Boolean;
|
||||||
|
begin
|
||||||
|
Result := FIndex >= 0;
|
||||||
|
end;
|
||||||
|
|
||||||
function TDwarfScopeInfo.GetNext: TDwarfScopeInfo;
|
function TDwarfScopeInfo.GetNext: TDwarfScopeInfo;
|
||||||
begin
|
begin
|
||||||
Result.Init(FScopeList);
|
Result.Init(FScopeList);
|
||||||
@ -1517,10 +1577,22 @@ begin
|
|||||||
Result.Index := l;
|
Result.Index := l;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TDwarfScopeInfo.GetParentIndex: Integer;
|
||||||
|
begin
|
||||||
|
Result := -1;
|
||||||
|
if not IsValid then exit;
|
||||||
|
Result := FScopeList^.List[FIndex].Link; // GetParent (or -1 for toplevel)
|
||||||
|
assert(Result <= FScopeList^.HighestKnown);
|
||||||
|
if Result > Index then
|
||||||
|
Result := Index - 1; // This is a first child, make l = parent
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TDwarfScopeInfo.SetIndex(AIndex: Integer);
|
procedure TDwarfScopeInfo.SetIndex(AIndex: Integer);
|
||||||
begin
|
begin
|
||||||
FIndex := AIndex;
|
if (AIndex >= 0) and (AIndex <= FScopeList^.HighestKnown) then
|
||||||
FIsValid := (FIndex >= 0) and (FIndex <= FScopeList^.HighestKnown);
|
FIndex := AIndex
|
||||||
|
else
|
||||||
|
FIndex := -1;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TDwarfScopeInfo.CreateScopeForEntry(AEntry: Pointer; ALink: Integer): Integer;
|
function TDwarfScopeInfo.CreateScopeForEntry(AEntry: Pointer; ALink: Integer): Integer;
|
||||||
@ -2228,8 +2300,8 @@ begin
|
|||||||
Scope := ResultScope;
|
Scope := ResultScope;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
while (not Scope.HasNext) and (Scope.HasParent) do Scope := Scope.Parent;
|
while (not Scope.HasNext) and (Scope.HasParent) do Scope.GoParent;
|
||||||
Scope := Scope.Next;
|
Scope.GoNext;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
FAddressMapBuild := True;
|
FAddressMapBuild := True;
|
||||||
@ -2478,7 +2550,8 @@ begin
|
|||||||
Result := Map^.GetAddressForLine(ALine);
|
Result := Map^.GetAddressForLine(ALine);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TDwarfCompilationUnit.LocateAttribute(AEntry: Pointer; AAttribute: Cardinal; const AList: TPointerDynArray; out AAttribPtr: Pointer; out AForm: Cardinal): Boolean;
|
function TDwarfCompilationUnit.LocateAttribute(AEntry: Pointer; AAttribute: Cardinal;
|
||||||
|
const AList: TPointerDynArray; out AAttribPtr: Pointer; out AForm: Cardinal): Boolean;
|
||||||
var
|
var
|
||||||
Abbrev: Cardinal;
|
Abbrev: Cardinal;
|
||||||
Def: TDwarfAbbrev;
|
Def: TDwarfAbbrev;
|
||||||
@ -2517,103 +2590,26 @@ end;
|
|||||||
// AResultScope: the located scope info
|
// AResultScope: the located scope info
|
||||||
// AList: an array where pointers to all attribs are stored
|
// AList: an array where pointers to all attribs are stored
|
||||||
//----------------------------------------
|
//----------------------------------------
|
||||||
function TDwarfCompilationUnit.LocateEntry(ATag: Cardinal; AStartScope: TDwarfScopeInfo; AFlags: TDwarfLocateEntryFlags; out AResultScope: TDwarfScopeInfo; out AList: TPointerDynArray): Boolean;
|
function TDwarfCompilationUnit.LocateEntry(ATag: Cardinal; AStartScope: TDwarfScopeInfo;
|
||||||
procedure SkipLEB(var p: Pointer);
|
AFlags: TDwarfLocateEntryFlags; out AResultScope: TDwarfScopeInfo; out
|
||||||
begin
|
AList: TPointerDynArray): Boolean;
|
||||||
while (PByte(p)^ and $80) <> 0 do Inc(p);
|
|
||||||
Inc(p);
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure SkipStr(var p: Pointer);
|
|
||||||
begin
|
|
||||||
while PByte(p)^ <> 0 do Inc(p);
|
|
||||||
Inc(p);
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure ParseAttribs(const ADef: TDwarfAbbrev; ABuildList: Boolean; var p: Pointer);
|
procedure ParseAttribs(const ADef: TDwarfAbbrev; ABuildList: Boolean; var p: Pointer);
|
||||||
var
|
var
|
||||||
idx: Integer;
|
idx: Integer;
|
||||||
Form: Cardinal;
|
|
||||||
UValue: QWord;
|
|
||||||
ADefs: PDwarfAbbrevEntry;
|
ADefs: PDwarfAbbrevEntry;
|
||||||
|
AdrSize: Byte;
|
||||||
begin
|
begin
|
||||||
ADefs := FAbbrevList.EntryPointer[0];
|
ADefs := FAbbrevList.EntryPointer[ADef.Index];
|
||||||
for idx := ADef.Index to ADef.Index + ADef.Count - 1 do
|
AdrSize := FAddressSize;
|
||||||
|
for idx := 0 to ADef.Count - 1 do
|
||||||
begin
|
begin
|
||||||
if ABuildList
|
if ABuildList
|
||||||
then AList[idx - ADef.Index] := p;
|
then AList[idx] := p;
|
||||||
|
|
||||||
Form := ADefs[idx].Form;
|
if not SkipEntryDataForForm(p, ADefs^.Form, AdrSize) then
|
||||||
while Form = DW_FORM_indirect do Form := ULEB128toOrdinal(p);
|
|
||||||
|
|
||||||
case Form of
|
|
||||||
DW_FORM_addr : begin
|
|
||||||
Inc(p, FAddressSize);
|
|
||||||
end;
|
|
||||||
DW_FORM_block : begin
|
|
||||||
UValue := ULEB128toOrdinal(p);
|
|
||||||
Inc(p, UValue);
|
|
||||||
end;
|
|
||||||
DW_FORM_block1 : begin
|
|
||||||
Inc(p, PByte(p)^ + 1);
|
|
||||||
end;
|
|
||||||
DW_FORM_block2 : begin
|
|
||||||
Inc(p, PWord(p)^ + 2);
|
|
||||||
end;
|
|
||||||
DW_FORM_block4 : begin
|
|
||||||
Inc(p, PLongWord(p)^ + 4);
|
|
||||||
end;
|
|
||||||
DW_FORM_data1 : begin
|
|
||||||
Inc(p, 1);
|
|
||||||
end;
|
|
||||||
DW_FORM_data2 : begin
|
|
||||||
Inc(p, 2);
|
|
||||||
end;
|
|
||||||
DW_FORM_data4 : begin
|
|
||||||
Inc(p, 4);
|
|
||||||
end;
|
|
||||||
DW_FORM_data8 : begin
|
|
||||||
Inc(p, 8);
|
|
||||||
end;
|
|
||||||
DW_FORM_sdata : begin
|
|
||||||
SkipLEB(p);
|
|
||||||
end;
|
|
||||||
DW_FORM_udata : begin
|
|
||||||
SkipLEB(p);
|
|
||||||
end;
|
|
||||||
DW_FORM_flag : begin
|
|
||||||
Inc(p, 1);
|
|
||||||
end;
|
|
||||||
DW_FORM_ref1 : begin
|
|
||||||
Inc(p, 1);
|
|
||||||
end;
|
|
||||||
DW_FORM_ref2 : begin
|
|
||||||
Inc(p, 2);
|
|
||||||
end;
|
|
||||||
DW_FORM_ref4 : begin
|
|
||||||
Inc(p, 4);
|
|
||||||
end;
|
|
||||||
DW_FORM_ref8 : begin
|
|
||||||
Inc(p, 8);
|
|
||||||
end;
|
|
||||||
DW_FORM_ref_udata: begin
|
|
||||||
SkipLEB(p);
|
|
||||||
end;
|
|
||||||
DW_FORM_ref_addr : begin
|
|
||||||
Inc(p, FAddressSize);
|
|
||||||
end;
|
|
||||||
DW_FORM_string : begin
|
|
||||||
SkipStr(p);
|
|
||||||
end;
|
|
||||||
DW_FORM_strp : begin
|
|
||||||
Inc(p, FAddressSize);
|
|
||||||
end;
|
|
||||||
DW_FORM_indirect : begin
|
|
||||||
end;
|
|
||||||
else
|
|
||||||
DebugLn(FPDBG_DWARF_WARNINGS, ['Error: Unknown Form: ', Form]);
|
|
||||||
Break;
|
Break;
|
||||||
end;
|
inc(ADefs);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -2643,7 +2639,7 @@ var
|
|||||||
Level: Integer;
|
Level: Integer;
|
||||||
MaxData: Pointer;
|
MaxData: Pointer;
|
||||||
p: Pointer;
|
p: Pointer;
|
||||||
Scope, Scope2: TDwarfScopeInfo;
|
Scope: TDwarfScopeInfo;
|
||||||
BuildList: Boolean; // set once if we need to fill the list
|
BuildList: Boolean; // set once if we need to fill the list
|
||||||
Searching: Boolean; // set as long as we need searching for a tag.
|
Searching: Boolean; // set as long as we need searching for a tag.
|
||||||
p2: Pointer;
|
p2: Pointer;
|
||||||
@ -2675,10 +2671,10 @@ begin
|
|||||||
// p is now the entry of the next of the startparent
|
// p is now the entry of the next of the startparent
|
||||||
// let's see if we need to set it
|
// let's see if we need to set it
|
||||||
if not (lefContinuable in AFlags) then Exit;
|
if not (lefContinuable in AFlags) then Exit;
|
||||||
Scope2 := AStartScope.Parent;
|
Scope.Index := AStartScope.ParentIndex;
|
||||||
if not Scope2.IsValid then Exit;
|
//if not Scope2.IsValid then Exit;
|
||||||
if Scope2.HasNext then Exit;
|
if Scope.HasNext then Exit;
|
||||||
Scope2.CreateNextForEntry(p);
|
Scope.CreateNextForEntry(p);
|
||||||
Exit;
|
Exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -3018,7 +3014,8 @@ begin
|
|||||||
Size := 0;
|
Size := 0;
|
||||||
end;
|
end;
|
||||||
SetLength(AValue, Size);
|
SetLength(AValue, Size);
|
||||||
Move(AAttribute^, AValue[0], Size);
|
if Size > 0 then
|
||||||
|
Move(AAttribute^, AValue[0], Size);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TDwarfVerboseCompilationUnit }
|
{ TDwarfVerboseCompilationUnit }
|
||||||
|
Loading…
Reference in New Issue
Block a user