aboutsummaryrefslogtreecommitdiff
path: root/gdb/dwarf2loc.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/dwarf2loc.c')
-rw-r--r--gdb/dwarf2loc.c60
1 files changed, 51 insertions, 9 deletions
diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c
index 3a81202..9d0cd9e 100644
--- a/gdb/dwarf2loc.c
+++ b/gdb/dwarf2loc.c
@@ -41,6 +41,10 @@
#include "gdb_string.h"
#include "gdb_assert.h"
+static void
+dwarf_expr_frame_base_1 (struct symbol *framefunc, CORE_ADDR pc,
+ gdb_byte **start, size_t *length);
+
/* A helper function for dealing with location lists. Given a
symbol baton (BATON) and a pc value (PC), find the appropriate
location expression, set *LOCEXPR_LENGTH, and return a pointer
@@ -166,16 +170,23 @@ dwarf_expr_frame_base (void *baton, gdb_byte **start, size_t * length)
something has gone wrong. */
gdb_assert (framefunc != NULL);
+ dwarf_expr_frame_base_1 (framefunc,
+ get_frame_address_in_block (debaton->frame),
+ start, length);
+}
+
+static void
+dwarf_expr_frame_base_1 (struct symbol *framefunc, CORE_ADDR pc,
+ gdb_byte **start, size_t *length)
+{
if (SYMBOL_LOCATION_BATON (framefunc) == NULL)
*start = NULL;
else if (SYMBOL_COMPUTED_OPS (framefunc) == &dwarf2_loclist_funcs)
{
struct dwarf2_loclist_baton *symbaton;
- struct frame_info *frame = debaton->frame;
symbaton = SYMBOL_LOCATION_BATON (framefunc);
- *start = find_location_expression (symbaton, length,
- get_frame_address_in_block (frame));
+ *start = find_location_expression (symbaton, length, pc);
}
else
{
@@ -617,21 +628,52 @@ dwarf2_tracepoint_var_ref (struct symbol *symbol, struct gdbarch *gdbarch,
}
else if (data[0] == DW_OP_fbreg)
{
- /* And this is worse than just minimal; we should honor the frame base
- as above. */
- int frame_reg;
+ struct block *b;
+ struct symbol *framefunc;
+ int frame_reg = 0;
LONGEST frame_offset;
gdb_byte *buf_end;
+ gdb_byte *base_data;
+ size_t base_size;
+ LONGEST base_offset = 0;
+
+ b = block_for_pc (ax->scope);
+
+ if (!b)
+ error (_("No block found for address"));
+
+ framefunc = block_linkage_function (b);
+
+ if (!framefunc)
+ error (_("No function found for block"));
+
+ dwarf_expr_frame_base_1 (framefunc, ax->scope,
+ &base_data, &base_size);
+
+ if (base_data[0] >= DW_OP_breg0
+ && base_data[0] <= DW_OP_breg31)
+ {
+ frame_reg = base_data[0] - DW_OP_breg0;
+ buf_end = read_sleb128 (base_data + 1, base_data + base_size, &base_offset);
+ if (buf_end != base_data + base_size)
+ error (_("Unexpected opcode after DW_OP_breg%u for symbol \"%s\"."),
+ frame_reg, SYMBOL_PRINT_NAME (symbol));
+ }
+ else
+ {
+ /* We don't know what to do with the frame base expression,
+ so we can't trace this variable; give up. */
+ error (_("Cannot generate expression to collect symbol \"%s\"; DWARF 2 encoding not handled"),
+ SYMBOL_PRINT_NAME (symbol));
+ }
buf_end = read_sleb128 (data + 1, data + size, &frame_offset);
if (buf_end != data + size)
error (_("Unexpected opcode after DW_OP_fbreg for symbol \"%s\"."),
SYMBOL_PRINT_NAME (symbol));
- gdbarch_virtual_frame_pointer (gdbarch,
- ax->scope, &frame_reg, &frame_offset);
ax_reg (ax, frame_reg);
- ax_const_l (ax, frame_offset);
+ ax_const_l (ax, base_offset + frame_offset);
ax_simple (ax, aop_add);
value->kind = axs_lvalue_memory;