FpDebug: more DWARF-4 DW_FORM_exprloc and location-list handling (DW_FORM_sec_offset)

This commit is contained in:
Martin 2025-04-21 20:05:06 +02:00
parent b849b153b5
commit 6362a111d9
2 changed files with 27 additions and 4 deletions

View File

@ -4588,13 +4588,17 @@ var
InitLocParserData: TInitLocParserData;
ByteSize: TFpDbgValueSize;
BitOffset, BitSize: Int64;
IsLocList: Boolean;
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
IsLocList := DW_Form_IsLocationList(Form, CompilationUnit.Version);
if (not IsLocList) and
(Form in [DW_FORM_data1, DW_FORM_data2, DW_FORM_data4, DW_FORM_data8, 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;
@ -4605,10 +4609,9 @@ begin
SetLastError(AValueObj, 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
if IsLocList or (Form in [DW_FORM_block, DW_FORM_block1, DW_FORM_block2, DW_FORM_block4, DW_FORM_exprloc])
then begin
InitLocParserData.ObjectDataAddress := AnAddress;
InitLocParserData.ObjectDataAddrPush := True;
Result := LocationFromAttrData(AttrData, AValueObj, AnAddress, @InitLocParserData);
@ -4881,8 +4884,12 @@ begin
AnAddress := InvalidLoc;
AForm := AnAttribData.InformationEntry.AttribForm[AnAttribData.Idx];
(* DW_FORM_data4, DW_FORM_data8 should only happen with DWARF-3 or before *)
if (AForm = DW_FORM_data4) or (AForm = DW_FORM_data8) or (AForm = DW_FORM_sec_offset) then begin
// location list
DebugLn((FPDBG_DWARF_VERBOSE or FPDBG_DWARF_WARNINGS or DBG_WARNINGS) and
(AForm in [DW_FORM_data4, DW_FORM_data8]) and (CompilationUnit.Version > 3),
['Found location-list via DW_FORM_data# for newer DWARF version']);
if not LocationExprFromLocationList(AnAttribData, AValueObj, Val) then begin
DebugLn(FPDBG_DWARF_VERBOSE, ['LocationFromAttrData: failed to read DW_AT_location from loc-list']);
if not IsError(AValueObj.LastError) then

View File

@ -949,6 +949,8 @@ function DbgsDump(AScope: TDwarfScopeInfo; ACompUnit: TDwarfCompilationUnit): St
function GetDwarfSymbolClassMapList: TFpSymbolDwarfClassMapList; inline;
function NameInfoForSearch(const AName: String): TNameSearchInfo;
function DW_Form_IsLocationList(AForm: Cardinal; ADwarfVersion: integer): Boolean;
property DwarfSymbolClassMapList: TFpSymbolDwarfClassMapList read GetDwarfSymbolClassMapList;
implementation
@ -979,6 +981,20 @@ begin
Result.NameHash := objpas.Hash(Result.NameUpper) and $7fff or $8000;
end;
function DW_Form_IsLocationList(AForm: Cardinal; ADwarfVersion: integer): Boolean;
begin
(* In DWARF V3 the forms DW_FORM_data4 and DW_FORM_data8 were members of either
class constant or one of the classes lineptr, loclistptr, macptr or rangelistptr,
depending on context.
In DWARF V4 DW_FORM_data4 and DW_FORM_data8 are members of class constant in all cases.
The new DW_FORM_sec_offset replaces their usage for the other classes.
*)
Result := (AForm = DW_FORM_sec_offset) or
( (ADwarfVersion < 4) and
(AForm in [DW_FORM_data4, DW_FORM_data8])
);
end;
function Dbgs(AInfoData: Pointer; ACompUnit: TDwarfCompilationUnit): String;
var
Attrib: Pointer;