summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Tromey <tromey@adacore.com>2020-07-28 10:55:43 -0600
committerTom Tromey <tromey@adacore.com>2020-07-28 10:55:43 -0600
commit4888741a22e1ab88b53d92f1c915ccd2bacf6280 (patch)
tree3c87d2dd8673f338d2c3d2cb8b74fd49f0e33d99
parent4d46f40270b16070398412bc02a512143380814c (diff)
downloadbinutils-gdb-4888741a22e1ab88b53d92f1c915ccd2bacf6280.tar.gz
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/ChangeLog5
-rw-r--r--gdb/dwarf2/expr.c3
-rw-r--r--gdb/testsuite/ChangeLog5
-rw-r--r--gdb/testsuite/gdb.dwarf2/varval.exp2
4 files changed, 14 insertions, 1 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index bc05eeaea30..e10f89fc2d6 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 91ac4c0d9d2..9bf74139d2d 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 5ae258820e6..40283fa5326 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 69790e7370e..cb8836e2b24 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}
}