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
_______________________________________________
Dwarf-Discuss mailing list
Dwarf-Discuss@lists.dwarfstd.org
http://lists.dwarfstd.org/listinfo.cgi/dwarf-discuss-dwarfstd.org

Reply via email to