fpdebug: refactor

git-svn-id: trunk@43075 -
This commit is contained in:
martin 2013-10-04 18:58:17 +00:00
parent 30c8902002
commit 1c207fad5d

View File

@ -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 }