[Dwarf-Discuss] About self-referencial sized types

Agovic, Sanimir sanimir.agovic at intel.com
Thu May 15 07:22:27 PDT 2014

> > Can you illustrate the record descriptor representation? e.g. a
> > simple representation in form of a C struct. My knowledge about how
> > vla work is pretty limited to C99 and Fortran. It might help to
> > understand the problem a bit better.
> Sure, I should have done it earlier. The Record_Type I was refering to
> in my example would be translated to something like:
>    struct record_type {
>      int n;
>      int a[1 .. max(n, 0)];
>    };
For this particular case you might do something like:

	DW_AT_upper_bound: DW_OP_push_object_address; DW_OP_lit4; 
                        DW_OP_minus; DW_OP_deref_size 4;

Of course it is very limiting, please see this as FYI only. It illustrates
how to use DW_OP_push_object_address.

An alternative is

	DW_AT_upper_bound: DW_OP_call_ref "R"; DW_OP_deref_size 4;

The first operation evaluates the DW_AT_location attribute of the referenced
DIE. We end up of having the value of n, thus the upper bound. But I`m not
sure if I misuse the op here, as it requires a type to be bound/instantiated
for a particular variable.

The way you implement the record above is quite interesting. It requires
member offsets to be computed rather than being constant.

This leads me to a funny idea:

struct record_type {
  int n;
  int a1[1]; // array_type with constant member offset
  int a2[1]; // ...

In this scenario you have constant offsets, upper_bound for a1,a2 could look 

  DW_OP_push_object_address; DW_OP_deref_size 4

The actual location of a1, a2 could be described via DW_AT_data_location. The
attribute allows indirection to the actual payload.

I hope the examples above make sense to you.

> So, if I understand correctly, the C99 VLAs rely on "neighbor" local
> variables, the Fortran ones rely on descriptors (i.e. wrapped pointers
> that embbed information about the array), while the Ada ones can rely on
> both _plus_ other cases, like the example I introduced at the beginning
> of the thread. The DW_OP_push_object_address seems to be suited only for
> descriptors, and thus it is not adapted to describe such bound
> computations in DWARF.
Indeed. DW_OP_push_object_address is suited for relative based information
e.g. struct array_type { void* data; size_t n;};

Btw, gcc accepts vla as members of structures as an extension see ['1] and
Tom pointed out ['2] in a source comment:

| [...] GCC does have an extension that allows a VLA in the middle of a
| structure, but the DWARF it emits is relatively useless
| to us, so we can't represent such a type properly --

This might be related to your current work.

['1] https://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html 
['2] https://sourceware.org/ml/gdb-patches/2014-05/msg00097.html

> By the way, I came across an issue on dwarfstd.org[1]: it defines a new
> operation (DW_OP_implicit_pointer) which can be used to get the address
> of an object from the corresponding DIE. While it was created to deal
> with "optimized out" objects (that obviously cannot be referenced with a
> real pointer), it fits more what we would need to do here than
> DW_OP_push_object_address. Using it would look more like a hack to me,
> however...
Can't say much about it.

Intel GmbH
Dornacher Strasse 1
85622 Feldkirchen/Muenchen, Deutschland
Sitz der Gesellschaft: Feldkirchen bei Muenchen
Geschaeftsfuehrer: Christian Lamprechter, Hannes Schwaderer, Douglas Lusk
Registergericht: Muenchen HRB 47456
Ust.-IdNr./VAT Registration No.: DE129385895
Citibank Frankfurt a.M. (BLZ 502 109 00) 600119052

More information about the Dwarf-Discuss mailing list