diff options
author | Tom de Vries <tdevries@suse.de> | 2020-11-30 13:50:26 +0100 |
---|---|---|
committer | Tom de Vries <tdevries@suse.de> | 2020-11-30 13:50:26 +0100 |
commit | 7ce05d212d1b825dc58d2b0d390417f2c134cd98 (patch) | |
tree | e0ea14b8917a8f330f604c8847cf4d18218bf73b /gdb/dwarf2 | |
parent | 61049d1ee59905589b2ad3f8140a2582e01add7a (diff) | |
download | fsf-binutils-gdb-7ce05d212d1b825dc58d2b0d390417f2c134cd98.zip fsf-binutils-gdb-7ce05d212d1b825dc58d2b0d390417f2c134cd98.tar.gz fsf-binutils-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.c | 13 |
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); |