This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[PATCH] Support for DW_OP_addrx and DW_FORM_addrx tags
- From: "Ali Tamur via gdb-patches" <gdb-patches at sourceware dot org>
- To: gdb-patches at sourceware dot org
- Date: Wed, 3 Apr 2019 17:50:54 -0700
- Subject: [PATCH] Support for DW_OP_addrx and DW_FORM_addrx tags
- Reply-to: Ali Tamur <tamur at google dot com>
DW_OP_addrx is the new name of DW_OP_GNU_addr_index, and DW_FORM_addrx
is the name of DW_FORM_addr_index in the Dwarf 5 standard. This is a small
step towards supporting Dwarf 5 in gdb.
Note: I could not find any tests specifically for *_GNU_addr_index, and
I did not add any new tests, please advise.
gdb/ChangeLog:
2019-04-03 Ali Tamur <tamur@google.com>
* dwarf2-frame.c(dwarf_expr_executor::get_addr_index): Update
comment
* dwarf2expr.c(dwarf_expr_context::execute_stack_op): Add
DW_OP_addrx
* dwarf2expr.h(dwarf_expr_context::offset): Update comment
(dwarf_expr_context::get_addr_index): Likewise
* dwarf2loc.c(dwarf_evaluate_loc_desc::get_addr_index): Likewise
(symbol_needs_eval_context::get_addr_index): Likewise
(disassemble_dwarf_expression): Add DW_OP_addrx
* dwarf2read.c(attr_value_as_address): Add DW_FORM_addrx
(read_cutu_die_from_dwo): Update comment
(skip_one_die): Add DW_FORM_addrx
(read_attribute_value): Likewise
(var_decode_location): Add DW_OP_addrx
(dwarf2_const_value_attr): Add DW_FORM_addrx
(dump_die_shallow): Likewise
(dwarf2_fetch_constant_bytes): Likewise
(decode_locdesc): Add DW_OP_addrx
(skip_form_bytes): Add DW_FORM_addrx
---
diff --git a/gdb/dwarf2-frame.c b/gdb/dwarf2-frame.c
index 178ac44ecb..8223050d2c 100644
--- a/gdb/dwarf2-frame.c
+++ b/gdb/dwarf2-frame.c
@@ -290,7 +290,7 @@ class dwarf_expr_executor : public dwarf_expr_context
CORE_ADDR get_addr_index (unsigned int index) override
{
- invalid ("DW_OP_GNU_addr_index");
+ invalid ("DW_OP_addrx or DW_OP_GNU_addr_index");
}
private:
diff --git a/gdb/dwarf2expr.c b/gdb/dwarf2expr.c
index e412e182c0..3bd9abc440 100644
--- a/gdb/dwarf2expr.c
+++ b/gdb/dwarf2expr.c
@@ -634,6 +634,7 @@ dwarf_expr_context::execute_stack_op (const gdb_byte
*op_ptr,
result_val = value_from_ulongest (address_type, result);
break;
+ case DW_OP_addrx:
case DW_OP_GNU_addr_index:
op_ptr = safe_read_uleb128 (op_ptr, op_end, &uoffset);
result = this->get_addr_index (uoffset);
diff --git a/gdb/dwarf2expr.h b/gdb/dwarf2expr.h
index c7cbf32d5e..4f6231faea 100644
--- a/gdb/dwarf2expr.h
+++ b/gdb/dwarf2expr.h
@@ -139,7 +139,8 @@ struct dwarf_expr_context
context and operations depending on DW_FORM_ref_addr are not
allowed. */
int ref_addr_size;
- /* Offset used to relocate DW_OP_addr and DW_OP_GNU_addr_index
arguments. */
+ /* Offset used to relocate DW_OP_addr, DW_OP_addrx, and
DW_OP_GNU_addr_index
+ arguments. */
CORE_ADDR offset;
/* The current depth of dwarf expression recursion, via DW_OP_call*,
@@ -242,7 +243,7 @@ struct dwarf_expr_context
union call_site_parameter_u kind_u,
int deref_size) = 0;
- /* Return the address indexed by DW_OP_GNU_addr_index.
+ /* Return the address indexed by DW_OP_addrx or DW_OP_GNU_addr_index.
This can throw an exception if the index is out of range. */
virtual CORE_ADDR get_addr_index (unsigned int index) = 0;
diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c
index 29d289b4d0..01d8cbfc63 100644
--- a/gdb/dwarf2loc.c
+++ b/gdb/dwarf2loc.c
@@ -636,7 +636,7 @@ class dwarf_evaluate_loc_desc : public
dwarf_expr_context
}
/* Callback function for dwarf2_evaluate_loc_desc.
- Fetch the address indexed by DW_OP_GNU_addr_index. */
+ Fetch the address indexed by DW_OP_addrx or DW_OP_GNU_addr_index. */
CORE_ADDR get_addr_index (unsigned int index) override
{
@@ -2645,7 +2645,7 @@ class symbol_needs_eval_context : public
dwarf_expr_context
push_address (0, 0);
}
- /* DW_OP_GNU_addr_index doesn't require a frame. */
+ /* DW_OP_addrx and DW_OP_GNU_addr_index doesn't require a frame. */
CORE_ADDR get_addr_index (unsigned int index) override
{
@@ -4089,6 +4089,7 @@ disassemble_dwarf_expression (struct ui_file *stream,
fprintf_filtered (stream, " offset %s", phex_nz (ul, 4));
break;
+ case DW_OP_addrx:
case DW_OP_GNU_addr_index:
data = safe_read_uleb128 (data, end, &ul);
ul = dwarf2_read_addr_index (per_cu, ul);
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 658c86264b..1aac47174d 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -2134,7 +2134,8 @@ attr_value_as_address (struct attribute *attr)
{
CORE_ADDR addr;
- if (attr->form != DW_FORM_addr && attr->form != DW_FORM_GNU_addr_index)
+ if (attr->form != DW_FORM_addr && attr->form != DW_FORM_addrx
+ && attr->form != DW_FORM_GNU_addr_index)
{
/* Aside from a few clearly defined exceptions, attributes that
contain an address must always be in DW_FORM_addr form.
@@ -7230,7 +7231,8 @@ read_cutu_die_from_dwo (struct dwarf2_per_cu_data
*this_cu,
comp_dir = dwarf2_attr (stub_comp_unit_die, DW_AT_comp_dir, cu);
/* There should be a DW_AT_addr_base attribute here (if needed).
- We need the value before we can process DW_FORM_GNU_addr_index. */
+ We need the value before we can process DW_FORM_GNU_addr_index or
+ DW_FORM_addrx. */
cu->addr_base = 0;
attr = dwarf2_attr (stub_comp_unit_die, DW_AT_GNU_addr_base, cu);
if (attr)
@@ -9367,6 +9369,7 @@ skip_one_die (const struct die_reader_specs *reader,
const gdb_byte *info_ptr,
case DW_FORM_block4:
info_ptr += 4 + read_4_bytes (abfd, info_ptr);
break;
+ case DW_FORM_addrx:
case DW_FORM_sdata:
case DW_FORM_udata:
case DW_FORM_ref_udata:
@@ -19217,6 +19220,7 @@ read_attribute_value (const struct die_reader_specs
*reader,
case DW_FORM_implicit_const:
DW_SND (attr) = implicit_const;
break;
+ case DW_FORM_addrx:
case DW_FORM_GNU_addr_index:
if (reader->dwo_file == NULL)
{
@@ -21298,13 +21302,14 @@ var_decode_location (struct attribute *attr,
struct symbol *sym,
/* Handle one degenerate form of location expression specially, to
preserve GDB's previous behavior when section offsets are
- specified. If this is just a DW_OP_addr or DW_OP_GNU_addr_index
- then mark this symbol as LOC_STATIC. */
+ specified. If this is just a DW_OP_addr, DW_OP_addrx or
+ DW_OP_GNU_addr_index then mark this symbol as LOC_STATIC. */
if (attr_form_is_block (attr)
&& ((DW_BLOCK (attr)->data[0] == DW_OP_addr
&& DW_BLOCK (attr)->size == 1 + cu_header->addr_size)
- || (DW_BLOCK (attr)->data[0] == DW_OP_GNU_addr_index
+ || ((DW_BLOCK (attr)->data[0] == DW_OP_GNU_addr_index
+ || DW_BLOCK (attr)->data[0] == DW_OP_addrx)
&& (DW_BLOCK (attr)->size
== 1 + leb128_size (&DW_BLOCK (attr)->data[1])))))
{
@@ -21801,6 +21806,7 @@ dwarf2_const_value_attr (const struct attribute
*attr, struct type *type,
switch (attr->form)
{
case DW_FORM_addr:
+ case DW_FORM_addrx:
case DW_FORM_GNU_addr_index:
{
gdb_byte *data;
@@ -22777,6 +22783,7 @@ dump_die_shallow (struct ui_file *f, int indent,
struct die_info *die)
switch (die->attrs[i].form)
{
case DW_FORM_addr:
+ case DW_FORM_addrx:
case DW_FORM_GNU_addr_index:
fprintf_unfiltered (f, "address: ");
fputs_filtered (hex_string (DW_ADDR (&die->attrs[i])), f);
@@ -23246,6 +23253,7 @@ dwarf2_fetch_constant_bytes (sect_offset sect_off,
switch (attr->form)
{
case DW_FORM_addr:
+ case DW_FORM_addrx:
case DW_FORM_GNU_addr_index:
{
gdb_byte *tem;
@@ -23850,6 +23858,7 @@ decode_locdesc (struct dwarf_block *blk, struct
dwarf2_cu *cu)
case DW_OP_GNU_uninit:
break;
+ case DW_OP_addrx:
case DW_OP_GNU_addr_index:
case DW_OP_GNU_const_index:
stack[++stacki] = read_addr_index_from_leb128 (cu, &data[i],
@@ -24220,6 +24229,7 @@ skip_form_bytes (bfd *abfd, const gdb_byte *bytes,
const gdb_byte *buffer_end,
bytes += 4 + read_4_bytes (abfd, bytes);
break;
+ case DW_FORM_addrx:
case DW_FORM_sdata:
case DW_FORM_udata:
case DW_FORM_GNU_addr_index: