diff options
author | Tom Tromey <tromey@adacore.com> | 2020-07-28 10:55:43 -0600 |
---|---|---|
committer | Tom Tromey <tromey@adacore.com> | 2020-07-28 10:55:43 -0600 |
commit | 4888741a22e1ab88b53d92f1c915ccd2bacf6280 (patch) | |
tree | 3c87d2dd8673f338d2c3d2cb8b74fd49f0e33d99 | |
parent | 4d46f40270b16070398412bc02a512143380814c (diff) | |
download | gdb-4888741a22e1ab88b53d92f1c915ccd2bacf6280.zip gdb-4888741a22e1ab88b53d92f1c915ccd2bacf6280.tar.gz gdb-4888741a22e1ab88b53d92f1c915ccd2bacf6280.tar.bz2 |
Fix bug in DW_OP_GNU_variable_value evaluation
A modified version of the gnat compiler (TBH I don't know if the
modifications are relevant to this bug or not, but I figured I'd
mention it) can generate a DWARF location expression like:
<1><1201>: Abbrev Number: 3 (DW_TAG_dwarf_procedure)
<1202> DW_AT_location : 32 byte block: 12 31 29 28 4 0 30 2f 12 0 14 30 2d 28 4 0 14 2f 1 0 30 34 1e 23 3 9 fc 1a 16 13 16 13 (DW_OP_dup; DW_OP_lit1; DW_OP_eq; DW_OP_bra: 4; DW_OP_lit0; DW_OP_skip: 18; DW_OP_over; DW_OP_lit0; DW_OP_lt; DW_OP_bra: 4; DW_OP_over; DW_OP_skip: 1; DW_OP_lit0; DW_OP_lit4; DW_OP_mul; DW_OP_plus_uconst: 3; DW_OP_const1s: -4; DW_OP_and; DW_OP_swap; DW_OP_drop; DW_OP_swap; DW_OP_drop)
<2><1279>: Abbrev Number: 9 (DW_TAG_structure_type)
<127a> DW_AT_name : (indirect string, offset: 0x1a5a): p__logical_channel_t
<127e> DW_AT_byte_size : 18 byte block: fd 43 12 0 0 97 94 1 99 34 0 0 0 23 7 9 fc 1a (DW_OP_GNU_variable_value: <0x1243>; DW_OP_push_object_address; DW_OP_deref_size: 1; DW_OP_call4: <0x1201>; DW_OP_plus_uconst: 7; DW_OP_const1s: -4; DW_OP_and)
When evaluated, this gives:
Incompatible types on DWARF stack
In Jakub's original message about DW_OP_GNU_variable_value:
https://gcc.gnu.org/legacy-ml/gcc-patches/2017-02/msg01499.html
.. it says:
The intended behavior is that the debug info consumer computes the
value of that referenced variable at the current PC, and if it can
compute it and pushes the value as a generic type integer into the
DWARF stack
Instead, gdb is using the variable's type -- but this fails with some
operations, like DW_OP_and, which expect the types to match.
I believe what was intended was for the value to be cast to the DWARF
"untyped" type, which is what this patch implements. This patch also
updates varval.exp to exhibit the bug.
gdb/ChangeLog
2020-07-28 Tom Tromey <tromey@adacore.com>
* dwarf2/expr.c (dwarf_expr_context::execute_stack_op)
<DW_OP_GNU_variable_value>: Cast to address type.
gdb/testsuite/ChangeLog
2020-07-28 Tom Tromey <tromey@adacore.com>
* gdb.dwarf2/varval.exp (setup_exec): Add 'or' instruction to
'varval' location.
-rw-r--r-- | gdb/ChangeLog | 5 | ||||
-rw-r--r-- | gdb/dwarf2/expr.c | 3 | ||||
-rw-r--r-- | gdb/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gdb/testsuite/gdb.dwarf2/varval.exp | 2 |
4 files changed, 14 insertions, 1 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index bc05eea..e10f89f 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,8 @@ +2020-07-28 Tom Tromey <tromey@adacore.com> + + * dwarf2/expr.c (dwarf_expr_context::execute_stack_op) + <DW_OP_GNU_variable_value>: Cast to address type. + 2020-07-28 Kamil Rytarowski <n54@gmx.com> * nbsd-nat.h (nbsd_nat_target::xfer_partial): New declaration. diff --git a/gdb/dwarf2/expr.c b/gdb/dwarf2/expr.c index 91ac4c0..9bf7413 100644 --- a/gdb/dwarf2/expr.c +++ b/gdb/dwarf2/expr.c @@ -1270,7 +1270,8 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr, this->ref_addr_size, byte_order); op_ptr += this->ref_addr_size; - result_val = this->dwarf_variable_value (sect_off); + result_val = value_cast (address_type, + this->dwarf_variable_value (sect_off)); } break; diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 5ae2588..40283fa 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2020-07-28 Tom Tromey <tromey@adacore.com> + + * gdb.dwarf2/varval.exp (setup_exec): Add 'or' instruction to + 'varval' location. + 2020-07-28 Andrew Burgess <andrew.burgess@embecosm.com> * gdb.python/py-unwind.py: Update to make use of a register diff --git a/gdb/testsuite/gdb.dwarf2/varval.exp b/gdb/testsuite/gdb.dwarf2/varval.exp index 69790e7..cb8836e 100644 --- a/gdb/testsuite/gdb.dwarf2/varval.exp +++ b/gdb/testsuite/gdb.dwarf2/varval.exp @@ -207,6 +207,8 @@ proc setup_exec { arg_bad } { {DW_AT_type :${int_label}} {DW_AT_location { DW_OP_GNU_variable_value ${var_a_label} + DW_OP_const1s 0 + DW_OP_or DW_OP_stack_value } SPECIAL_expr} } |