Add support for DW_OP_GNU_variable_value
authorKevin Buettner <kevinb@redhat.com>
Mon, 30 Jul 2018 22:41:56 +0000 (15:41 -0700)
committerKevin Buettner <kevinb@redhat.com>
Sat, 18 Aug 2018 19:57:59 +0000 (12:57 -0700)
commita6b786da4e3353bf634ec7d9c7bffbd7569e73c6
tree10386bffdca5e61d5d05ff6379b5880319275dd4
parentf41078422a4381d4943f36aa1ef95b1d7c85ee7e
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><e1>: Abbrev Number: 12 (DW_TAG_variable)
    <e2>   DW_AT_name        : (indirect string, offset: 0x115): span.0
    <e6>   DW_AT_type        : <0x2e>
    <ea>   DW_AT_artificial  : 1
    <ea>   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/ChangeLog
gdb/dwarf2-frame.c
gdb/dwarf2expr.c
gdb/dwarf2expr.h
gdb/dwarf2loc.c