From b5c0b037203eea0dc41f93900330522fe821eca9 Mon Sep 17 00:00:00 2001 From: Petr Machata Date: Tue, 9 Oct 2012 02:11:29 +0200 Subject: Handle GNU extension opcodes in dwarf_getlocation --- libdw/ChangeLog | 7 +++++++ libdw/dwarf_getlocation.c | 26 ++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/libdw/ChangeLog b/libdw/ChangeLog index 7db34ea5..0d35ca91 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 cda98a99..c3f3f477 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; } -- cgit v1.2.1