summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPetr Machata <pmachata@redhat.com>2012-10-09 02:11:29 +0200
committerPetr Machata <pmachata@redhat.com>2012-10-10 15:08:38 +0200
commitb5c0b037203eea0dc41f93900330522fe821eca9 (patch)
treed062b66ac6481aaf5088a7b30e6e4c95151fdda4
parent6a1ed3836d644086a823138c405b48edd38479a3 (diff)
downloadelfutils-b5c0b037203eea0dc41f93900330522fe821eca9.tar.gz
Handle GNU extension opcodes in dwarf_getlocation
-rw-r--r--libdw/ChangeLog7
-rw-r--r--libdw/dwarf_getlocation.c26
2 files changed, 33 insertions, 0 deletions
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 <pmachata@redhat.com>
+
+ * 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 <jan.kratochvil@redhat.com>
* 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;
}