[Dwarf-Discuss] About self-referencial sized types
Pierre-Marie de Rodat
derodat@adacore.com
Thu May 15 16:30:20 GMT 2014
Sanimir,
On 05/15/2014 04:22 PM, Agovic, Sanimir wrote:
> For this particular case you might do something like:
>
> DW_TAG_subrange_type:
> 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.
Absolutely. I that was my first try in GCC, before I thought about the
nasty example with two array fields.
> An alternative is
>
> DW_TAG_subrange_type:
> 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.
Oh, smart: I missed this operation. I just had a look at the DWARFv4
standard, however:
These operations transfer control of DWARF expression evaluation to
the DW_AT_location attribute of the referenced debugging
information entry. If there is no such attribute, then there is no
effect.
In our case, the "Record_type" DW_TAG_structure type does not have a
DW_AT_location attribute, so regardless how DW_AT_push_object_address
migth be evaluated in such cases, the DW_OP_call_ref operation would
have no effect.
> The way you implement the record above is quite interesting. It requires
> member offsets to be computed rather than being constant.
Indeed. I only had a look at how it was implemented by GNAT, though:
it's working this way for ages. ;-)
By the way, variable record field offsets are not an issue in DWARF,
even for our example: the evaluation of the DWARF expression in
DW_AT_data_member_location starts with a stack that contains the address
of the record, so it's easy to compute a field offset (for instance a2)
using the discriminants values (here: n).
> 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
> like:
>
> 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.
I'm not sure what you meant: how could a1 and a2 still be arrays with
dynamic bounds? (assuming they have constant member offsets)
I don't know if this is what you had in mind, but I thought you were
suggesting to use the whole record as a descriptor for each array. That
would be, in the DWARF info:
1. setting the DW_AT_member_data_location attribute of the a1 and a2
structure members to an "identity" expression (i.e. DW_OP_plus_uconst: 0);
2. setting the array type DIEs' DW_AT_data_location attribute to add
the field offset (which sometimes depend on discriminants, but that
isn't an issue anymore since we have the address of the record);
3. likewise for the subrange type DIEs' DW_AT_{lower,upper}_bound
attributes.
... It would work pretty well, actually! I'm not sure if this would
really be the way to go:
- it looks like DWARF hacking: I'm not sure that the record can be
properly considered as an array descriptor
- it may require to change a bunch of things in the compiler, but I
guess this is not an issue if know we will generate quality DWARF info. :-)
> 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
Interesting. This is still about arrays whose size depends on local
variables (or function arguments, which is the same to me), though. So
crafting DWARF expressions for the DW_AT_{lower,uppper}_bound attributes
looks reasonably easy to me: a sequence of regular register/stack
operations and computations on them should be sufficient.
--
Pierre-Marie de Rodat
More information about the Dwarf-discuss
mailing list