FpDebug: Added support for DW_AT_entry_pc. Implemented <func>.EntryPCAddress to return the entry-point.

This commit is contained in:
Martin 2023-02-12 15:06:21 +01:00
parent a27e4c7d55
commit f86112c649
3 changed files with 60 additions and 1 deletions

View File

@ -496,6 +496,7 @@ type
TFpValueDwarfSubroutine = class(TFpValueDwarf)
protected
function IsValidTypeCast: Boolean; override;
function GetEntryPCAddress: TFpDbgMemLocation; override;
end;
{%endregion Value objects }
@ -1045,6 +1046,8 @@ DECL = DW_AT_decl_column, DW_AT_decl_file, DW_AT_decl_line
function GetValueObject: TFpValue; override;
function GetValueAddress(AValueObj: TFpValueDwarf; out
AnAddress: TFpDbgMemLocation): Boolean; override;
function GetEntryPCAddress(AValueObj: TFpValueDwarf; out
AnAddress: TFpDbgMemLocation): Boolean;
property DbgInfo: TFpDwarfInfo read FDwarf;
property ProcAddress: TDBGPtr read FAddress;
@ -1190,6 +1193,16 @@ begin
Result := False;
end;
function TFpValueDwarfSubroutine.GetEntryPCAddress: TFpDbgMemLocation;
begin
Result := InvalidLoc;
if (FDataSymbol = nil) then
exit;
assert(FDataSymbol is TFpSymbolDwarfDataProc, 'TFpValueDwarfSubroutine.GetEntryPCAddress: FDataSymbol is TFpSymbolDwarfDataProc');
if not TFpSymbolDwarfDataProc(FDataSymbol).GetEntryPCAddress(Self, Result) then
Result := InvalidLoc;
end;
{ TFpDwarfDefaultSymbolClassMap }
class function TFpDwarfDefaultSymbolClassMap.GetExistingClassMap: PFpDwarfSymbolClassMap;
@ -6278,6 +6291,45 @@ begin
Result := IsValidLoc(AnAddress);
end;
function TFpSymbolDwarfDataProc.GetEntryPCAddress(AValueObj: TFpValueDwarf; out
AnAddress: TFpDbgMemLocation): Boolean;
var
AttrData: TDwarfAttribData;
Addr: TDBGPtr;
Offs: QWord;
f: Cardinal;
begin
AnAddress := InvalidLoc;
Offs := 0;
if InformationEntry.GetAttribData(DW_AT_entry_pc, AttrData) then begin
f := AttrData.InformationEntry.AttribForm[AttrData.Idx];
if f = DW_FORM_addr then begin
Result := InformationEntry.ReadAddressValue(AttrData, Addr);
if Result then
AnAddress := TargetLoc(Addr);
exit;
end
else
// DWARF 5: DW_AT_entry_pc can be an unsigned offset to DW_AT_low_pc
if f in [DW_FORM_data1, DW_FORM_data2, DW_FORM_data4, DW_FORM_data8, DW_FORM_sdata, DW_FORM_udata] then begin
Result := InformationEntry.ReadValue(AttrData, Offs);
if not Result then
exit;
end
else
exit(False); // error
end;
if InformationEntry.GetAttribData(DW_AT_low_pc, AttrData) then
if InformationEntry.ReadAddressValue(AttrData, Addr) then
{$PUSH}{$R-}{$Q-}
AnAddress := TargetLoc(Addr + Offs);
{$POP}
//DW_AT_ranges
Result := IsValidLoc(AnAddress);
end;
function TFpSymbolDwarfDataProc.StateMachineValid: Boolean;
var
SM1, SM2: TDwarfLineInfoStateMachine;

View File

@ -134,6 +134,7 @@ type
function DoGetSize(out ASize: TFpDbgValueSize): Boolean; virtual;
function GetDataAddress: TFpDbgMemLocation; virtual;
function GetDerefAddress: TFpDbgMemLocation; virtual;
function GetEntryPCAddress: TFpDbgMemLocation; virtual;
function GetDataSize: TFpDbgValueSize; virtual;
function GetHasBounds: Boolean; virtual;
@ -180,6 +181,7 @@ type
property Address: TFpDbgMemLocation read GetAddress;
property DataAddress: TFpDbgMemLocation read GetDataAddress; //
property DerefAddress: TFpDbgMemLocation read GetDerefAddress; //
property EntryPCAddress: TFpDbgMemLocation read GetEntryPCAddress;
property DataSize: TFpDbgValueSize read GetDataSize;
property HasBounds: Boolean read GetHasBounds;
@ -1035,6 +1037,11 @@ begin
Result := 0;
end;
function TFpValue.GetEntryPCAddress: TFpDbgMemLocation;
begin
Result := InvalidLoc;
end;
procedure TFpValue.Reset;
begin
FEvalFlags := [];

View File

@ -898,7 +898,7 @@ begin
// check params
ProcAddress := AFunctionValue.DataAddress;
ProcAddress := AFunctionValue.EntryPCAddress;
if not IsReadableLoc(ProcAddress) then begin
DebugLn(['Error proc addr']);
AnError := CreateError(fpErrAnyError, ['Unable to calculate function address']);