aboutsummaryrefslogtreecommitdiff
path: root/gdb/dwarf2
diff options
context:
space:
mode:
authorTom de Vries <tdevries@suse.de>2020-11-30 13:50:26 +0100
committerTom de Vries <tdevries@suse.de>2020-11-30 13:50:26 +0100
commit7ce05d212d1b825dc58d2b0d390417f2c134cd98 (patch)
treee0ea14b8917a8f330f604c8847cf4d18218bf73b /gdb/dwarf2
parent61049d1ee59905589b2ad3f8140a2582e01add7a (diff)
downloadgdb-7ce05d212d1b825dc58d2b0d390417f2c134cd98.zip
gdb-7ce05d212d1b825dc58d2b0d390417f2c134cd98.tar.gz
gdb-7ce05d212d1b825dc58d2b0d390417f2c134cd98.tar.bz2
[gdb/symtab] Fix gdb.base/vla-optimized-out.exp with clang
Consider test-case gdb.base/vla-optimized-out.exp, compiled using clang-10. GDB fails to get the size of the vla a: ... (gdb) p sizeof (a)^M Cannot access memory at address 0x6^M (gdb) FAIL: gdb.base/vla-optimized-out.exp: o1: printed size of \ optimized out vla ... The relevant DWARF looks like this: the variable a: ... <2><12b>: Abbrev Number: 5 (DW_TAG_variable) <12c> DW_AT_name : a <132> DW_AT_type : <0x189> ... has type: ... <1><189>: Abbrev Number: 10 (DW_TAG_array_type) <18a> DW_AT_type : <0x198> <2><18e>: Abbrev Number: 11 (DW_TAG_subrange_type) <18f> DW_AT_type : <0x19f> <193> DW_AT_count : <0x117> ... with the count attribute equated to the value of this artificial variable: ... <2><117>: Abbrev Number: 4 (DW_TAG_variable) <118> DW_AT_location : 10 byte block: 75 1 10 ff ff ff ff f 1a 9f \ (DW_OP_breg5 (rdi): 1; DW_OP_constu: 4294967295; DW_OP_and; DW_OP_stack_value) <123> DW_AT_name : __vla_expr0 <127> DW_AT_type : <0x182> <12b> DW_AT_artificial : 1 ... The location description of the variable is terminated with DW_OP_stack_value, which according to the DWARF spec means that "the DWARF expression represents the actual value of the object, rather than its location". However, in attr_to_dynamic_prop, we set is_reference to true: ... baton->locexpr.is_reference = true; ... and use it in dwarf2_evaluate_property to dereference the value of the DWARF expression, which causes the access to memory at address 0x6. Fix this by ignoring the baton->locexpr.is_reference == true setting if the expression evaluation has ctx.location == DWARF_VALUE_STACK, such that we get: ... (gdb) p sizeof (a)^M $2 = 6^M (gdb) PASS: gdb.base/vla-optimized-out.exp: o1: printed size of \ optimized out vla ... Tested on x86_64-linux, with gcc. Tested the following test-cases (the ones mentioned in PR26905) on x86_64-linux with clang-10: - gdb.base/vla-optimized-out.exp - gdb.base/vla-ptr.exp - gdb.mi/mi-vla-c99 gdb/ChangeLog: 2020-11-30 Tom de Vries <tdevries@suse.de> PR symtab/26905 * dwarf2/loc.c (dwarf2_locexpr_baton_eval): Add and handle is_reference parameter. (dwarf2_evaluate_property): Update dwarf2_locexpr_baton_eval call. gdb/testsuite/ChangeLog: 2020-11-30 Tom de Vries <tdevries@suse.de> PR symtab/26905 * gdb.dwarf2/count.exp: Remove kfails.
Diffstat (limited to 'gdb/dwarf2')
-rw-r--r--gdb/dwarf2/loc.c13
1 files changed, 9 insertions, 4 deletions
diff --git a/gdb/dwarf2/loc.c b/gdb/dwarf2/loc.c
index 86d0ca4..fea49c3 100644
--- a/gdb/dwarf2/loc.c
+++ b/gdb/dwarf2/loc.c
@@ -2499,7 +2499,8 @@ dwarf2_locexpr_baton_eval (const struct dwarf2_locexpr_baton *dlbaton,
struct frame_info *frame,
const struct property_addr_info *addr_stack,
CORE_ADDR *valp,
- bool push_initial_value)
+ bool push_initial_value,
+ bool *is_reference)
{
if (dlbaton == NULL || dlbaton->size == 0)
return 0;
@@ -2546,9 +2547,12 @@ dwarf2_locexpr_baton_eval (const struct dwarf2_locexpr_baton *dlbaton,
switch (ctx.location)
{
+ case DWARF_VALUE_STACK:
+ *is_reference = false;
+ /* FALLTHROUGH */
+
case DWARF_VALUE_REGISTER:
case DWARF_VALUE_MEMORY:
- case DWARF_VALUE_STACK:
*valp = ctx.fetch_address (0);
if (ctx.location == DWARF_VALUE_REGISTER)
*valp = ctx.read_addr_from_reg (*valp);
@@ -2589,10 +2593,11 @@ dwarf2_evaluate_property (const struct dynamic_prop *prop,
= (const struct dwarf2_property_baton *) prop->baton ();
gdb_assert (baton->property_type != NULL);
+ bool is_reference = baton->locexpr.is_reference;
if (dwarf2_locexpr_baton_eval (&baton->locexpr, frame, addr_stack,
- value, push_initial_value))
+ value, push_initial_value, &is_reference))
{
- if (baton->locexpr.is_reference)
+ if (is_reference)
{
struct value *val = value_at (baton->property_type, *value);
*value = value_as_address (val);