mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-27 15:25:07 +02:00
FPDebug: scan all units
git-svn-id: trunk@43394 -
This commit is contained in:
parent
7745fdd2f0
commit
4c8b79e5fc
@ -42,7 +42,7 @@ interface
|
||||
|
||||
uses
|
||||
Classes, Types, SysUtils, FpDbgInfo, FpDbgDwarfConst, Maps, Math,
|
||||
FpDbgLoader, FpImgReaderBase, LazLoggerBase, LazClasses, contnrs;
|
||||
FpDbgLoader, FpImgReaderBase, LazLoggerBase, LazClasses, LazFileUtils, contnrs;
|
||||
|
||||
type
|
||||
// compilation unit header
|
||||
@ -390,6 +390,7 @@ type
|
||||
|
||||
FInfoData: Pointer;
|
||||
FFileName: String;
|
||||
FUnitName: String;
|
||||
FIdentifierCase: Integer;
|
||||
|
||||
FAbbrevList: TDwarfAbbrevList;
|
||||
@ -422,11 +423,14 @@ type
|
||||
FMaxPC: QWord; //
|
||||
FScope: TDwarfScopeInfo;
|
||||
FScopeList: TDwarfScopeList;
|
||||
FScannedToEnd: Boolean;
|
||||
|
||||
procedure BuildAddressMap;
|
||||
procedure BuildLineInfo(AAddressInfo: PDwarfAddressInfo; ADoAll: Boolean);
|
||||
function GetUnitName: String;
|
||||
function MakeAddress(AData: Pointer): QWord;
|
||||
protected
|
||||
procedure ScanAllEntries;
|
||||
function LocateEntry(ATag: Cardinal; AStartScope: TDwarfScopeInfo;
|
||||
AFlags: TDwarfLocateEntryFlags;
|
||||
out AResultScope: TDwarfScopeInfo; out AList: TPointerDynArray): Boolean;
|
||||
@ -450,6 +454,7 @@ type
|
||||
function GetLineAddressMap(const AFileName: String): PDWarfLineMap;
|
||||
function GetLineAddress(const AFileName: String; ALine: Cardinal): TDbgPtr;
|
||||
property FileName: String read FFileName;
|
||||
property UnitName: String read GetUnitName;
|
||||
property Valid: Boolean read FValid;
|
||||
end;
|
||||
|
||||
@ -866,6 +871,7 @@ type
|
||||
function LoadCompilationUnits: Integer;
|
||||
function PointerFromRVA(ARVA: QWord): Pointer;
|
||||
function PointerFromVA(ASection: TDwarfSection; AVA: QWord): Pointer;
|
||||
function CompilationUnitsCount: Integer;
|
||||
property CompilationUnits[AIndex: Integer]: TDwarfCompilationUnit read GetCompilationUnit;
|
||||
end;
|
||||
|
||||
@ -1392,9 +1398,9 @@ end;
|
||||
function TDbgDwarfInfoAddressContext.FindSymbol(const AName: String): TDbgSymbol;
|
||||
var
|
||||
SubRoutine: TDbgDwarfProcSymbol; // TDbgSymbol;
|
||||
CU: TDwarfCompilationUnit;
|
||||
CU, CU2: TDwarfCompilationUnit;
|
||||
//Scope,
|
||||
StartScopeIdx: Integer;
|
||||
StartScopeIdx, ExtVal, i: Integer;
|
||||
InfoEntry: TDwarfInformationEntry;
|
||||
s, InfoName: String;
|
||||
begin
|
||||
@ -1419,14 +1425,14 @@ begin
|
||||
if UpperCase(InfoName) = s then begin
|
||||
Result := TDbgDwarfIdentifier.CreateSubClass(AName, InfoEntry);
|
||||
DebugLn(FPDBG_DWARF_SEARCH, ['TDbgDwarf.FindIdentifier found ', dbgs(InfoEntry.FScope, CU), DbgSName(Result)]);
|
||||
break;
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
|
||||
if InfoEntry.GoNamedChildEx(AName) then begin
|
||||
Result := TDbgDwarfIdentifier.CreateSubClass(AName, InfoEntry);
|
||||
DebugLn(FPDBG_DWARF_SEARCH, ['TDbgDwarf.FindIdentifier found ', dbgs(InfoEntry.FScope, CU), DbgSName(Result)]);
|
||||
break;
|
||||
exit;
|
||||
end;
|
||||
|
||||
// Search parent(s)
|
||||
@ -1434,7 +1440,40 @@ begin
|
||||
InfoEntry.GoParent;
|
||||
end;
|
||||
|
||||
// other units
|
||||
// other units
|
||||
i := FDwarf.CompilationUnitsCount;
|
||||
while i > 0 do begin
|
||||
dec(i);
|
||||
CU2 := FDwarf.CompilationUnits[i];
|
||||
if CU2 = CU then
|
||||
continue;
|
||||
|
||||
InfoEntry.ReleaseReference;
|
||||
InfoEntry := TDwarfInformationEntry.Create(CU2, nil);
|
||||
InfoEntry.ScopeIndex := CU2.FirstScope.Index;
|
||||
|
||||
if not InfoEntry.Abbrev.tag = DW_TAG_compile_unit then
|
||||
continue;
|
||||
|
||||
if UpperCase(CU2.UnitName) = s then begin
|
||||
Result := TDbgDwarfIdentifier.CreateSubClass(AName, InfoEntry);
|
||||
DebugLn(FPDBG_DWARF_SEARCH, ['TDbgDwarf.FindIdentifier found unit ', dbgs(InfoEntry.FScope, CU2), DbgSName(Result)]);
|
||||
break;
|
||||
end;
|
||||
|
||||
CU2.ScanAllEntries;
|
||||
if InfoEntry.GoNamedChildEx(AName) then begin
|
||||
// only variables are marked, but types not / so we may need all top level
|
||||
Result := TDbgDwarfIdentifier.CreateSubClass(AName, InfoEntry);
|
||||
DebugLn(FPDBG_DWARF_SEARCH, ['TDbgDwarf.FindIdentifier found (other unit) ', dbgs(InfoEntry.FScope, CU2), DbgSName(Result)]);
|
||||
// DW_AT_visibility ?
|
||||
if InfoEntry.ReadValue(DW_AT_external, ExtVal) then
|
||||
if ExtVal <> 0 then
|
||||
break;
|
||||
// Search for better result
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
finally
|
||||
ReleaseRefAndNil(InfoEntry);
|
||||
@ -3905,6 +3944,11 @@ begin
|
||||
Result := FSections[ASection].RawData + AVA - FImageBase - FSections[ASection].VirtualAdress;
|
||||
end;
|
||||
|
||||
function TDbgDwarf.CompilationUnitsCount: Integer;
|
||||
begin
|
||||
Result := FCompilationUnits.Count;
|
||||
end;
|
||||
|
||||
{ TDbgVerboseDwarf }
|
||||
|
||||
function TDbgVerboseDwarf.GetCompilationUnitClass: TDwarfCompilationUnitClass;
|
||||
@ -4167,6 +4211,15 @@ begin
|
||||
PDWarfLineMap(FLineNumberMap.Objects[idx])^.Compress;
|
||||
end;
|
||||
|
||||
function TDwarfCompilationUnit.GetUnitName: String;
|
||||
begin
|
||||
Result := FUnitName;
|
||||
if Result <> '' then exit;
|
||||
|
||||
FUnitName := LazFileUtils.ExtractFileNameOnly(FileName);
|
||||
Result := FUnitName;
|
||||
end;
|
||||
|
||||
procedure TDwarfCompilationUnit.BuildAddressMap;
|
||||
var
|
||||
AttribList: TPointerDynArray;
|
||||
@ -4178,8 +4231,7 @@ var
|
||||
begin
|
||||
if FAddressMapBuild then Exit;
|
||||
|
||||
// scan to end
|
||||
LocateEntry(0, FScope, [lefContinuable, lefSearchChild], ResultScope, AttribList);
|
||||
ScanAllEntries;
|
||||
|
||||
Scope := FScope;
|
||||
while Scope.IsValid do
|
||||
@ -4775,6 +4827,17 @@ begin
|
||||
else Result := PQWord(AData)^;
|
||||
end;
|
||||
|
||||
procedure TDwarfCompilationUnit.ScanAllEntries;
|
||||
var
|
||||
ResultScope: TDwarfScopeInfo;
|
||||
AttribList: TPointerDynArray;
|
||||
begin
|
||||
if FScannedToEnd then exit;
|
||||
FScannedToEnd := True;
|
||||
// scan to end
|
||||
LocateEntry(0, FScope, [lefContinuable, lefSearchChild], ResultScope, AttribList);
|
||||
end;
|
||||
|
||||
function TDwarfCompilationUnit.ReadValue(AAttribute: Pointer; AForm: Cardinal; out AValue: Cardinal): Boolean;
|
||||
begin
|
||||
Result := True;
|
||||
|
@ -150,6 +150,7 @@ type
|
||||
TFpPascalExpressionPartIdentifer = class(TFpPascalExpressionPartContainer)
|
||||
private
|
||||
FDbgType: TDbgSymbol; // may be a variable or function or a type ...
|
||||
FDbgTypeDone: Boolean;
|
||||
protected
|
||||
function DoGetResultType: TDbgSymbol; override;
|
||||
function DoGetIsTypeCast: Boolean; override;
|
||||
@ -679,8 +680,9 @@ end;
|
||||
function TFpPascalExpressionPartIdentifer.DoGetResultType: TDbgSymbol;
|
||||
begin
|
||||
Result := nil;
|
||||
if FDbgType = nil then
|
||||
if (FDbgType = nil) and not FDbgTypeDone then
|
||||
FDbgType := FExpression.GetDbgTyeForIdentifier(GetText);
|
||||
FDbgTypeDone := True;
|
||||
if FDbgType = nil then
|
||||
exit;
|
||||
|
||||
@ -696,8 +698,9 @@ end;
|
||||
|
||||
function TFpPascalExpressionPartIdentifer.DoGetIsTypeCast: Boolean;
|
||||
begin
|
||||
if FDbgType = nil then
|
||||
if (FDbgType = nil) and not FDbgTypeDone then
|
||||
FDbgType := FExpression.GetDbgTyeForIdentifier(GetText);
|
||||
FDbgTypeDone := True;
|
||||
Result := (FDbgType <> nil) and (FDbgType.SymbolType = stType);
|
||||
end;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user