+2018-08-18 Kevin Buettner <kevinb@redhat.com>
+
+ * dwarf2expr.h (struct dwarf_expr_context): Add virtual method
+ dwarf_variable_value.
+ * dwarf2-frame.c (class dwarf_expr_executor):
+ Add override for dwarf_variable_value.
+ * dwarf2loc.c (class dwarf_evaluate_loc_desc): Likewise.
+ (class symbol_needs_eval_context): Likewise.
+ (indirect_synthetic_pointer): Add forward declaration.
+ (sect_variable_value): New function.
+ (dwarf2_compile_expr_to_ax): Add case for DW_OP_GNU_variable_value.
+ * dwarf2expr.c (dwarf_expr_context::execute_stack_op): Add case
+ for DW_OP_GNU_variable_value.
+
2018-08-16 Tom Tromey <tom@tromey.com>
* top.c (read_command_file): Update.
union call_site_parameter_u kind_u,
struct dwarf2_per_cu_data **per_cu_return);
+static struct value *indirect_synthetic_pointer
+ (sect_offset die, LONGEST byte_offset,
+ struct dwarf2_per_cu_data *per_cu,
+ struct frame_info *frame,
+ struct type *type);
+
/* Until these have formal names, we define these here.
ref: http://gcc.gnu.org/wiki/DebugFission
Each entry in .debug_loc.dwo begins with a byte that describes the entry,
ctx->eval (block.data, block.size);
}
+/* 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. */
+
+static struct value *
+sect_variable_value (struct dwarf_expr_context *ctx, sect_offset sect_off,
+ struct dwarf2_per_cu_data *per_cu)
+{
+ struct type *die_type = dwarf2_fetch_die_type_sect_off (sect_off, per_cu);
+
+ if (die_type == NULL)
+ error (_("Bad DW_OP_GNU_variable_value DIE."));
+
+ /* Note: Things still work when the following test is removed. This
+ test and error is here to conform to the proposed specification. */
+ if (TYPE_CODE (die_type) != TYPE_CODE_INT
+ && TYPE_CODE (die_type) != TYPE_CODE_PTR)
+ error (_("Type of DW_OP_GNU_variable_value DIE must be an integer or pointer."));
+
+ 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, frame, type);
+}
+
class dwarf_evaluate_loc_desc : public dwarf_expr_context
{
public:
per_cu_dwarf_call (this, die_offset, per_cu);
}
+ /* Helper interface of sect_variable_value for
+ dwarf2_evaluate_loc_desc. */
+
+ struct value *dwarf_variable_value (sect_offset sect_off) override
+ {
+ return sect_variable_value (this, sect_off, per_cu);
+ }
+
struct type *get_base_type (cu_offset die_offset, int size) override
{
struct type *result = dwarf2_get_die_type (die_offset, per_cu);
per_cu_dwarf_call (this, die_offset, per_cu);
}
+ /* Helper interface of sect_variable_value for
+ dwarf2_loc_desc_get_symbol_read_needs. */
+
+ struct value *dwarf_variable_value (sect_offset sect_off) override
+ {
+ return sect_variable_value (this, sect_off, per_cu);
+ }
+
/* DW_OP_entry_value accesses require a caller, therefore a
frame. */
case DW_OP_call_ref:
unimplemented (op);
+ case DW_OP_GNU_variable_value:
+ unimplemented (op);
+
default:
unimplemented (op);
}
ul = dwarf2_read_addr_index (per_cu, ul);
fprintf_filtered (stream, " %s", pulongest (ul));
break;
+
+ case DW_OP_GNU_variable_value:
+ ul = extract_unsigned_integer (data, offset_size,
+ gdbarch_byte_order (arch));
+ data += offset_size;
+ fprintf_filtered (stream, " offset %s", phex_nz (ul, offset_size));
+ break;
}
fprintf_filtered (stream, "\n");