From: Petr Machata Date: Tue, 9 Oct 2012 00:11:29 +0000 (+0200) Subject: Handle GNU extension opcodes in dwarf_getlocation X-Git-Tag: elfutils-0.156~79 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b5c0b037203eea0dc41f93900330522fe821eca9;p=thirdparty%2Felfutils.git Handle GNU extension opcodes in dwarf_getlocation --- diff --git a/libdw/ChangeLog b/libdw/ChangeLog index 7db34ea5d..0d35ca91a 100644 --- a/libdw/ChangeLog +++ b/libdw/ChangeLog @@ -1,3 +1,10 @@ +2012-10-09 Petr Machata + + * 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-10-08 Jan Kratochvil * cfi.c: New include system.h. diff --git a/libdw/dwarf_getlocation.c b/libdw/dwarf_getlocation.c index cda98a993..c3f3f477d 100644 --- a/libdw/dwarf_getlocation.c +++ b/libdw/dwarf_getlocation.c @@ -354,6 +354,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; @@ -378,6 +379,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; @@ -396,12 +399,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; @@ -423,6 +428,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; }