Hi,
Since the gcc vta branch now emits the new (Dwarf 4) DW_OP_stack_value
and DW_OP_implicit_value operands I looked into supporting them. This is
a little bit difficult since, especially DW_OP_implicit_value changes
some assumptions (at least some of mine).
Unlike what the current comment in dwarf.h says the value block of
DW_OP_implicit_value isn't carried in a DW_FORM, but uses the "raw
memory encoding of the target". At least that is what gcc seems to emit,
and reading the spec, that does seem what was meant to happen. This is
somewhat awkward since it means we don't have the context to interpret
the value at this point. You could see what points to the location
description and see what the type should be, but that might not always
be simple, so you have to depend on the caller knowing what to do with
the "raw memory encoding".
2009-07-19 Mark Wielaard <mjw(a)redhat.com>
* dwarf.h: Correct description of DW_OP_implicit_value encoding.
Making readelf support them isn't too hard. For DW_OP_stack_value it is
simply listing the new opcode. For DW_OP_implicit_value it means just
reading the length and the (non-encoded) value. The only difficult is
whether or not the try to print the value in a decoded form when the
length is known. My patch prints it decoded when it is [1,] 2, 4 or 8
bytes since it is most likely to be a value of a basic type, otherwise
it just dumps it as a hex bytes as is.
2009-07-19 Mark Wielaard <mjw(a)redhat.com>
* readelf.c (print_ops): Add handling of DW_OP_implicit_value
and DW_OP_stack_value.
Then we come to libdw getlocation() and things get a bit harder. Again
DW_OP_stack_value isn't much trouble. It doesn't have any operands, so
just return it as is when interning. But DW_OP_implicit_value is a bit
of an issue, since we don't know the actual value (no DW_FORM, just raw
bytes), there is no convenient way to store it. Also it can be of
arbitrary length, and all we have are two Dwarf_Words. In theory we
could just pass the length and the offset (already there in the
Dwarf_Op) into the Dwarf_Block. But there are two issues with this.
First, the offset is to the start of the DW_OP and there is no
convenient way I know of for the caller to get the size of the length
encoding, so it is hard to determine the actual offset (we could store
the extra offset/length-size in the number2 Dwarf_Word though).
Secondly I don't actually understand how the caller would get a handle
to the Dwarf_Block the offset refers to. For dwarf_getlocation() it
would be easy, just call dwarf_formblock() on the Dwarf_Attribute. But
for dwarf_getlocation_addr() the caller would have to parse the location
list themselves and hope they do it in the same order/preference that
dwarf_getlocation_addr() does it. Or am I missing some simple method to
get at the Dwarf_Block that the Dwarf_Op array that
dwarf_getlocation_addr() returns refer to?
So for now I just store the length as number and the actual address into
the Dwarf_Block data where the raw memory representation starts into
number2. But this feels a bit like cheating, since it isn't really
interning the DW_OP data since it depends on having the pointer into the
data around.
2009-07-20 Mark Wielaard <mjw(a)redhat.com>
* dwarf_getlocation.c (__libdw_intern_expression): Handle
DW_OP_stack_value and DW_OP_implicit_value.
Cheers,
Mark