This is just for low-level byte munching support, so that libdw knows how to decode the opcode stream, and doesn't fail when it encounters one of the new opcodes.
The context is that I'm reviving locstat. The test binary that I have on hand uses some of these opcodes. locstat mostly doesn't care what exact location expression describes location of variable on any particular address. It just cares that there is at least one. So what's below actually fixes the problem for locstat, even if there are no higher-level interfaces for grokking the extensions. OK to push this? Thanks, PM --- libdw/ChangeLog | 7 +++++++ libdw/dwarf_getlocation.c | 26 ++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 0 deletions(-) diff --git a/libdw/ChangeLog b/libdw/ChangeLog index 416a16f..0e65da8 100644 --- a/libdw/ChangeLog +++ b/libdw/ChangeLog @@ -1,3 +1,10 @@ +2012-10-09 Petr Machata <[email protected]> + + * dwarf_getlocation.c (__libdw_intern_expression): Handle + DW_OP_GNU_parameter_ref, DW_OP_GNU_convert, DW_OP_GNU_reinterpret, + DW_OP_GNU_regval_type, DW_OP_GNU_entry_value, + DW_OP_GNU_deref_type, DW_OP_GNU_const_type. + 2012-08-24 Mark Wielaard <[email protected]> * dwarf_begin_elf.c (check_section): Only probe for dwz multi files diff --git a/libdw/dwarf_getlocation.c b/libdw/dwarf_getlocation.c index dfaa742..daeff2d 100644 --- a/libdw/dwarf_getlocation.c +++ b/libdw/dwarf_getlocation.c @@ -339,6 +339,7 @@ __libdw_intern_expression (Dwarf *dbg, bool other_byte_order, case DW_OP_const4s: case DW_OP_call4: + case DW_OP_GNU_parameter_ref: if (unlikely (data + 4 > end_data)) goto invalid; @@ -363,6 +364,8 @@ __libdw_intern_expression (Dwarf *dbg, bool other_byte_order, case DW_OP_plus_uconst: case DW_OP_regx: case DW_OP_piece: + case DW_OP_GNU_convert: + case DW_OP_GNU_reinterpret: /* XXX Check size. */ get_uleb128 (newloc->number, data); break; @@ -381,12 +384,14 @@ __libdw_intern_expression (Dwarf *dbg, bool other_byte_order, break; case DW_OP_bit_piece: + case DW_OP_GNU_regval_type: /* XXX Check size. */ get_uleb128 (newloc->number, data); get_uleb128 (newloc->number2, data); break; case DW_OP_implicit_value: + case DW_OP_GNU_entry_value: /* This cannot be used in a CFI expression. */ if (unlikely (dbg == NULL)) goto invalid; @@ -408,6 +413,27 @@ __libdw_intern_expression (Dwarf *dbg, bool other_byte_order, get_uleb128 (newloc->number2, data); /* Byte offset. */ break; + case DW_OP_GNU_deref_type: + if (unlikely (data >= end_data)) + goto invalid; + newloc->number = *data++; + get_uleb128 (newloc->number2, data); + break; + + case DW_OP_GNU_const_type: + /* XXX Check size. */ + get_uleb128 (newloc->number, data); + if (unlikely (data >= end_data)) + goto invalid; + newloc->number2 = *data++; /* Block length. */ + if (unlikely ((Dwarf_Word) (end_data - data) < newloc->number2)) + goto invalid; + /* The third operand is relative block offset: + newloc->number3 = data - block->data; + We don't support this at this point. */ + data += newloc->number2; /* Skip the block. */ + break; + default: goto invalid; } -- 1.7.6.5 _______________________________________________ elfutils-devel mailing list [email protected] https://lists.fedorahosted.org/mailman/listinfo/elfutils-devel
