Add functionality to get proc start/end addresses from debug info. Used to scan prologue and epilogue for frame information on AVR target.

This commit is contained in:
ccrause 2021-07-04 08:36:33 +02:00
parent 542c98a369
commit 23065e004c
3 changed files with 100 additions and 0 deletions

View File

@ -463,6 +463,8 @@ type
function AddrOffset: TDBGPtr; virtual; // gives the offset between the loaded addresses and the compiled addresses
function FindProcSymbol(const AName: String): TFpSymbol; overload;
function FindProcSymbol(AAdress: TDbgPtr): TFpSymbol; overload;
function FindProcStartEndPC(AAdress: TDbgPtr; out AStartPC, AEndPC: TDBGPtr): boolean;
procedure LoadInfo; virtual;
property Process: TDbgProcess read FProcess;
@ -617,6 +619,8 @@ public
function FindProcSymbol(const AName, ALibraryName: String; IsFullLibName: Boolean = True): TFpSymbol; overload;
function FindProcSymbol(AAdress: TDbgPtr): TFpSymbol; overload;
function FindSymbolScope(AThreadId, AStackFrame: Integer): TFpDbgSymbolScope;
function FindProcStartEndPC(const AAdress: TDbgPtr; out AStartPC, AEndPC: TDBGPtr): boolean;
function ContextFromProc(AThreadId, AStackFrame: Integer; AProcSym: TFpSymbol): TFpDbgLocationContext; inline; deprecated 'use TFpDbgSimpleLocationContext.Create';
function GetLib(const AHandle: THandle; out ALib: TDbgLibrary): Boolean;
property LastLibraryLoaded: TDbgLibrary read GetLastLibraryLoaded;
@ -1623,6 +1627,15 @@ begin
result := FSymbolTableInfo.FindProcSymbol(AAdress);
end;
function TDbgInstance.FindProcStartEndPC(AAdress: TDbgPtr; out AStartPC,
AEndPC: TDBGPtr): boolean;
begin
{$PUSH}{$R-}{$Q-}
AAdress := AAdress + AddrOffset;
{$POP}
Result := FDbgInfo.FindProcStartEndPC(AAdress, AStartPC, AEndPC);
end;
procedure TDbgInstance.LoadInfo;
begin
InitializeLoaders;
@ -1871,6 +1884,20 @@ begin
Ctx.ReleaseReference;
end;
function TDbgProcess.FindProcStartEndPC(const AAdress: TDbgPtr; out AStartPC,
AEndPC: TDBGPtr): boolean;
var
n: Integer;
Inst: TDbgInstance;
begin
for n := 0 to FSymInstances.Count - 1 do
begin
Inst := TDbgInstance(FSymInstances[n]);
Result := Inst.FindProcStartEndPC(AAdress, AStartPC, AEndPC);
if Result then Exit;
end;
end;
function TDbgProcess.ContextFromProc(AThreadId, AStackFrame: Integer;
AProcSym: TFpSymbol): TFpDbgLocationContext;
begin

View File

@ -683,6 +683,8 @@ type
// On Darwin it could be that the debug-information is not included into the executable by the linker.
// This function is to map object-file addresses into the corresponding addresses in the executable.
function MapAddressToNewValue(AValue: QWord): QWord;
// Get start/end addresses of proc
function GetProcStartEnd(const AAddress: TDBGPtr; out AStartPC, AEndPC: TDBGPtr): boolean;
property Valid: Boolean read FValid;
property FileName: String read FFileName;
@ -736,6 +738,8 @@ type
function FindSymbolScope(ALocationContext: TFpDbgLocationContext; AAddress: TDbgPtr = 0): TFpDbgSymbolScope; override;
function FindDwarfProcSymbol(AAddress: TDbgPtr): TDbgDwarfSymbolBase; inline;
function FindProcSymbol(AAddress: TDbgPtr): TFpSymbol; override; overload;
function FindProcStartEndPC(const AAddress: TDbgPtr; out AStartPC, AEndPC: TDBGPtr): boolean; override;
//function FindSymbol(const AName: String): TDbgSymbol; override; overload;
function GetLineAddresses(const AFileName: String; ALine: Cardinal; var AResultList: TDBGPtrArray): Boolean; override;
function GetLineAddressMap(const AFileName: String): PDWarfLineMap;
@ -3640,6 +3644,29 @@ begin
end;
end;
function TFpDwarfInfo.FindProcStartEndPC(const AAddress: TDbgPtr; out AStartPC,
AEndPC: TDBGPtr): boolean;
var
n: Integer;
CU: TDwarfCompilationUnit;
Iter: TLockedMapIterator;
Info: PDwarfAddressInfo;
MinMaxSet: boolean;
begin
for n := 0 to FCompilationUnits.Count - 1 do
begin
CU := TDwarfCompilationUnit(FCompilationUnits[n]);
CU.WaitForScopeScan;
if not CU.Valid then Continue;
MinMaxSet := CU.FMinPC <> CU.FMaxPC;
if MinMaxSet and ((AAddress < CU.FMinPC) or (AAddress > CU.FMaxPC))
then Continue;
Result := CU.GetProcStartEnd(AAddress, AStartPC, AEndPC);
if Result then exit;
end;
end;
function TFpDwarfInfo.FindDwarfUnitSymbol(AAddress: TDbgPtr
): TDbgDwarfSymbolBase;
var
@ -4771,6 +4798,41 @@ begin
end;
end;
function TDwarfCompilationUnit.GetProcStartEnd(const AAddress: TDBGPtr; out
AStartPC, AEndPC: TDBGPtr): boolean;
var
Iter: TLockedMapIterator;
Info: PDwarfAddressInfo;
begin
if not FAddressMapBuild then
BuildAddressMap;
Result := false;
Iter := TLockedMapIterator.Create(FAddressMap);
try
if not Iter.Locate(AAddress) then
begin
if not Iter.BOM then
Iter.Previous;
if Iter.BOM then
Exit;
end;
// iter is at the closest defined address before AAddress
Info := Iter.DataPtr;
if (AAddress >= Info^.StartPC) or (AAddress <= Info^.EndPC) then
begin
AStartPC := Info^.StartPC;
AEndPC := Info^.EndPC;
Result := true;
end;
finally
Iter.Free;
end;
end;
function TDwarfCompilationUnit.ReadValue(AAttribute: Pointer; AForm: Cardinal; out AValue: Cardinal): Boolean;
begin
Result := True;

View File

@ -598,6 +598,9 @@ type
function FindSymbolScope(ALocationContext: TFpDbgLocationContext; {%H-}AAddress: TDbgPtr = 0): TFpDbgSymbolScope; virtual;
function FindProcSymbol(AAddress: TDbgPtr): TFpSymbol; virtual; overload;
function FindProcSymbol(const {%H-}AName: String): TFpSymbol; virtual; overload;
function FindProcStartEndPC(const AAddress: TDbgPtr; out AStartPC, AEndPC: TDBGPtr): boolean; virtual;
property HasInfo: Boolean read FHasInfo;
function GetLineAddresses(const AFileName: String; ALine: Cardinal; var AResultList: TDBGPtrArray): Boolean; virtual;
//property MemManager: TFpDbgMemReaderBase read GetMemManager write SetMemManager;
@ -1746,6 +1749,14 @@ begin
Result := nil;
end;
function TDbgInfo.FindProcStartEndPC(const AAddress: TDbgPtr; out AStartPC,
AEndPC: TDBGPtr): boolean;
begin
AStartPC := 0;
AEndPC := 0;
Result := false;
end;
function TDbgInfo.GetLineAddresses(const AFileName: String; ALine: Cardinal;
var AResultList: TDBGPtrArray): Boolean;
begin