summaryrefslogtreecommitdiff
path: root/gdb/testsuite/gdb.dwarf2
diff options
context:
space:
mode:
authorTom de Vries <tdevries@suse.de>2018-08-24 12:01:10 +0200
committerTom de Vries <tdevries@suse.de>2018-09-05 10:39:19 +0200
commite4a62c65fa8fe6a48b6ff564f45c1ac535f10f14 (patch)
treec4544b77a6215000f38d8c99cb929beb6d9e433e /gdb/testsuite/gdb.dwarf2
parent2b69821e70c7f648fa31f5d5110021a156158432 (diff)
downloadbinutils-gdb-e4a62c65fa8fe6a48b6ff564f45c1ac535f10f14.tar.gz
[gdb/exp] Handle DW_OP_GNU_variable_value refs to abstract dies
Consider a vla variable 'a' in function f1: ... <2><1a7>: Abbrev Number: 11 (DW_TAG_variable) <1a8> DW_AT_description : a <1aa> DW_AT_abstract_origin: <0x311> ... with abstract origin 'a': ... <2><311>: Abbrev Number: 3 (DW_TAG_variable) <312> DW_AT_name : a <317> DW_AT_type : <0x325> ... and inherited abstract vla type: ... <1><325>: Abbrev Number: 9 (DW_TAG_array_type) <326> DW_AT_type : <0x33a> <2><32e>: Abbrev Number: 10 (DW_TAG_subrange_type) <32f> DW_AT_type : <0x2ea> <333> DW_AT_upper_bound : 5 byte block: fd 1b 3 0 0 (DW_OP_GNU_variable_value: <0x31b>) ... where the upper bound refers to this artificial variable D.1922 without location attribute: ... <2><31b>: Abbrev Number: 8 (DW_TAG_variable) <31c> DW_AT_description : (indirect string, offset: 0x39a): D.1922 <320> DW_AT_type : <0x2ea> <324> DW_AT_artificial : 1 ... Currently, when we execute "p sizeof (a)" in f1, the upper bound is calculated by evaluating the DW_OP_GNU_variable_value expression referring to D.1922, but since that die doesn't have a location attribute, we get: ... value has been optimized out ... However, there's also artificial variable D.4283 that is sibling of vla variable 'a', has artificial variable D.1922 as abstract origin, and has a location attribute: ... <2><1ae>: Abbrev Number: 12 (DW_TAG_variable) <1af> DW_AT_description : (indirect string, offset: 0x1f8): D.4283 <1b3> DW_AT_abstract_origin: <0x31b> <1b7> DW_AT_location : 11 byte block: 75 1 8 20 24 8 20 26 31 1c 9f (DW_OP_breg5 (rdi):1; DW_OP_const1u: 32; DW_OP_shl; DW_OP_const1u: 32; DW_OP_shra; DW_OP_lit1; DW_OP_minus; DW_OP_stack_value) ... The intended behaviour for DW_OP_GNU_variable_value is to find a die that refers to D.1922 as abstract origin, has a location attribute and is 'in scope', so the expected behaviour is: ... $1 = 6 ... The 'in scope' concept can be thought of as variable D.1922 having name attribute "D.1922", and variable D.4283 inheriting that attribute, resulting in D.4283 being declared with name "D.1922" alongside vla a in f1, and when we lookup "DW_OP_GNU_variable_value D.1922", it should work as if we try to find the value of a variable named "D.1922" on the gdb command line using "p D.1922", and we should return the value of D.4283. This patch fixes the case described above, by: - adding a field abstract_to_concrete to struct dwarf2_per_objfile, - using that field to keep track of which concrete dies are instances of an abstract die, and - using that information when getting the value DW_OP_GNU_variable_value. Build and reg-tested on x86_64-linux. 2018-09-05 Tom de Vries <tdevries@suse.de> * dwarf2loc.c (sect_variable_value): Call indirect_synthetic_pointer with resolve_abstract_p == true. (indirect_synthetic_pointer): Add resolve_abstract_p parameter, defaulting to false. Propagate resolve_abstract_p to dwarf2_fetch_die_loc_sect_off. * dwarf2loc.h (dwarf2_fetch_die_loc_sect_off): Add resolve_abstract_p parameter, defaulting to false. * dwarf2read.c (read_variable): Add variable to abstract_to_concrete. (dwarf2_fetch_die_loc_sect_off): Add and handle resolve_abstract_p parameter. * dwarf2read.h (struct die_info): Forward-declare. (die_info_ptr): New typedef. (struct dwarf2_per_objfile): Add abstract_to_concrete field. * gdb.dwarf2/varval.exp: Add test.
Diffstat (limited to 'gdb/testsuite/gdb.dwarf2')
-rw-r--r--gdb/testsuite/gdb.dwarf2/varval.exp22
1 files changed, 21 insertions, 1 deletions
diff --git a/gdb/testsuite/gdb.dwarf2/varval.exp b/gdb/testsuite/gdb.dwarf2/varval.exp
index f4319ae7d25..400ad60873b 100644
--- a/gdb/testsuite/gdb.dwarf2/varval.exp
+++ b/gdb/testsuite/gdb.dwarf2/varval.exp
@@ -49,7 +49,9 @@ Dwarf::assemble ${asm_file} {
} {
declare_labels int_label ptr_label struct_label var_a_label \
var_b_label var_c_label var_p_label var_bad_label \
- varval_label var_s_label var_untyped_label
+ varval_label var_s_label var_untyped_label \
+ var_a_abstract_label var_a_concrete_label \
+ varval2_label
set int_size [get_sizeof "int" -1]
@@ -73,6 +75,11 @@ Dwarf::assemble ${asm_file} {
{DW_AT_location {DW_OP_addr [gdb_target_symbol "var_a"]} SPECIAL_expr}
}
+ var_a_abstract_label: DW_TAG_variable {
+ {DW_AT_type :${int_label}}
+ {DW_AT_external 1 DW_FORM_flag}
+ }
+
var_b_label: DW_TAG_variable {
{DW_AT_name "var_b"}
{DW_AT_type :${int_label}}
@@ -171,6 +178,18 @@ Dwarf::assemble ${asm_file} {
DW_OP_stack_value
} SPECIAL_expr}
}
+ varval2_label: DW_TAG_variable {
+ {DW_AT_name "varval2"}
+ {DW_AT_type :${int_label}}
+ {DW_AT_location {
+ DW_OP_GNU_variable_value ${var_a_abstract_label}
+ DW_OP_stack_value
+ } SPECIAL_expr}
+ }
+ var_a_concrete_label: DW_TAG_variable {
+ {DW_AT_abstract_origin :${var_a_abstract_label}}
+ {DW_AT_location {DW_OP_addr [gdb_target_symbol "var_a"]} SPECIAL_expr}
+ }
DW_TAG_variable {
{DW_AT_name "constval"}
{DW_AT_type :${int_label}}
@@ -255,6 +274,7 @@ if ![runto_main] {
}
gdb_test "print varval" "= 8"
+gdb_test "print varval2" "= 8"
gdb_test "print constval" "= 53"
gdb_test "print mixedval" "= 42"
gdb_test "print pointerval" "= \\(int \\*\\) $hex <var_b>"