FpDebug: DW_AT_data_member_location now handles constant offset too. Moved to ComputeDataMemberAddress

git-svn-id: trunk@61789 -
This commit is contained in:
martin 2019-08-31 20:59:06 +00:00
parent 0d8b455ac6
commit 4b2740c97a

View File

@ -480,6 +480,8 @@ type
protected protected
function InitLocationParser(const {%H-}ALocationParser: TDwarfLocationExpression; function InitLocationParser(const {%H-}ALocationParser: TDwarfLocationExpression;
AnInitLocParserData: PInitLocParserData = nil): Boolean; virtual; AnInitLocParserData: PInitLocParserData = nil): Boolean; virtual;
function ComputeDataMemberAddress(const AnInformationEntry: TDwarfInformationEntry;
AValueObj: TFpValueDwarf; var AnAddress: TFpDbgMemLocation): Boolean; inline;
function LocationFromAttrData(const AnAttribData: TDwarfAttribData; AValueObj: TFpValueDwarf; function LocationFromAttrData(const AnAttribData: TDwarfAttribData; AValueObj: TFpValueDwarf;
var AnAddress: TFpDbgMemLocation; // kept, if tag does not exist var AnAddress: TFpDbgMemLocation; // kept, if tag does not exist
AnInitLocParserData: PInitLocParserData = nil; AnInitLocParserData: PInitLocParserData = nil;
@ -2611,8 +2613,6 @@ begin
end; end;
function TFpValueDwarfStructTypeCast.GetMemberCount: Integer; function TFpValueDwarfStructTypeCast.GetMemberCount: Integer;
var
ti: TFpSymbol;
begin begin
Result := 0; Result := 0;
if not HasTypeCastInfo then if not HasTypeCastInfo then
@ -2932,6 +2932,46 @@ begin
Result := True; Result := True;
end; end;
function TFpSymbolDwarf.ComputeDataMemberAddress(
const AnInformationEntry: TDwarfInformationEntry; AValueObj: TFpValueDwarf;
var AnAddress: TFpDbgMemLocation): Boolean;
var
AttrData: TDwarfAttribData;
Form: Cardinal;
ConstOffs: Int64;
InitLocParserData: TInitLocParserData;
begin
Result := True;
if AnInformationEntry.GetAttribData(DW_AT_data_member_location, AttrData) then begin
Form := AnInformationEntry.AttribForm[AttrData.Idx];
Result := False;
if Form in [DW_FORM_data1, DW_FORM_data2, DW_FORM_sdata, DW_FORM_udata] then begin
if AnInformationEntry.ReadValue(AttrData, ConstOffs) then begin
{$PUSH}{$R-}{$Q-} // TODO: check overflow
AnAddress.Address := AnAddress.Address + ConstOffs;
{$POP}
Result := True;
end
else
SetLastError(CreateError(fpErrAnyError));
end
// TODO: loclistptr: DW_FORM_data4, DW_FORM_data8,
else
if Form in [DW_FORM_block, DW_FORM_block1, DW_FORM_block2, DW_FORM_block4] then begin
InitLocParserData.ObjectDataAddress := AnAddress;
InitLocParserData.ObjectDataAddrPush := True;
Result := LocationFromAttrData(AttrData, AValueObj, AnAddress, @InitLocParserData);
end
else begin
SetLastError(CreateError(fpErrAnyError));
end;
end;
end;
function TFpSymbolDwarf.LocationFromAttrData( function TFpSymbolDwarf.LocationFromAttrData(
const AnAttribData: TDwarfAttribData; AValueObj: TFpValueDwarf; const AnAttribData: TDwarfAttribData; AValueObj: TFpValueDwarf;
var AnAddress: TFpDbgMemLocation; AnInitLocParserData: PInitLocParserData; var AnAddress: TFpDbgMemLocation; AnInitLocParserData: PInitLocParserData;
@ -3045,7 +3085,6 @@ function TFpSymbolDwarf.GetDataAddress(AValueObj: TFpValueDwarf;
var var
ti: TFpSymbolDwarfType; ti: TFpSymbolDwarfType;
InitLocParserData: TInitLocParserData; InitLocParserData: TInitLocParserData;
tmp: TFpDbgMemLocation;
begin begin
InitLocParserData.ObjectDataAddress := AnAddress; InitLocParserData.ObjectDataAddress := AnAddress;
InitLocParserData.ObjectDataAddrPush := False; InitLocParserData.ObjectDataAddrPush := False;
@ -3163,7 +3202,6 @@ end;
function TFpSymbolDwarfData.GetNestedSymbol(AIndex: Int64): TFpSymbol; function TFpSymbolDwarfData.GetNestedSymbol(AIndex: Int64): TFpSymbol;
var var
ti: TFpSymbol; ti: TFpSymbol;
k: TDbgSymbolKind;
begin begin
ti := TypeInfo; ti := TypeInfo;
if ti = nil then begin if ti = nil then begin
@ -3171,7 +3209,6 @@ begin
exit; exit;
end; end;
k := ti.Kind;
// while holding result, until refcount added, do not call any function // while holding result, until refcount added, do not call any function
Result := ti.NestedSymbol[AIndex]; Result := ti.NestedSymbol[AIndex];
assert((Result = nil) or (Result is TFpSymbolDwarfData), 'TFpSymbolDwarfData.GetMember is Value'); assert((Result = nil) or (Result is TFpSymbolDwarfData), 'TFpSymbolDwarfData.GetMember is Value');
@ -3180,7 +3217,6 @@ end;
function TFpSymbolDwarfData.GetNestedSymbolByName(AIndex: String): TFpSymbol; function TFpSymbolDwarfData.GetNestedSymbolByName(AIndex: String): TFpSymbol;
var var
ti: TFpSymbol; ti: TFpSymbol;
k: TDbgSymbolKind;
begin begin
ti := TypeInfo; ti := TypeInfo;
if ti = nil then begin if ti = nil then begin
@ -3188,8 +3224,6 @@ begin
exit; exit;
end; end;
k := ti.Kind;
// while holding result, until refcount added, do not call any function // while holding result, until refcount added, do not call any function
Result := ti.NestedSymbolByName[AIndex]; Result := ti.NestedSymbolByName[AIndex];
assert((Result = nil) or (Result is TFpSymbolDwarfData), 'TFpSymbolDwarfData.GetMember is Value'); assert((Result = nil) or (Result is TFpSymbolDwarfData), 'TFpSymbolDwarfData.GetMember is Value');
@ -4092,9 +4126,6 @@ end;
function TFpSymbolDwarfDataMember.GetValueAddress(AValueObj: TFpValueDwarf; out function TFpSymbolDwarfDataMember.GetValueAddress(AValueObj: TFpValueDwarf; out
AnAddress: TFpDbgMemLocation): Boolean; AnAddress: TFpDbgMemLocation): Boolean;
var
BaseAddr: TFpDbgMemLocation;
InitLocParserData: TInitLocParserData;
begin begin
AnAddress := AValueObj.DataAddressCache[0]; AnAddress := AValueObj.DataAddressCache[0];
Result := IsValidLoc(AnAddress); Result := IsValidLoc(AnAddress);
@ -4113,7 +4144,7 @@ begin
exit; exit;
end; end;
Assert((ParentTypeInfo is TFpSymbolDwarf) and (ParentTypeInfo.SymbolType = stType), ''); Assert((ParentTypeInfo is TFpSymbolDwarf) and (ParentTypeInfo.SymbolType = stType), '');
if not AValueObj.GetStructureDwarfDataAddress(BaseAddr, TFpSymbolDwarfType(ParentTypeInfo)) then begin if not AValueObj.GetStructureDwarfDataAddress(AnAddress, TFpSymbolDwarfType(ParentTypeInfo)) then begin
debugln(FPDBG_DWARF_ERRORS, ['DWARF ERROR in TFpSymbolDwarfDataMember.InitLocationParser Error: ',ErrorCode(LastError),' ValueObject=', DbgSName(FValueObject)]); debugln(FPDBG_DWARF_ERRORS, ['DWARF ERROR in TFpSymbolDwarfDataMember.InitLocationParser Error: ',ErrorCode(LastError),' ValueObject=', DbgSName(FValueObject)]);
Result := False; Result := False;
if not IsError(LastError) then if not IsError(LastError) then
@ -4122,9 +4153,9 @@ begin
end; end;
//TODO: AValueObj.StructureValue.LastError //TODO: AValueObj.StructureValue.LastError
InitLocParserData.ObjectDataAddress := BaseAddr; Result := ComputeDataMemberAddress(InformationEntry, AValueObj, AnAddress);
InitLocParserData.ObjectDataAddrPush := True; if not Result then
Result := LocationFromTag(DW_AT_data_member_location, AValueObj, AnAddress, @InitLocParserData); exit;
AValueObj.DataAddressCache[0] := AnAddress; AValueObj.DataAddressCache[0] := AnAddress;
end; end;
@ -4182,8 +4213,10 @@ function TFpSymbolDwarfTypeStructure.GetDataAddressNext(AValueObj: TFpValueDwarf
ATargetCacheIndex: Integer): Boolean; ATargetCacheIndex: Integer): Boolean;
var var
t: TFpDbgMemLocation; t: TFpDbgMemLocation;
InitLocParserData: TInitLocParserData;
begin begin
Result := IsReadableMem(AnAddress);
if not Result then
exit;
t := AValueObj.DataAddressCache[ATargetCacheIndex]; t := AValueObj.DataAddressCache[ATargetCacheIndex];
if IsInitializedLoc(t) then begin if IsInitializedLoc(t) then begin
AnAddress := t; AnAddress := t;
@ -4191,17 +4224,16 @@ begin
end end
else begin else begin
InitInheritanceInfo; InitInheritanceInfo;
//TODO: may be a constant // offset
InitLocParserData.ObjectDataAddress := AnAddress; Result := FInheritanceInfo = nil;
InitLocParserData.ObjectDataAddrPush := True; if Result then
Result := LocationFromTag(DW_AT_data_member_location, AValueObj, t, @InitLocParserData, FInheritanceInfo); exit;
Result := ComputeDataMemberAddress(FInheritanceInfo, AValueObj, AnAddress);
if not Result then if not Result then
exit; exit;
AnAddress := t;
AValueObj.DataAddressCache[ATargetCacheIndex] := AnAddress;
if IsError(AValueObj.MemManager.LastError) then AValueObj.DataAddressCache[ATargetCacheIndex] := AnAddress;
SetLastError(AValueObj.MemManager.LastError);
end; end;
Result := inherited GetDataAddressNext(AValueObj, AnAddress, ATargetType, ATargetCacheIndex); Result := inherited GetDataAddressNext(AValueObj, AnAddress, ATargetType, ATargetCacheIndex);