[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