[Dwarf-Discuss] What to do with Pascal properties?

2021-05-28 Thread Joost van der Sluis via Dwarf-Discuss

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.


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. 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.


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. 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?
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. 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><0x0123>DW_TAG_class_type
  DW_AT_name  TMyClass
  DW_AT_byte_size 0x0010
< 2><0x012e>  DW_TAG_inheritance
DW_AT_accessibility DW_ACCESS_public
DW_AT_data_member_location  DW_OP_plus_uconst 0
DW_AT_type  
< 2><0x0137>  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  
< 2><0x0146>  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  
< 2><0x015d>  
DW_AT_name  IndividualItem
   
DW_AT_type  
< 2><0x0175>  
DW_AT_name  Prop
   
   
DW_AT_type  
< 2><0x0187>  
DW_AT_name  OtherProp
   
   
DW_AT_type  
< 2><0x019e>  
DW_AT_name  Item2
   
DW_AT_type  
< 2><0x01ad>  DW_TAG_subprogram
DW_AT_name  GetProp
DW_AT_prototypedyes(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  
DW_AT_low_pc0x00404840
DW_AT_high_pc   0x00404867
< 3><0x01ce>DW_TAG_formal_parameter
  DW_AT_name  this
  DW_AT_location  0x7678

Re: [Dwarf-Discuss] What to do with Pascal properties?

2021-05-28 Thread Michael Eager via Dwarf-Discuss

In 5/28/21 7:11 AM, Joost van der Sluis via Dwarf-Discuss 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.


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. 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.


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. 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?


Generally, it looks like you are heading in the right direction.  I'd
have to look into the details much more to make any suggestions.

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. 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?


The general DWARF philosophy is to minimize relocations where ever
possible.  It isn't clear whether you are pointing the TAG
with a relocatable address or not.  Use offsets from the start of the
section where ever possible.

If the question is about local vs global symbols, many assemblers
will treat symbols which start with a period (e.g., .start) as
local and not export them to the object file symbol table.



This is a dwarfdump of the class-definition above with my current 
additions:


< 1><0x0123>    DW_TAG_class_type
   DW_AT_name  TMyClass
   DW_AT_byte_size 0x0010
< 2><0x012e>  DW_TAG_inheritance
     DW_AT_accessibility DW_ACCESS_public
     DW_AT_data_member_location  DW_OP_plus_uconst 0
     DW_AT_type  
< 2><0x0137>  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  
< 2><0x0146>  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  
< 2><0x015d>  
     DW_AT_name  IndividualItem
        
     DW_AT_type  
< 2><0x0175>  
     DW_AT_name  Prop
        
        
     DW_AT_type  
< 2><0x0187>  
     DW_AT_name  OtherProp
        
        
     DW_AT_type  
< 2><0x019e>  
     DW_AT_name  Item2
        
     DW_AT_type  
< 2><0x01ad>  DW_TAG_subprogram