From a6b786da4e3353bf634ec7d9c7bffbd7569e73c6 Mon Sep 17 00:00:00 2001 From: Kevin Buettner Date: Mon, 30 Jul 2018 15:41:56 -0700 Subject: Add support for DW_OP_GNU_variable_value This patch adds support for DW_OP_GNU_variable_value to GDB. Jakub Jelinek provides a fairly expansive discussion of this DWARF expression opcode in his GCC patch... https://gcc.gnu.org/ml/gcc-patches/2017-02/msg01499.html It has also been proposed for addition to the DWARF Standard: http://www.dwarfstd.org/ShowIssue.php?issue=161109.2 If compiled with a suitable version of GCC, the test case associated with GCC Bug 77589 uses DW_OP_GNU_variable_value in a DW_AT_byte_stride expression. Here's a link to the bug: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77589 This is what the DWARF looks like. Look at the last line, which has the DW_AT_byte_stride expression: <2>: Abbrev Number: 12 (DW_TAG_variable) DW_AT_name : (indirect string, offset: 0x115): span.0 DW_AT_type : <0x2e> DW_AT_artificial : 1 DW_AT_location : 3 byte block: 91 b0 7f (DW_OP_fbreg: -80) ... <2><178>: Abbrev Number: 18 (DW_TAG_subrange_type) <179> DW_AT_lower_bound : 4 byte block: 97 23 20 6 (DW_OP_push_object_address; DW_OP_plus_uconst: 32; DW_OP_deref) <17e> DW_AT_upper_bound : 4 byte block: 97 23 28 6 (DW_OP_push_object_address; DW_OP_plus_uconst: 40; DW_OP_deref) <183> DW_AT_byte_stride : 10 byte block: 97 23 18 6 fd e1 0 0 0 1e (DW_OP_push_object_address; DW_OP_plus_uconst: 24; DW_OP_deref; DW_OP_GNU_variable_value: <0xe1>; DW_OP_mul) A patch to readelf, which I'm also submitting, is required to do this decoding. I found that GDB gave me the correct answer for "p c40pt(2)" once I (correctly) implemented DW_OP_GNU_variable_value. I also have test case (later in this series) which uses the DWARF assembler and, therefore, do not rely on having a compiler with this support. gdb/ChangeLog: * dwarf2expr.h (struct dwarf_expr_context): Add virtual method dwarf_variable_value. * dwarf2-frame.c (class dwarf_expr_executor): Add override for dwarf_variable_value. * dwarf2loc.c (class dwarf_evaluate_loc_desc): Likewise. (class symbol_needs_eval_context): Likewise. (indirect_synthetic_pointer): Add forward declaration. (sect_variable_value): New function. (dwarf2_compile_expr_to_ax): Add case for DW_OP_GNU_variable_value. * dwarf2expr.c (dwarf_expr_context::execute_stack_op): Add case for DW_OP_GNU_variable_value. --- gdb/dwarf2expr.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'gdb/dwarf2expr.h') diff --git a/gdb/dwarf2expr.h b/gdb/dwarf2expr.h index c746bfe..a98edc9 100644 --- a/gdb/dwarf2expr.h +++ b/gdb/dwarf2expr.h @@ -221,6 +221,9 @@ struct dwarf_expr_context subroutine. */ virtual void dwarf_call (cu_offset die_cu_off) = 0; + /* Execute "variable value" operation on the DIE at SECT_OFF. */ + virtual struct value *dwarf_variable_value (sect_offset sect_off) = 0; + /* Return the base type given by the indicated DIE at DIE_CU_OFF. This can throw an exception if the DIE is invalid or does not represent a base type. SIZE is non-zero if this function should -- cgit v1.1