mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-09-15 10:19:23 +02:00
FPDebug: refactor
git-svn-id: trunk@43406 -
This commit is contained in:
parent
987732d77c
commit
e8550987a1
@ -42,7 +42,8 @@ interface
|
|||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, Types, SysUtils, FpDbgInfo, FpDbgDwarfConst, Maps, Math,
|
Classes, Types, SysUtils, FpDbgInfo, FpDbgDwarfConst, Maps, Math,
|
||||||
FpDbgLoader, FpImgReaderBase, LazLoggerBase, LazClasses, LazFileUtils, contnrs;
|
FpDbgLoader, FpImgReaderBase, LazLoggerBase, // LazLoggerDummy,
|
||||||
|
LazClasses, LazFileUtils, contnrs;
|
||||||
|
|
||||||
type
|
type
|
||||||
// compilation unit header
|
// compilation unit header
|
||||||
@ -100,8 +101,6 @@ const
|
|||||||
DWARF_HEADER64_SIGNATURE = $FFFFFFFF;
|
DWARF_HEADER64_SIGNATURE = $FFFFFFFF;
|
||||||
|
|
||||||
type
|
type
|
||||||
TPointerDynArray = array of Pointer;
|
|
||||||
|
|
||||||
TDbgDwarf = class;
|
TDbgDwarf = class;
|
||||||
TDwarfCompilationUnit = class;
|
TDwarfCompilationUnit = class;
|
||||||
|
|
||||||
@ -128,6 +127,13 @@ type
|
|||||||
end;
|
end;
|
||||||
PLeb128TableEntry = ^TLeb128TableEntry;
|
PLeb128TableEntry = ^TLeb128TableEntry;
|
||||||
|
|
||||||
|
TPointerDynArray = array of Pointer;
|
||||||
|
TAttribPointerList = record
|
||||||
|
List: TPointerDynArray;
|
||||||
|
Abbrev: TDwarfAbbrev;
|
||||||
|
EvalCount: Integer;
|
||||||
|
end;
|
||||||
|
|
||||||
{ TLEB128PreFixTree }
|
{ TLEB128PreFixTree }
|
||||||
|
|
||||||
TLEB128PreFixTree = class
|
TLEB128PreFixTree = class
|
||||||
@ -347,8 +353,6 @@ type
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
TDwarfLocateEntryFlag = (
|
TDwarfLocateEntryFlag = (
|
||||||
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,
|
||||||
@ -433,9 +437,11 @@ type
|
|||||||
procedure ScanAllEntries;
|
procedure ScanAllEntries;
|
||||||
function LocateEntry(ATag: Cardinal; AStartScope: TDwarfScopeInfo;
|
function LocateEntry(ATag: Cardinal; AStartScope: TDwarfScopeInfo;
|
||||||
AFlags: TDwarfLocateEntryFlags;
|
AFlags: TDwarfLocateEntryFlags;
|
||||||
out AResultScope: TDwarfScopeInfo; out AList: TPointerDynArray): Boolean;
|
out AResultScope: TDwarfScopeInfo): Boolean;
|
||||||
function LocateAttribute(AEntry: Pointer; AAttribute: Cardinal; const AList: TPointerDynArray; out AAttribPtr: Pointer; out AForm: Cardinal): Boolean;
|
function LocateAttribute(AEntry: Pointer; AAttribute: Cardinal; var AList: TAttribPointerList;
|
||||||
function LocateAttribute(AEntry: Pointer; AAttribute: Cardinal; out AAttribPtr: Pointer; out AForm: Cardinal): Boolean;
|
out AAttribPtr: Pointer; out AForm: Cardinal): Boolean;
|
||||||
|
function LocateAttribute(AEntry: Pointer; AAttribute: Cardinal;
|
||||||
|
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;
|
||||||
function ReadValue(AAttribute: Pointer; AForm: Cardinal; out AValue: Int64): Boolean;
|
function ReadValue(AAttribute: Pointer; AForm: Cardinal; out AValue: Int64): Boolean;
|
||||||
@ -4173,6 +4179,7 @@ begin
|
|||||||
if AAddressInfo = nil then Exit;
|
if AAddressInfo = nil then Exit;
|
||||||
if AAddressInfo^.StateMachine <> nil then Exit;
|
if AAddressInfo^.StateMachine <> nil then Exit;
|
||||||
end;
|
end;
|
||||||
|
if FLineInfo.StateMachine = nil then Exit;
|
||||||
if FLineInfo.StateMachine.Ended then Exit;
|
if FLineInfo.StateMachine.Ended then Exit;
|
||||||
|
|
||||||
BuildAddressMap;
|
BuildAddressMap;
|
||||||
@ -4247,12 +4254,13 @@ end;
|
|||||||
|
|
||||||
procedure TDwarfCompilationUnit.BuildAddressMap;
|
procedure TDwarfCompilationUnit.BuildAddressMap;
|
||||||
var
|
var
|
||||||
AttribList: TPointerDynArray;
|
AttribList: TAttribPointerList;
|
||||||
Attrib: Pointer;
|
Attrib: Pointer;
|
||||||
Form: Cardinal;
|
Form: Cardinal;
|
||||||
Info: TDwarfAddressInfo;
|
Info: TDwarfAddressInfo;
|
||||||
Scope, ResultScope: TDwarfScopeInfo;
|
Scope, ResultScope: TDwarfScopeInfo;
|
||||||
i: Integer;
|
i: Integer;
|
||||||
|
xxAttribList: TPointerDynArray; // xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||||
begin
|
begin
|
||||||
if FAddressMapBuild then Exit;
|
if FAddressMapBuild then Exit;
|
||||||
|
|
||||||
@ -4261,8 +4269,10 @@ begin
|
|||||||
Scope := FScope;
|
Scope := FScope;
|
||||||
while Scope.IsValid do
|
while Scope.IsValid do
|
||||||
begin
|
begin
|
||||||
if LocateEntry(DW_TAG_subprogram, Scope, [lefCreateAttribList, lefContinuable, lefSearchChild], ResultScope, AttribList)
|
if LocateEntry(DW_TAG_subprogram, Scope, [lefContinuable, lefSearchChild],
|
||||||
|
ResultScope)
|
||||||
then begin
|
then begin
|
||||||
|
AttribList.EvalCount := 0;
|
||||||
Info.ScopeIndex := ResultScope.Index;
|
Info.ScopeIndex := ResultScope.Index;
|
||||||
Info.ScopeList := ResultScope.FScopeList;
|
Info.ScopeList := ResultScope.FScopeList;
|
||||||
if LocateAttribute(ResultScope.Entry, DW_AT_low_pc, AttribList, Attrib, Form)
|
if LocateAttribute(ResultScope.Entry, DW_AT_low_pc, AttribList, Attrib, Form)
|
||||||
@ -4391,11 +4401,12 @@ constructor TDwarfCompilationUnit.Create(AOwner: TDbgDwarf; ADataOffset: QWord;
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
var
|
var
|
||||||
AttribList: TPointerDynArray;
|
AttribList: TAttribPointerList;
|
||||||
Attrib: Pointer;
|
Attrib: Pointer;
|
||||||
Form: Cardinal;
|
Form: Cardinal;
|
||||||
StatementListOffs, Offs: QWord;
|
StatementListOffs, Offs: QWord;
|
||||||
Scope: TDwarfScopeInfo;
|
Scope: TDwarfScopeInfo;
|
||||||
|
xxAttribList: TPointerDynArray; // xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||||
begin
|
begin
|
||||||
inherited Create;
|
inherited Create;
|
||||||
FOwner := AOwner;
|
FOwner := AOwner;
|
||||||
@ -4434,13 +4445,14 @@ begin
|
|||||||
FScope.Init(@FScopeList);
|
FScope.Init(@FScopeList);
|
||||||
FScope.Index := 0;
|
FScope.Index := 0;
|
||||||
// retrieve some info about this unit
|
// retrieve some info about this unit
|
||||||
if not LocateEntry(DW_TAG_compile_unit, FScope, [lefCreateAttribList, lefSearchChild], Scope, AttribList)
|
if not LocateEntry(DW_TAG_compile_unit, FScope, [lefSearchChild], Scope)
|
||||||
then begin
|
then begin
|
||||||
DebugLn(FPDBG_DWARF_WARNINGS, ['WARNING compilation unit has no compile_unit tag']);
|
DebugLn(FPDBG_DWARF_WARNINGS, ['WARNING compilation unit has no compile_unit tag']);
|
||||||
Exit;
|
Exit;
|
||||||
end;
|
end;
|
||||||
FValid := True;
|
FValid := True;
|
||||||
|
|
||||||
|
AttribList.EvalCount := 0;
|
||||||
if LocateAttribute(Scope.Entry, DW_AT_name, AttribList, Attrib, Form)
|
if LocateAttribute(Scope.Entry, DW_AT_name, AttribList, Attrib, Form)
|
||||||
then ReadValue(Attrib, Form, FFileName);
|
then ReadValue(Attrib, Form, FFileName);
|
||||||
|
|
||||||
@ -4549,34 +4561,70 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
function TDwarfCompilationUnit.LocateAttribute(AEntry: Pointer; AAttribute: Cardinal;
|
function TDwarfCompilationUnit.LocateAttribute(AEntry: Pointer; AAttribute: Cardinal;
|
||||||
const AList: TPointerDynArray; out AAttribPtr: Pointer; out AForm: Cardinal): Boolean;
|
var AList: TAttribPointerList; out AAttribPtr: Pointer; out AForm: Cardinal): Boolean;
|
||||||
var
|
var
|
||||||
Abbrev: Cardinal;
|
Abbrev: Cardinal;
|
||||||
Def: TDwarfAbbrev;
|
i, EvalCnt, AbrIdx, AbrCnt: Integer;
|
||||||
n: Integer;
|
|
||||||
ADefs: PDwarfAbbrevEntry;
|
ADefs: PDwarfAbbrevEntry;
|
||||||
begin
|
begin
|
||||||
if not GetDefinition(AEntry, Def)
|
Result := False;
|
||||||
then begin
|
if AList.EvalCount < 0 then
|
||||||
//???
|
exit;
|
||||||
Abbrev := ULEB128toOrdinal(AEntry);
|
|
||||||
DebugLn(FPDBG_DWARF_WARNINGS, ['Error: Abbrev not found: ', Abbrev]);
|
if AList.EvalCount = 0 then begin
|
||||||
Result := False;
|
if not GetDefinition(AEntry, AList.Abbrev)
|
||||||
Exit;
|
then begin //???
|
||||||
|
Abbrev := ULEB128toOrdinal(AEntry);
|
||||||
|
DebugLn(FPDBG_DWARF_WARNINGS, ['Error: Abbrev not found: ', Abbrev]);
|
||||||
|
AList.EvalCount := -1;
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
AbrIdx := AList.Abbrev.count;
|
||||||
|
if AbrIdx = 0 then begin
|
||||||
|
AList.EvalCount := -1;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
SetLength(AList.List, AbrIdx);
|
||||||
|
ULEB128toOrdinal(AEntry);
|
||||||
|
AList.List[0] := AEntry;
|
||||||
|
AList.EvalCount := 1;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
ADefs := FAbbrevList.EntryPointer[0];
|
ADefs := FAbbrevList.EntryPointer[0];
|
||||||
for n := Def.Index to Def.Index + Def.Count - 1 do
|
AbrIdx := AList.Abbrev.Index;
|
||||||
begin
|
AbrCnt := AList.Abbrev.Count - 1;
|
||||||
if ADefs[n].Attribute = AAttribute
|
EvalCnt := AList.EvalCount - 1;
|
||||||
|
i := 0;
|
||||||
|
|
||||||
|
while true do begin
|
||||||
|
if ADefs[AbrIdx].Attribute = AAttribute
|
||||||
then begin
|
then begin
|
||||||
Result := True;
|
Result := True;
|
||||||
AAttribPtr := AList[n - Def.Index];
|
AAttribPtr := AList.List[i];
|
||||||
AForm := ADefs[n].Form;
|
AForm := ADefs[AbrIdx].Form;
|
||||||
Exit;
|
break;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
if i = AbrCnt then
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (i < EvalCnt) then begin
|
||||||
|
inc(i);
|
||||||
|
inc(AbrIdx);
|
||||||
|
Continue;
|
||||||
|
end;
|
||||||
|
|
||||||
|
AEntry := AList.List[i];
|
||||||
|
if not SkipEntryDataForForm(AEntry, ADefs[AbrIdx].Form, FAddressSize) then
|
||||||
|
break;
|
||||||
|
AList.List[i+1] := AEntry;
|
||||||
|
inc(i);
|
||||||
|
inc(AbrIdx);
|
||||||
end;
|
end;
|
||||||
Result := False;
|
|
||||||
|
if i {+ 1} > EvalCnt {+ 1} then
|
||||||
|
AList.EvalCount := i + 1
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TDwarfCompilationUnit.LocateAttribute(AEntry: Pointer; AAttribute: Cardinal; out
|
function TDwarfCompilationUnit.LocateAttribute(AEntry: Pointer; AAttribute: Cardinal; out
|
||||||
@ -4618,16 +4666,13 @@ end;
|
|||||||
// Params
|
// Params
|
||||||
// ATag: a tag to search for
|
// ATag: a tag to search for
|
||||||
// AStartScope: a startpoint in the data
|
// AStartScope: a startpoint in the data
|
||||||
// ABuildList: if set, build the attrib list
|
|
||||||
// ACurrentOnly: if set, process only current entry
|
// ACurrentOnly: if set, process only current entry
|
||||||
// AResultScope: the located scope info
|
// AResultScope: the located scope info
|
||||||
// AList: an array where pointers to all attribs are stored
|
|
||||||
//----------------------------------------
|
//----------------------------------------
|
||||||
function TDwarfCompilationUnit.LocateEntry(ATag: Cardinal; AStartScope: TDwarfScopeInfo;
|
function TDwarfCompilationUnit.LocateEntry(ATag: Cardinal; AStartScope: TDwarfScopeInfo;
|
||||||
AFlags: TDwarfLocateEntryFlags; out AResultScope: TDwarfScopeInfo; out
|
AFlags: TDwarfLocateEntryFlags; out AResultScope: TDwarfScopeInfo): Boolean;
|
||||||
AList: TPointerDynArray): Boolean;
|
|
||||||
|
|
||||||
procedure ParseAttribs(const ADef: TDwarfAbbrev; ABuildList: Boolean; var p: Pointer);
|
procedure ParseAttribs(const ADef: TDwarfAbbrev; var p: Pointer);
|
||||||
var
|
var
|
||||||
idx: Integer;
|
idx: Integer;
|
||||||
ADefs: PDwarfAbbrevEntry;
|
ADefs: PDwarfAbbrevEntry;
|
||||||
@ -4637,9 +4682,6 @@ function TDwarfCompilationUnit.LocateEntry(ATag: Cardinal; AStartScope: TDwarfSc
|
|||||||
AdrSize := FAddressSize;
|
AdrSize := FAddressSize;
|
||||||
for idx := 0 to ADef.Count - 1 do
|
for idx := 0 to ADef.Count - 1 do
|
||||||
begin
|
begin
|
||||||
if ABuildList
|
|
||||||
then AList[idx] := p;
|
|
||||||
|
|
||||||
if not SkipEntryDataForForm(p, ADefs^.Form, AdrSize) then
|
if not SkipEntryDataForForm(p, ADefs^.Form, AdrSize) then
|
||||||
break;
|
break;
|
||||||
inc(ADefs);
|
inc(ADefs);
|
||||||
@ -4673,7 +4715,6 @@ var
|
|||||||
MaxData: Pointer;
|
MaxData: Pointer;
|
||||||
p: Pointer;
|
p: Pointer;
|
||||||
Scope: TDwarfScopeInfo;
|
Scope: TDwarfScopeInfo;
|
||||||
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;
|
||||||
ni: Integer;
|
ni: Integer;
|
||||||
@ -4681,7 +4722,6 @@ var
|
|||||||
begin
|
begin
|
||||||
Result := False;
|
Result := False;
|
||||||
if not AStartScope.IsValid then Exit;
|
if not AStartScope.IsValid then Exit;
|
||||||
BuildList := False;
|
|
||||||
Searching := True;
|
Searching := True;
|
||||||
Level := 0;
|
Level := 0;
|
||||||
MaxData := FInfoData + FLength;
|
MaxData := FInfoData + FLength;
|
||||||
@ -4738,16 +4778,8 @@ begin
|
|||||||
then begin
|
then begin
|
||||||
Searching := False;
|
Searching := False;
|
||||||
AResultScope := Scope;
|
AResultScope := Scope;
|
||||||
if lefCreateAttribList in AFlags
|
if not (lefContinuable in AFlags)
|
||||||
then begin
|
then Exit
|
||||||
SetLength(AList, Def.Count);
|
|
||||||
BuildList := True;
|
|
||||||
end
|
|
||||||
else begin
|
|
||||||
AList := nil;
|
|
||||||
if not (lefContinuable in AFlags)
|
|
||||||
then Exit
|
|
||||||
end;
|
|
||||||
end
|
end
|
||||||
else begin
|
else begin
|
||||||
if CanExit(False) then Exit;
|
if CanExit(False) then Exit;
|
||||||
@ -4756,36 +4788,31 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if not BuildList
|
// check if we can shortcut the searches
|
||||||
|
ni := Scope.ChildIndex;
|
||||||
|
if (ni >= 0) // (Scope.HasChild)
|
||||||
|
and ((lefSearchChild in AFlags) or (not Scope.HasNext))
|
||||||
then begin
|
then begin
|
||||||
// check if we can shortcut the searches
|
Inc(Level);
|
||||||
ni := Scope.ChildIndex;
|
Scope.Index := ni; // GoChild
|
||||||
if (ni >= 0) // (Scope.HasChild)
|
Continue;
|
||||||
and ((lefSearchChild in AFlags) or (not Scope.HasNext))
|
end;
|
||||||
|
|
||||||
|
ni := Scope.NextIndex;
|
||||||
|
if ni >= 0 // Scope.HasNext
|
||||||
|
then begin
|
||||||
|
// scope.Childvalid is true, otherwise we can not have a next.
|
||||||
|
// So no need to check
|
||||||
|
if lefSearchSibling in AFlags
|
||||||
then begin
|
then begin
|
||||||
Inc(Level);
|
Scope.Index := ni; // GoNext
|
||||||
Scope.Index := ni; // GoChild
|
|
||||||
Continue;
|
Continue;
|
||||||
end;
|
end;
|
||||||
|
if Level = 0 then Exit;
|
||||||
ni := Scope.NextIndex;
|
|
||||||
if ni >= 0 // Scope.HasNext
|
|
||||||
then begin
|
|
||||||
// scope.Childvalid is true, otherwise we can not have a next.
|
|
||||||
// So no need to check
|
|
||||||
if lefSearchSibling in AFlags
|
|
||||||
then begin
|
|
||||||
Scope.Index := ni; // GoNext
|
|
||||||
Continue;
|
|
||||||
end;
|
|
||||||
if Level = 0 then Exit;
|
|
||||||
end;
|
|
||||||
|
|
||||||
// bummer, we need to parse our attribs, if we want them or not
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
ParseAttribs(Def, BuildList, p);
|
// bummer, we need to parse our attribs, if we want them or not
|
||||||
BuildList := False;
|
ParseAttribs(Def, p);
|
||||||
|
|
||||||
// if we have a result or don't want to search we're done here
|
// if we have a result or don't want to search we're done here
|
||||||
if CanExit(Result) then Exit;
|
if CanExit(Result) then Exit;
|
||||||
@ -4860,7 +4887,7 @@ begin
|
|||||||
if FScannedToEnd then exit;
|
if FScannedToEnd then exit;
|
||||||
FScannedToEnd := True;
|
FScannedToEnd := True;
|
||||||
// scan to end
|
// scan to end
|
||||||
LocateEntry(0, FScope, [lefContinuable, lefSearchChild], ResultScope, AttribList);
|
LocateEntry(0, FScope, [lefContinuable, lefSearchChild], ResultScope);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TDwarfCompilationUnit.ReadValue(AAttribute: Pointer; AForm: Cardinal; out AValue: Cardinal): Boolean;
|
function TDwarfCompilationUnit.ReadValue(AAttribute: Pointer; AForm: Cardinal; out AValue: Cardinal): Boolean;
|
||||||
@ -5416,7 +5443,7 @@ var
|
|||||||
begin
|
begin
|
||||||
// Tag - should not exist. Load all scopes
|
// Tag - should not exist. Load all scopes
|
||||||
//FCU.LocateEntry(0, Scope, [lefContinuable, lefSearchChild, lefSearchSibling],
|
//FCU.LocateEntry(0, Scope, [lefContinuable, lefSearchChild, lefSearchSibling],
|
||||||
// ResultScope, AttribList);
|
// ResultScope);
|
||||||
|
|
||||||
Indent := AIndent;
|
Indent := AIndent;
|
||||||
Level := 0;
|
Level := 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user