aboutsummaryrefslogtreecommitdiff
path: root/gdb/dwarf2/loc.c
diff options
context:
space:
mode:
authorTom Tromey <tromey@adacore.com>2021-06-04 13:51:23 -0600
committerTom Tromey <tromey@adacore.com>2021-06-04 13:51:23 -0600
commit386de171cbffa86e804057030f3d64a404279f43 (patch)
treefb9c127f3c004533fa43110baa467b7405e323ce /gdb/dwarf2/loc.c
parent4351271e9c98553900f6ae3cbcaaa75198909daa (diff)
downloadgdb-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.c37
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;