diff options
author | Tom Tromey <tromey@adacore.com> | 2021-06-04 13:51:23 -0600 |
---|---|---|
committer | Tom Tromey <tromey@adacore.com> | 2021-06-04 13:51:23 -0600 |
commit | 386de171cbffa86e804057030f3d64a404279f43 (patch) | |
tree | fb9c127f3c004533fa43110baa467b7405e323ce /gdb/dwarf2/loc.c | |
parent | 4351271e9c98553900f6ae3cbcaaa75198909daa (diff) | |
download | gdb-386de171cbffa86e804057030f3d64a404279f43.zip gdb-386de171cbffa86e804057030f3d64a404279f43.tar.gz gdb-386de171cbffa86e804057030f3d64a404279f43.tar.bz2 |
Add PROP_VARIABLE_NAME
With -fgnat-encodings=minimal, an internal version (these patches will
be upstreamed in the near future) of the Ada compiler can emit DWARF
for an array where the bound comes from a variable, like:
<1><12a7>: Abbrev Number: 7 (DW_TAG_array_type)
<12a8> DW_AT_name : (indirect string, offset: 0x1ae9): pck__my_array
[...]
<2><12b4>: Abbrev Number: 8 (DW_TAG_subrange_type)
<12b5> DW_AT_type : <0x1294>
<12b9> DW_AT_upper_bound : <0x1277>
With the upper bound DIE being:
<1><1277>: Abbrev Number: 2 (DW_TAG_variable)
<1278> DW_AT_name : (indirect string, offset: 0x1a4d): pck__my_length___U
<127c> DW_AT_type : <0x128f>
<1280> DW_AT_external : 1
<1280> DW_AT_artificial : 1
<1280> DW_AT_declaration : 1
Note that the variable is just a declaration -- in this situation, the
variable comes from another compilation unit, and must be found when
trying to compute the array bound.
This patch adds a new PROP_VARIABLE_NAME kind, to enable this search.
This same scenario can occur with DW_OP_GNU_variable_value, so this
patch adds support for that as well.
gdb/ChangeLog
2021-06-04 Tom Tromey <tromey@adacore.com>
* dwarf2/read.h (dwarf2_fetch_die_type_sect_off): Add 'var_name'
parameter.
* dwarf2/loc.c (dwarf2_evaluate_property) <case
PROP_VARIABLE_NAME>: New case.
(compute_var_value): New function.
(sect_variable_value): Use compute_var_value.
* dwarf2/read.c (attr_to_dynamic_prop): Handle DW_TAG_variable.
(var_decl_name): New function.
(dwarf2_fetch_die_type_sect_off): Add 'var_name' parameter.
* gdbtypes.h (enum dynamic_prop_kind) <PROP_VARIABLE_NAME>: New
constant.
(union dynamic_prop_data) <variable_name>: New member.
(struct dynamic_prop) <variable_name, set_variable_name>: New
methods.
gdb/testsuite/ChangeLog
2021-06-04 Tom Tromey <tromey@adacore.com>
* gdb.ada/array_of_symbolic_length.exp: New file.
* gdb.ada/array_of_symbolic_length/foo.adb: New file.
* gdb.ada/array_of_symbolic_length/gl.adb: New file.
* gdb.ada/array_of_symbolic_length/gl.ads: New file.
* gdb.ada/array_of_symbolic_length/pck.adb: New file.
* gdb.ada/array_of_symbolic_length/pck.ads: New file.
Diffstat (limited to 'gdb/dwarf2/loc.c')
-rw-r--r-- | gdb/dwarf2/loc.c | 37 |
1 files changed, 36 insertions, 1 deletions
diff --git a/gdb/dwarf2/loc.c b/gdb/dwarf2/loc.c index e816f92..b7e30e3 100644 --- a/gdb/dwarf2/loc.c +++ b/gdb/dwarf2/loc.c @@ -620,6 +620,19 @@ per_cu_dwarf_call (struct dwarf_expr_context *ctx, cu_offset die_offset, ctx->eval (block.data, block.size); } +/* A helper function to find the definition of NAME and compute its + value. Returns nullptr if the name is not found. */ + +static value * +compute_var_value (const char *name) +{ + struct block_symbol sym = lookup_symbol (name, nullptr, VAR_DOMAIN, + nullptr); + if (sym.symbol != nullptr) + return value_of_variable (sym.symbol, sym.block); + return nullptr; +} + /* Given context CTX, section offset SECT_OFF, and compilation unit data PER_CU, execute the "variable value" operation on the DIE found at SECT_OFF. */ @@ -629,8 +642,10 @@ sect_variable_value (struct dwarf_expr_context *ctx, sect_offset sect_off, dwarf2_per_cu_data *per_cu, dwarf2_per_objfile *per_objfile) { + const char *var_name = nullptr; struct type *die_type - = dwarf2_fetch_die_type_sect_off (sect_off, per_cu, per_objfile); + = dwarf2_fetch_die_type_sect_off (sect_off, per_cu, per_objfile, + &var_name); if (die_type == NULL) error (_("Bad DW_OP_GNU_variable_value DIE.")); @@ -638,9 +653,18 @@ sect_variable_value (struct dwarf_expr_context *ctx, sect_offset sect_off, /* Note: Things still work when the following test is removed. This test and error is here to conform to the proposed specification. */ if (die_type->code () != TYPE_CODE_INT + && die_type->code () != TYPE_CODE_ENUM + && die_type->code () != TYPE_CODE_RANGE && die_type->code () != TYPE_CODE_PTR) error (_("Type of DW_OP_GNU_variable_value DIE must be an integer or pointer.")); + if (var_name != nullptr) + { + value *result = compute_var_value (var_name); + if (result != nullptr) + return result; + } + struct type *type = lookup_pointer_type (die_type); struct frame_info *frame = get_selected_frame (_("No frame selected.")); return indirect_synthetic_pointer (sect_off, 0, per_cu, per_objfile, frame, @@ -2691,6 +2715,17 @@ dwarf2_evaluate_property (const struct dynamic_prop *prop, *value = value_as_address (val); return true; } + + case PROP_VARIABLE_NAME: + { + struct value *val = compute_var_value (prop->variable_name ()); + if (val != nullptr) + { + *value = value_as_long (val); + return true; + } + } + break; } return false; |