From 6362a111d93556659edc837740167d62485081e0 Mon Sep 17 00:00:00 2001 From: Martin Date: Mon, 21 Apr 2025 20:05:06 +0200 Subject: [PATCH] FpDebug: more DWARF-4 DW_FORM_exprloc and location-list handling (DW_FORM_sec_offset) --- components/fpdebug/fpdbgdwarf.pas | 15 +++++++++++---- components/fpdebug/fpdbgdwarfdataclasses.pas | 16 ++++++++++++++++ 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/components/fpdebug/fpdbgdwarf.pas b/components/fpdebug/fpdbgdwarf.pas index 9cdabb9f5e..5233d1eeaf 100644 --- a/components/fpdebug/fpdbgdwarf.pas +++ b/components/fpdebug/fpdbgdwarf.pas @@ -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 diff --git a/components/fpdebug/fpdbgdwarfdataclasses.pas b/components/fpdebug/fpdbgdwarfdataclasses.pas index 9dce993e88..d18835862f 100644 --- a/components/fpdebug/fpdbgdwarfdataclasses.pas +++ b/components/fpdebug/fpdbgdwarfdataclasses.pas @@ -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;