> > 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. > Indeed, therefore you have to reference a DW_TAG_variable. But this introduces a type/variable dependency. So a record type maps to a single variable, you end up with a 1:1 relation for this kind of types.
> > 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). > Unfortunately gdb only allows constant offsets or constant dwarf expressions. > > 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) > It essentially works around the limitation of not having dynamic member offset support. a) Assign constant offsets to your record members. b) Use data_location for array types to refer to the actual array offset c) use upper/lower to specify the bounds See a1/a2/aN as proxy array types which use data_location to point to the right location at runtime. > 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 is indeed quite hackish and we should rather add the necessary bits to gdb. > - it looks like DWARF hacking: I'm not sure that the record can be > properly considered as an array descriptor > If you emit the corresponding dwarf tags for your initial example and add the data_location as well as the upper/lower attributes it should work, of course only in theory ATM. > > 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. > The problem is that the member offset depend on runtime information similar to sizeof which needs to be evaluated at runtime if the operand is a vla. Given the following snippet: struct foo {int a[n], int b[i];}; &((struct foo *)0)->b; What value do you expect here? And should the value be different if it is evaluated at runtime e.g. &f.b - &f.a? -Sanimir 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 _______________________________________________ Dwarf-Discuss mailing list Dwarf-Discuss@lists.dwarfstd.org http://lists.dwarfstd.org/listinfo.cgi/dwarf-discuss-dwarfstd.org