From: Ali Tamur Date: Sat, 30 Mar 2019 02:29:24 +0000 (-0700) Subject: Support for DW_OP_addrx and DW_FORM_addrx tags X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=336d760da60d93ce76c4560525f65339f3403914;p=binutils-gdb.git Support for DW_OP_addrx and DW_FORM_addrx tags 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. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index d99b954d0d3..7c5e4fb3cd4 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,24 @@ + +2019-03-27 Ali Tamur + + * 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 + 2019-04-22 Ali Tamur * MAINTAINERS (Write After Approval): Add self. diff --git a/gdb/dwarf2-frame.c b/gdb/dwarf2-frame.c index b1db1ede038..e2bf61bd309 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 e412e182c01..3bd9abc4401 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 c7cbf32d5e7..2a92a28908d 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 2b8aeee83ad..bd630ee0588 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 { @@ -2642,7 +2642,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 { @@ -4086,6 +4086,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 16bf2404a21..829b07f01ac 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. @@ -7229,7 +7230,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) @@ -9366,6 +9368,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: @@ -19279,6 +19282,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) { @@ -21360,13 +21364,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]))))) { @@ -21863,6 +21868,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; @@ -22839,6 +22845,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); @@ -23308,6 +23315,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; @@ -23912,6 +23920,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], @@ -24282,6 +24291,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: