On Fri, May 28, 2021 at 8:29 AM Joost van der Sluis via Dwarf-Discuss <dwarf-discuss@lists.dwarfstd.org> wrote: > > Hi all, > > I am one of the Free Pascal developers and also work on a debugger, > aimed towards Free Pascal. > > Now in Pascal there are 'properties'. Maybe you know these from c# which > has something alike. Basically a property is an alias in a structure > that links to other members of the same structure for reading, writing > and/or storage-information.
Hmm - so this isn't like C# where you can write arbitrary code for the property? In this case it's only direct access - but you get to choose whether it's read only, read-write, etc, compared to having the member directly be public? That might 'just work' with existing DWARF consumers/debuggers if you had the alias as another member (as you say, with different access level) that happens to have the same data_member_location as the underlying member - you could add an extra/extension attribute to describe it as being read only, etc. I doubt the duplication of the data_member_location would be super expensive - but I could be wrong. Might be worth measuring, especially if this representational choice does get you "free" support in existing DWARF consumers, compared to having to teach them about new attributes, etc. > Example: > > type > TMyClass=class > private > FProp: Integer; > FPropIsStored: Boolean; > protected > function GetProp: Integer; > function GetItem(const Index: Integer): string; > public > property IndividualItem[Index: Integer]: string read GetItem; > published > property Prop: Integer read GetProp stored FPropIsStored; > property OtherProp: Integer read FProp write FProp; > property Item2: string index 2 read GetItem; > end; > > var > MyClass = TMyClass; > > Reading MyClass.Prop effectively calls GetProp. > > MyClass.Prop is read-only, and during streaming the information in > FPropIsStored is being used. > > MyClass.OtherProp is read/write, and is more or less an alias for the > private FProp field. > > MyClass.IndividualItem[6] is accessible like it is an array. And Item2 > has a fixed index. > > I want to encode this propery into the Dwarf debug-information. First question I usually ask is: Is there any prior art? (does GCC support this situation, what DWARF does it use to describe these entities? What about other DWARF producers?) > At this > moment we only generate debug-information for cases similar to > MyClass.OtherProp by duplicating the debug-information of FProp with > another visibility-class. Ah, guess that's my suggestion above? > I've added the following attributes: > DW_AT_FPC_property_read (0x3230) > DW_AT_FPC_property_write (0x3231) > DW_AT_FPC_property_stored (0x3232) > > And then those attributes contain a link to the corresponding > DW_TAG_members. OK, so FW_AT_FPC_property_stored uses an address form, most likely a CU-local one, like DW_FORM_ref4, etc? > This to keep the debug-information as compact as > possible. Furthermore I've added the tag DW_TAG_FPC_property (0x4230) or > else other debuggers may be confused when they encounter a DW_TAG_member > with only one or more of these specific fpc-attributes. > > I'll also have to add something like DW_AT_FPC_property_index to store > the value of a fixed index. > > I have two questions: > 1. Am I on the good track, or did I miss something? Sounds plausible. > 2. Maybe implementation specific, but maybe someone might have an idea: > to generate the proposed debug-info, I need to add a label to every > DW_TAG_member. The way LLVM deals with CU-local DIE references isn't with labels - it precomputes the offsets of all the DIEs and uses the known offset for the FORM value. You can see that here: https://godbolt.org/z/hqdP4x5eG .long 51 # DW_AT_type But LLVM also uses labels and relocations without issue - especially local labels (as Michael mentioned), section labels, and label differences (the latter is all you'd need if you wanted to do CU-relative references with labels instead of manually computing them) - label differences are resolved at assembly time, so they don't exist by the time the linker sees things & can't complicate that. > Using global labels inside these structures though, may > lead to all kinds of troubles, for example when a linker regards these > labels as the start of a new section. Or on Darwin/macOS. Calculating > the location of these tags is in principle possible I think, but > difficult. Any tips here? > > This is a dwarfdump of the class-definition above with my current additions: > > < 1><0x00000123> DW_TAG_class_type > DW_AT_name TMyClass > DW_AT_byte_size 0x00000010 > < 2><0x0000012e> DW_TAG_inheritance > DW_AT_accessibility DW_ACCESS_public > DW_AT_data_member_location DW_OP_plus_uconst 0 > DW_AT_type <GOFF=0x00005122> > < 2><0x00000137> DW_TAG_member > DW_AT_name FProp > DW_AT_data_member_location DW_OP_plus_uconst 8 > DW_AT_accessibility DW_ACCESS_private > DW_AT_type <GOFF=0x000000f3> > < 2><0x00000146> DW_TAG_member > DW_AT_name FPropIsStored > DW_AT_data_member_location DW_OP_plus_uconst 12 > DW_AT_accessibility DW_ACCESS_private > DW_AT_type <GOFF=0x000057a7> > < 2><0x0000015d> <Unknown TAG value 0x4230> > DW_AT_name IndividualItem > <Unknown AT value 0x3230> <GOFF=0x0000020c> > DW_AT_type <GOFF=0x000057c4> > < 2><0x00000175> <Unknown TAG value 0x4230> > DW_AT_name Prop > <Unknown AT value 0x3230> <GOFF=0x000001ad> > <Unknown AT value 0x3232> <GOFF=0x00000146> > DW_AT_type <GOFF=0x000000f3> > < 2><0x00000187> <Unknown TAG value 0x4230> > DW_AT_name OtherProp > <Unknown AT value 0x3230> <GOFF=0x00000137> > <Unknown AT value 0x3231> <GOFF=0x00000137> > DW_AT_type <GOFF=0x000000f3> > < 2><0x0000019e> <Unknown TAG value 0x4230> > DW_AT_name Item2 > <Unknown AT value 0x3230> <GOFF=0x0000020c> > DW_AT_type <GOFF=0x000057c4> > < 2><0x000001ad> DW_TAG_subprogram > DW_AT_name GetProp > DW_AT_prototyped yes(1) > DW_AT_calling_convention > DW_CC_GNU_borland_fastcall_i386 > DW_AT_external yes(1) > DW_AT_accessibility DW_ACCESS_protected > DW_AT_type <GOFF=0x000000f3> > DW_AT_low_pc 0x00404840 > DW_AT_high_pc 0x00404867 > < 3><0x000001ce> DW_TAG_formal_parameter > DW_AT_name this > DW_AT_location 0x7678 DW_OP_breg6-8 > DW_AT_artificial yes(1) > DW_AT_type <GOFF=0x00000110> > < 3><0x000001dc> DW_TAG_variable > DW_AT_name $result > DW_AT_location 0x7674 DW_OP_breg6-12 > DW_AT_type <GOFF=0x000000f3> > < 3><0x000001ec> DW_TAG_variable > DW_AT_name GETPROP > DW_AT_location 0x7674 DW_OP_breg6-12 > DW_AT_type <GOFF=0x000000f3> > < 3><0x000001fc> DW_TAG_variable > DW_AT_name RESULT > DW_AT_location 0x7674 DW_OP_breg6-12 > DW_AT_type <GOFF=0x000000f3> > < 2><0x0000020c> DW_TAG_subprogram > DW_AT_name GetItem > DW_AT_prototyped yes(1) > DW_AT_calling_convention > DW_CC_GNU_borland_fastcall_i386 > DW_AT_external yes(1) > DW_AT_accessibility DW_ACCESS_protected > DW_AT_type <GOFF=0x000057c4> > DW_AT_low_pc 0x00404870 > DW_AT_high_pc 0x00404889 > < 3><0x0000022d> DW_TAG_formal_parameter > DW_AT_name this > DW_AT_location 0x7670 DW_OP_breg6-16 > DW_AT_artificial yes(1) > DW_AT_type <GOFF=0x00000110> > < 3><0x0000023b> DW_TAG_variable > DW_AT_name $result > DW_AT_location 0x766806 > DW_OP_breg6-24 DW_OP_deref > DW_AT_type <GOFF=0x000057c4> > < 3><0x0000024c> DW_TAG_formal_parameter > DW_AT_name Index > DW_AT_location 0x7678 DW_OP_breg6-8 > DW_AT_type <GOFF=0x000000f3> > < 3><0x0000025a> DW_TAG_variable > DW_AT_name GETITEM > DW_AT_location 0x766806 > DW_OP_breg6-24 DW_OP_deref > DW_AT_type <GOFF=0x000057c4> > < 3><0x0000026b> DW_TAG_variable > DW_AT_name RESULT > DW_AT_location 0x766806 > DW_OP_breg6-24 DW_OP_deref > DW_AT_type <GOFF=0x000057c4> > > > > _______________________________________________ > Dwarf-Discuss mailing list > Dwarf-Discuss@lists.dwarfstd.org > http://lists.dwarfstd.org/listinfo.cgi/dwarf-discuss-dwarfstd.org _______________________________________________ Dwarf-Discuss mailing list Dwarf-Discuss@lists.dwarfstd.org http://lists.dwarfstd.org/listinfo.cgi/dwarf-discuss-dwarfstd.org