summaryrefslogtreecommitdiffstats
path: root/libdw
diff options
context:
space:
mode:
authorMark Wielaard <[email protected]>2017-11-15 12:13:38 +0100
committerMark Wielaard <[email protected]>2018-03-11 16:34:02 +0100
commit86fbef9bcadb98272e247a005fdc8d7fd0701179 (patch)
tree713bf5f761e9436e5c790fbad1c9f6c57ae73eeb /libdw
parent06263dda990be6778a4beb33481cfd39ce60c623 (diff)
libdw: Add new DWARF5 Dwarf expression operations.
DW_OP_implicit_pointer, DW_OP_entry_value, DW_OP_const_type, DW_OP_regval_type, DW_OP_deref_type, DW_OP_xderef_type, DW_OP_convert and OP_reinterpret are implemented like their pre-DWARF5 GNU variants. DW_OP_xderef_type is implemented as a (non-CU relative) variant of DW_OP_deref_type. DW_OP_addrx and DW_OP_constx are recognized but not interpreted yet. Signed-off-by: Mark Wielaard <[email protected]>
Diffstat (limited to 'libdw')
-rw-r--r--libdw/ChangeLog19
-rw-r--r--libdw/dwarf.h11
-rw-r--r--libdw/dwarf_getlocation.c12
-rw-r--r--libdw/dwarf_getlocation_attr.c5
-rw-r--r--libdw/dwarf_getlocation_die.c12
-rw-r--r--libdw/dwarf_getlocation_implicit_pointer.c5
6 files changed, 59 insertions, 5 deletions
diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index 4c3587b4..f552644d 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,22 @@
+2018-03-06 Mark Wielaard <[email protected]>
+
+ * dwarf.h: Add DW_OP_implicit_pointer, DW_OP_addrx, DW_OP_constx,
+ DW_OP_entry_value, DW_OP_const_type, DW_OP_regval_type,
+ DW_OP_deref_type, DW_OP_xderef_type, DW_OP_convert and
+ DW_OP_reinterpret.
+ * dwarf_getlocation.c (__libdw_intern_expression): Handle
+ DW_OP_convert, DW_OP_reinterpret, DW_OP_addrx, DW_OP_constx,
+ DW_OP_regval_type, DW_OP_entry_value, DW_OP_implicit_pointer,
+ DW_OP_deref_type, DW_OP_xderef_type and DW_OP_const_type.
+ * dwarf_getlocation_attr.c (dwarf_getlocation_attr): Handle
+ DW_OP_entry_value, DW_OP_const_type and DW_OP_implicit_pointer.
+ * dwarf_getlocation_die.c (dwarf_getlocation_die): Handle
+ DW_OP_implicit_pointer, DW_OP_convert, DW_OP_reinterpret,
+ DW_OP_const_type, DW_OP_regval_type, DW_OP_deref_type and
+ DW_OP_xderef_type.
+ * dwarf_getlocation_implicit_pointer.c
+ (dwarf_getlocation_implicit_pointer): Handle DW_OP_implicit_pointer.
+
2018-03-01 Mark Wielaard <[email protected]>
* dwarf.h: Add DW_AT_GNU_locviews and DW_AT_GNU_entry_view.
diff --git a/libdw/dwarf.h b/libdw/dwarf.h
index d53a30d8..99cc1128 100644
--- a/libdw/dwarf.h
+++ b/libdw/dwarf.h
@@ -567,6 +567,17 @@ enum
DW_OP_implicit_value = 0x9e, /* DW_FORM_block follows opcode. */
DW_OP_stack_value = 0x9f, /* No operands, special like DW_OP_piece. */
+ DW_OP_implicit_pointer = 0xa0,
+ DW_OP_addrx = 0xa1,
+ DW_OP_constx = 0xa2,
+ DW_OP_entry_value = 0xa3,
+ DW_OP_const_type = 0xa4,
+ DW_OP_regval_type = 0xa5,
+ DW_OP_deref_type = 0xa6,
+ DW_OP_xderef_type = 0xa7,
+ DW_OP_convert = 0xa8,
+ DW_OP_reinterpret = 0xa9,
+
/* GNU extensions. */
DW_OP_GNU_push_tls_address = 0xe0,
DW_OP_GNU_uninit = 0xf0,
diff --git a/libdw/dwarf_getlocation.c b/libdw/dwarf_getlocation.c
index 86a9ae7f..0fcf9502 100644
--- a/libdw/dwarf_getlocation.c
+++ b/libdw/dwarf_getlocation.c
@@ -1,5 +1,5 @@
/* Return location expression list.
- Copyright (C) 2000-2010, 2013-2015 Red Hat, Inc.
+ Copyright (C) 2000-2010, 2013-2015, 2017 Red Hat, Inc.
This file is part of elfutils.
Written by Ulrich Drepper <[email protected]>, 2000.
@@ -452,8 +452,12 @@ __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_convert:
case DW_OP_GNU_convert:
+ case DW_OP_reinterpret:
case DW_OP_GNU_reinterpret:
+ case DW_OP_addrx:
+ case DW_OP_constx:
get_uleb128 (newloc->number, data, end_data);
break;
@@ -471,6 +475,7 @@ __libdw_intern_expression (Dwarf *dbg, bool other_byte_order,
break;
case DW_OP_bit_piece:
+ case DW_OP_regval_type:
case DW_OP_GNU_regval_type:
get_uleb128 (newloc->number, data, end_data);
if (unlikely (data >= end_data))
@@ -479,6 +484,7 @@ __libdw_intern_expression (Dwarf *dbg, bool other_byte_order,
break;
case DW_OP_implicit_value:
+ case DW_OP_entry_value:
case DW_OP_GNU_entry_value:
/* This cannot be used in a CFI expression. */
if (unlikely (dbg == NULL))
@@ -492,6 +498,7 @@ __libdw_intern_expression (Dwarf *dbg, bool other_byte_order,
data += newloc->number; /* Skip the block. */
break;
+ case DW_OP_implicit_pointer:
case DW_OP_GNU_implicit_pointer:
/* DW_FORM_ref_addr, depends on offset size of CU. */
if (dbg == NULL || __libdw_read_offset_inc (dbg, sec_index, &data,
@@ -504,13 +511,16 @@ __libdw_intern_expression (Dwarf *dbg, bool other_byte_order,
get_uleb128 (newloc->number2, data, end_data); /* Byte offset. */
break;
+ case DW_OP_deref_type:
case DW_OP_GNU_deref_type:
+ case DW_OP_xderef_type:
if (unlikely (data + 1 >= end_data))
goto invalid;
newloc->number = *data++;
get_uleb128 (newloc->number2, data, end_data);
break;
+ case DW_OP_const_type:
case DW_OP_GNU_const_type:
{
size_t size;
diff --git a/libdw/dwarf_getlocation_attr.c b/libdw/dwarf_getlocation_attr.c
index e4dd7089..162330f6 100644
--- a/libdw/dwarf_getlocation_attr.c
+++ b/libdw/dwarf_getlocation_attr.c
@@ -1,5 +1,5 @@
/* Return DWARF attribute associated with a location expression op.
- Copyright (C) 2013, 2014 Red Hat, Inc.
+ Copyright (C) 2013, 2014, 2017 Red Hat, Inc.
This file is part of elfutils.
This file is free software; you can redistribute it and/or modify
@@ -67,6 +67,7 @@ dwarf_getlocation_attr (Dwarf_Attribute *attr, const Dwarf_Op *op, Dwarf_Attribu
result->cu = attr_form_cu (attr);
break;
+ case DW_OP_entry_value:
case DW_OP_GNU_entry_value:
result->code = DW_AT_location;
result->form = DW_FORM_exprloc;
@@ -74,6 +75,7 @@ dwarf_getlocation_attr (Dwarf_Attribute *attr, const Dwarf_Op *op, Dwarf_Attribu
result->cu = attr_form_cu (attr);
break;
+ case DW_OP_const_type:
case DW_OP_GNU_const_type:
result->code = DW_AT_const_value;
result->form = DW_FORM_block1;
@@ -96,6 +98,7 @@ dwarf_getlocation_attr (Dwarf_Attribute *attr, const Dwarf_Op *op, Dwarf_Attribu
}
break;
+ case DW_OP_implicit_pointer:
case DW_OP_GNU_implicit_pointer:
case DW_OP_GNU_variable_value:
{
diff --git a/libdw/dwarf_getlocation_die.c b/libdw/dwarf_getlocation_die.c
index a07031ed..00369a9c 100644
--- a/libdw/dwarf_getlocation_die.c
+++ b/libdw/dwarf_getlocation_die.c
@@ -1,5 +1,5 @@
/* Return DIE associated with a location expression op.
- Copyright (C) 2013 Red Hat, Inc.
+ Copyright (C) 2013, 2017 Red Hat, Inc.
This file is part of elfutils.
This file is free software; you can redistribute it and/or modify
@@ -43,6 +43,7 @@ dwarf_getlocation_die (Dwarf_Attribute *attr, const Dwarf_Op *op,
Dwarf_Off dieoff;
switch (op->atom)
{
+ case DW_OP_implicit_pointer:
case DW_OP_GNU_implicit_pointer:
case DW_OP_call_ref:
case DW_OP_GNU_variable_value:
@@ -50,19 +51,28 @@ dwarf_getlocation_die (Dwarf_Attribute *attr, const Dwarf_Op *op,
break;
case DW_OP_GNU_parameter_ref:
+ case DW_OP_convert:
case DW_OP_GNU_convert:
+ case DW_OP_reinterpret:
case DW_OP_GNU_reinterpret:
+ case DW_OP_const_type:
case DW_OP_GNU_const_type:
case DW_OP_call2:
case DW_OP_call4:
dieoff = attr->cu->start + op->number;
break;
+ case DW_OP_regval_type:
case DW_OP_GNU_regval_type:
+ case DW_OP_deref_type:
case DW_OP_GNU_deref_type:
dieoff = attr->cu->start + op->number2;
break;
+ case DW_OP_xderef_type:
+ dieoff = op->number2;
+ break;
+
default:
__libdw_seterrno (DWARF_E_INVALID_ACCESS);
return -1;
diff --git a/libdw/dwarf_getlocation_implicit_pointer.c b/libdw/dwarf_getlocation_implicit_pointer.c
index b704c706..0c1cd00a 100644
--- a/libdw/dwarf_getlocation_implicit_pointer.c
+++ b/libdw/dwarf_getlocation_implicit_pointer.c
@@ -1,5 +1,5 @@
/* Return associated attribute for DW_OP_GNU_implicit_pointer.
- Copyright (C) 2010 Red Hat, Inc.
+ Copyright (C) 2010, 2017 Red Hat, Inc.
This file is part of elfutils.
This file is free software; you can redistribute it and/or modify
@@ -55,7 +55,8 @@ dwarf_getlocation_implicit_pointer (Dwarf_Attribute *attr, const Dwarf_Op *op,
if (attr == NULL)
return -1;
- if (unlikely (op->atom != DW_OP_GNU_implicit_pointer))
+ if (unlikely (op->atom != DW_OP_implicit_pointer
+ && op->atom != DW_OP_GNU_implicit_pointer))
{
__libdw_seterrno (DWARF_E_INVALID_ACCESS);
return -1;