mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-14 06:39:12 +02:00
FpDebug: Added support for DW_AT_entry_pc. Implemented <func>.EntryPCAddress to return the entry-point.
This commit is contained in:
parent
a27e4c7d55
commit
f86112c649
@ -496,6 +496,7 @@ type
|
|||||||
TFpValueDwarfSubroutine = class(TFpValueDwarf)
|
TFpValueDwarfSubroutine = class(TFpValueDwarf)
|
||||||
protected
|
protected
|
||||||
function IsValidTypeCast: Boolean; override;
|
function IsValidTypeCast: Boolean; override;
|
||||||
|
function GetEntryPCAddress: TFpDbgMemLocation; override;
|
||||||
end;
|
end;
|
||||||
{%endregion Value objects }
|
{%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 GetValueObject: TFpValue; override;
|
||||||
function GetValueAddress(AValueObj: TFpValueDwarf; out
|
function GetValueAddress(AValueObj: TFpValueDwarf; out
|
||||||
AnAddress: TFpDbgMemLocation): Boolean; override;
|
AnAddress: TFpDbgMemLocation): Boolean; override;
|
||||||
|
function GetEntryPCAddress(AValueObj: TFpValueDwarf; out
|
||||||
|
AnAddress: TFpDbgMemLocation): Boolean;
|
||||||
|
|
||||||
property DbgInfo: TFpDwarfInfo read FDwarf;
|
property DbgInfo: TFpDwarfInfo read FDwarf;
|
||||||
property ProcAddress: TDBGPtr read FAddress;
|
property ProcAddress: TDBGPtr read FAddress;
|
||||||
@ -1190,6 +1193,16 @@ begin
|
|||||||
Result := False;
|
Result := False;
|
||||||
end;
|
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 }
|
{ TFpDwarfDefaultSymbolClassMap }
|
||||||
|
|
||||||
class function TFpDwarfDefaultSymbolClassMap.GetExistingClassMap: PFpDwarfSymbolClassMap;
|
class function TFpDwarfDefaultSymbolClassMap.GetExistingClassMap: PFpDwarfSymbolClassMap;
|
||||||
@ -6278,6 +6291,45 @@ begin
|
|||||||
Result := IsValidLoc(AnAddress);
|
Result := IsValidLoc(AnAddress);
|
||||||
end;
|
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;
|
function TFpSymbolDwarfDataProc.StateMachineValid: Boolean;
|
||||||
var
|
var
|
||||||
SM1, SM2: TDwarfLineInfoStateMachine;
|
SM1, SM2: TDwarfLineInfoStateMachine;
|
||||||
|
@ -134,6 +134,7 @@ type
|
|||||||
function DoGetSize(out ASize: TFpDbgValueSize): Boolean; virtual;
|
function DoGetSize(out ASize: TFpDbgValueSize): Boolean; virtual;
|
||||||
function GetDataAddress: TFpDbgMemLocation; virtual;
|
function GetDataAddress: TFpDbgMemLocation; virtual;
|
||||||
function GetDerefAddress: TFpDbgMemLocation; virtual;
|
function GetDerefAddress: TFpDbgMemLocation; virtual;
|
||||||
|
function GetEntryPCAddress: TFpDbgMemLocation; virtual;
|
||||||
function GetDataSize: TFpDbgValueSize; virtual;
|
function GetDataSize: TFpDbgValueSize; virtual;
|
||||||
|
|
||||||
function GetHasBounds: Boolean; virtual;
|
function GetHasBounds: Boolean; virtual;
|
||||||
@ -180,6 +181,7 @@ type
|
|||||||
property Address: TFpDbgMemLocation read GetAddress;
|
property Address: TFpDbgMemLocation read GetAddress;
|
||||||
property DataAddress: TFpDbgMemLocation read GetDataAddress; //
|
property DataAddress: TFpDbgMemLocation read GetDataAddress; //
|
||||||
property DerefAddress: TFpDbgMemLocation read GetDerefAddress; //
|
property DerefAddress: TFpDbgMemLocation read GetDerefAddress; //
|
||||||
|
property EntryPCAddress: TFpDbgMemLocation read GetEntryPCAddress;
|
||||||
property DataSize: TFpDbgValueSize read GetDataSize;
|
property DataSize: TFpDbgValueSize read GetDataSize;
|
||||||
|
|
||||||
property HasBounds: Boolean read GetHasBounds;
|
property HasBounds: Boolean read GetHasBounds;
|
||||||
@ -1035,6 +1037,11 @@ begin
|
|||||||
Result := 0;
|
Result := 0;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TFpValue.GetEntryPCAddress: TFpDbgMemLocation;
|
||||||
|
begin
|
||||||
|
Result := InvalidLoc;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TFpValue.Reset;
|
procedure TFpValue.Reset;
|
||||||
begin
|
begin
|
||||||
FEvalFlags := [];
|
FEvalFlags := [];
|
||||||
|
@ -898,7 +898,7 @@ begin
|
|||||||
|
|
||||||
// check params
|
// check params
|
||||||
|
|
||||||
ProcAddress := AFunctionValue.DataAddress;
|
ProcAddress := AFunctionValue.EntryPCAddress;
|
||||||
if not IsReadableLoc(ProcAddress) then begin
|
if not IsReadableLoc(ProcAddress) then begin
|
||||||
DebugLn(['Error proc addr']);
|
DebugLn(['Error proc addr']);
|
||||||
AnError := CreateError(fpErrAnyError, ['Unable to calculate function address']);
|
AnError := CreateError(fpErrAnyError, ['Unable to calculate function address']);
|
||||||
|
Loading…
Reference in New Issue
Block a user