[Dwarf-Discuss] What to do with Pascal properties?
Joost van der Sluis
joost@cnoc.nl
Sat Jun 5 12:39:21 GMT 2021
Op 03-06-2021 om 00:50 schreef David Blaikie via Dwarf-Discuss:
> On Fri, May 28, 2021 at 8:29 AM Joost van der Sluis via Dwarf-Discuss
> <dwarf-discuss at lists.dwarfstd.org> wrote:
>> 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.
They can do both - direct access and arbitrary code. And I agree that in
the case of direct access it is not that expensive.
>> 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?)
Yes, that would be easy. But I do not know of any feature in C or C++ or
any other language that is comparable to this functionality, except for
C#, but that does not generate Dwarf debug-information. But I am well
aware that do not know all existing languages that well. ;)
>> 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?
Yes.
>> 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?
Well, my current implementation always uses DW_FORM_ref_addr, but I now
realize that this should be a DW_FORM_ref4 most of the time.
It is possible to reference a member in a another CU, though. So local
is not always possible.
>> 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.
Yes, for cu-local references I can use local-labels and use their
differences.
For cu-global I have to precompute the offsets for a global label, this
must be doable.
Thank you and Michael for the input.
>> 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 at lists.dwarfstd.org
>> http://lists.dwarfstd.org/listinfo.cgi/dwarf-discuss-dwarfstd.org
> _______________________________________________
> Dwarf-Discuss mailing list
> Dwarf-Discuss at lists.dwarfstd.org
> http://lists.dwarfstd.org/listinfo.cgi/dwarf-discuss-dwarfstd.org
>
More information about the Dwarf-discuss
mailing list