[PATCH v4 31/44] gdb, dwarf, ze: add DW_OP_INTEL_regval_bits
Markus Metzger <[email protected]>
| Newsgroups | gmane.comp.gnu.binutils,gmane.comp.gdb.patches |
|---|---|
| Message-ID | <[email protected]> |
Add support for a new DWARF expression proposed in https://dwarfstd.org/ShowIssue.php?issue=201007.1. Cc: <[email protected]> --- binutils/dwarf.c | 6 ++++++ gdb/dwarf2/expr.c | 37 +++++++++++++++++++++++++++++++++++++ gdb/dwarf2/expr.h | 5 +++++ gdb/dwarf2/loc.c | 2 ++ include/dwarf2.def | 4 ++++ 5 files changed, 54 insertions(+) diff --git a/binutils/dwarf.c b/binutils/dwarf.c index 829bcb761f7..bdeaf393572 100644 --- a/binutils/dwarf.c +++ b/binutils/dwarf.c @@ -1882,6 +1882,12 @@ decode_location_expression (unsigned char * data, printf ("DW_OP_PGI_omp_thread_num"); break; + /* Intel wide registers extension. */ + case DW_OP_INTEL_regval_bits: + SAFE_BYTE_GET_AND_INC (uvalue, data, 1, end); + printf ("DW_OP_INTEL_regval_bits: %lu", (unsigned long) uvalue); + break; + default: if (op >= DW_OP_lo_user && op <= DW_OP_hi_user) diff --git a/gdb/dwarf2/expr.c b/gdb/dwarf2/expr.c index 3a6b8f58199..03dae5bb064 100644 --- a/gdb/dwarf2/expr.c +++ b/gdb/dwarf2/expr.c @@ -946,6 +946,29 @@ dwarf_expr_context::deref (CORE_ADDR addr, int size, struct type *type) /* See expr.h. */ +void +dwarf_expr_context::read_reg (gdb_byte *buf, size_t bitoffset, + size_t bitsize, int dwregnum) +{ + struct gdbarch * const gdbarch = get_frame_arch (this->m_frame); + const int regnum = dwarf_reg_to_regnum_or_error (gdbarch, dwregnum); + + const int regsize = register_size (gdbarch, regnum); + if ((regsize * 8) < (bitsize + bitoffset)) + error (_("DWARF expr: error accessing %s[%" PRIu64 ":%" PRIu64 "]"), + gdbarch_register_name (gdbarch, regnum), + bitsize + bitoffset - 1, bitoffset); + + gdb_byte * const regbuf = (gdb_byte *) alloca (regsize); + get_frame_register (this->m_frame, regnum, + gdb::make_array_view (regbuf, regsize)); + + const enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); + copy_bitwise (buf, 0, regbuf, bitoffset, bitsize, byte_order); +} + +/* See expr.h. */ + void dwarf_expr_context::push_dwarf_reg_entry_value (call_site_parameter_kind kind, call_site_parameter_u kind_u, @@ -2459,6 +2482,20 @@ dwarf_expr_context::execute_stack_op (gdb::array_view<const gdb_byte> expr) } break; + case DW_OP_INTEL_regval_bits: + { + uint8_t size = *op_ptr++; + const ULONGEST off = value_as_long (fetch (0)); + pop (); + const LONGEST dwregnum = value_as_long (fetch (0)); + pop (); + + result = 0; + read_reg ((gdb_byte *) &result, off, size, dwregnum); + result_val = value_from_ulongest (address_type, result); + } + break; + case DW_OP_convert: case DW_OP_GNU_convert: case DW_OP_reinterpret: diff --git a/gdb/dwarf2/expr.h b/gdb/dwarf2/expr.h index 02b0e41f6fd..bc07ae4b95f 100644 --- a/gdb/dwarf2/expr.h +++ b/gdb/dwarf2/expr.h @@ -256,6 +256,11 @@ struct dwarf_expr_context memory reads to come from the passed-in buffer. */ void read_mem (gdb_byte *buf, CORE_ADDR addr, size_t length); + /* Read BITSIZE bits from the register indicated by the DWARF register + number DWREGNUM starting at bit BITOFFSET into BUF. */ + void read_reg (gdb_byte *buf, size_t bitoffset, size_t bitsize, + int dwregnum); + /* Deref ADDR with size SIZE and return a value of type TYPE. If TYPE == nullptr, defaults to this->address_type (). */ value *deref (CORE_ADDR addr, int size, struct type *type = nullptr); diff --git a/gdb/dwarf2/loc.c b/gdb/dwarf2/loc.c index 8e2b401ba34..d19695d96bd 100644 --- a/gdb/dwarf2/loc.c +++ b/gdb/dwarf2/loc.c @@ -2100,6 +2100,7 @@ dwarf2_get_symbol_read_needs (gdb::array_view<const gdb_byte> expr, case DW_OP_GNU_parameter_ref: case DW_OP_regval_type: case DW_OP_GNU_regval_type: + case DW_OP_INTEL_regval_bits: symbol_needs = SYMBOL_NEEDS_FRAME; break; @@ -3348,6 +3349,7 @@ disassemble_dwarf_expression (struct ui_file *stream, break; case DW_OP_const1u: + case DW_OP_INTEL_regval_bits: ul = extract_unsigned_integer (data, 1, gdbarch_byte_order (arch)); data += 1; gdb_printf (stream, " %s", pulongest (ul)); diff --git a/include/dwarf2.def b/include/dwarf2.def index 22b4b7d5b5a..056bb51a280 100644 --- a/include/dwarf2.def +++ b/include/dwarf2.def @@ -699,6 +699,10 @@ DW_OP (DW_OP_GNU_const_index, 0xfc) /* The GNU variable value extension. See http://dwarfstd.org/ShowIssue.php?issue=161109.2 . */ DW_OP (DW_OP_GNU_variable_value, 0xfd) +/* https://dwarfstd.org/ShowIssue.php?issue=201007.1 + + The DW_OP_regval_bits operation extracts a value from a register. */ +DW_OP (DW_OP_INTEL_regval_bits, 0xfe) /* HP extensions. */ DW_OP_DUP (DW_OP_HP_unknown, 0xe0) /* Ouch, the same as GNU_push_tls_address. */ DW_OP (DW_OP_HP_is_value, 0xe1) -- 2.43.0 ________________________________________ Intel Deutschland GmbH Registered Address: Dornacher Strasse 1, 85622 Feldkirchen, Germany Tel: +49 (89) 99143-0 www.intel.de Managing Directors: Candice Moore, Jeffrey Schneiderman, Ramachandran Sitaraman Chairperson of the Supervisory Board: Sonja Pierer Registered Seat: Munich Commercial Register B: Amtsgericht Munich HRB 186928 This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies.