summaryrefslogtreecommitdiff
path: root/gdb/dwarf2expr.c
diff options
context:
space:
mode:
authorJan Kratochvil <jan.kratochvil@redhat.com>2011-10-09 19:43:41 +0000
committerJan Kratochvil <jan.kratochvil@redhat.com>2011-10-09 19:43:41 +0000
commita471c5941e127823b95893176c7c9301c4b4cb32 (patch)
treee732be847bf169164a23958e102c6f029f7b71bc /gdb/dwarf2expr.c
parent36b11add17bf287b541a107ee64f7e313e77092f (diff)
gdb/
Display @entry parameter values even for references. * ada-valprint.c (ada_val_print_1) <TYPE_CODE_REF>: Try also coerce_ref_if_computed. * c-valprint.c (c_val_print) <TYPE_CODE_REF>: Likewise. * dwarf2expr.c (dwarf_block_to_dwarf_reg_deref): New function. (execute_stack_op) <DW_OP_GNU_entry_value>: Add -1 deref_size to the existing push_dwarf_reg_entry_value call. Add new detection calling dwarf_block_to_dwarf_reg_deref. Update the error message. (ctx_no_push_dwarf_reg_entry_value): New parameter deref_size. * dwarf2expr.h (struct dwarf_expr_context_funcs) <push_dwarf_reg_entry_value>: Add new parameter deref_size, describe it in the comment. (ctx_no_push_dwarf_reg_entry_value): Add new parameter deref_size. (dwarf_block_to_dwarf_reg_deref): New declaration. * dwarf2loc.c (dwarf_entry_parameter_to_value): Add new parameter deref_size, describe it in the function comment. New variables data_src and size, fetch the alternative block accoring to DEREF_SIZE. (dwarf_expr_push_dwarf_reg_entry_value): Add new parameter deref_size, describe it in the function comment. Fetch the alternative block accoring to DEREF_SIZE. (entry_data_value_coerce_ref, entry_data_value_copy_closure) (entry_data_value_free_closure, entry_data_value_funcs): New. (value_of_dwarf_reg_entry): New variables checked_type, target_type, outer_val, target_val, val and addr. Try to fetch and create also referenced value content. (pieced_value_funcs): NULL value for coerce_ref. (needs_dwarf_reg_entry_value): Add new parameter deref_size. * f-valprint.c (f_val_print) <TYPE_CODE_REF>: Try also coerce_ref_if_computed. * opencl-lang.c (opencl_value_funcs): NULL value for coerce_ref. * p-valprint.c (pascal_val_print) <TYPE_CODE_REF>: Likewise. * stack.c (read_frame_arg): Compare also dereferenced values. * value.c (value_computed_funcs): Make the parameter v const, use value_lval_const for it. (value_lval_const, coerce_ref_if_computed): New function. (coerce_ref): New variable retval. Call also coerce_ref_if_computed. * value.h (struct lval_funcs): New field coerce_ref. (value_computed_funcs): Make the parameter v const. (value_lval_const, coerce_ref_if_computed): New declarations. gdb/testsuite/ Display @entry parameter values even for references. * gdb.arch/amd64-entry-value.cc (reference, datap, datap_input): New functions. (main): New variables regvar, nodatavarp, stackvar1, stackvar2. Call reference and datap_input. * gdb.arch/amd64-entry-value.exp (reference, breakhere_reference): New breakpoints. (continue to breakpoint: entry_reference: reference) (entry_reference: bt at entry) (continue to breakpoint: entry_reference: breakhere_reference) (entry_reference: bt, entry_reference: ptype regparam) (entry_reference: p regparam, entry_reference: ptype regparam@entry) (entry_reference: p regparam@entry, entry_reference: p &regparam@entry) (entry_reference: p regcopy, entry_reference: p nodataparam) (entry_reference: p nodataparam@entry): New tests.
Diffstat (limited to 'gdb/dwarf2expr.c')
-rw-r--r--gdb/dwarf2expr.c79
1 files changed, 76 insertions, 3 deletions
diff --git a/gdb/dwarf2expr.c b/gdb/dwarf2expr.c
index 4fccc262ec..71aff6ad33 100644
--- a/gdb/dwarf2expr.c
+++ b/gdb/dwarf2expr.c
@@ -518,6 +518,63 @@ dwarf_block_to_dwarf_reg (const gdb_byte *buf, const gdb_byte *buf_end)
return dwarf_reg;
}
+/* If <BUF..BUF_END] contains DW_FORM_block* with just DW_OP_breg*(0) and
+ DW_OP_deref* return the DWARF register number. Otherwise return -1.
+ DEREF_SIZE_RETURN contains -1 for DW_OP_deref; otherwise it contains the
+ size from DW_OP_deref_size. */
+
+int
+dwarf_block_to_dwarf_reg_deref (const gdb_byte *buf, const gdb_byte *buf_end,
+ CORE_ADDR *deref_size_return)
+{
+ ULONGEST dwarf_reg;
+ LONGEST offset;
+
+ if (buf_end <= buf)
+ return -1;
+ if (*buf >= DW_OP_breg0 && *buf <= DW_OP_breg31)
+ {
+ dwarf_reg = *buf - DW_OP_breg0;
+ buf++;
+ }
+ else if (*buf == DW_OP_bregx)
+ {
+ buf++;
+ buf = read_uleb128 (buf, buf_end, &dwarf_reg);
+ if ((int) dwarf_reg != dwarf_reg)
+ return -1;
+ }
+ else
+ return -1;
+
+ buf = read_sleb128 (buf, buf_end, &offset);
+ if (offset != 0)
+ return -1;
+
+ if (buf >= buf_end)
+ return -1;
+
+ if (*buf == DW_OP_deref)
+ {
+ buf++;
+ *deref_size_return = -1;
+ }
+ else if (*buf == DW_OP_deref_size)
+ {
+ buf++;
+ if (buf >= buf_end)
+ return -1;
+ *deref_size_return = *buf++;
+ }
+ else
+ return -1;
+
+ if (buf != buf_end)
+ return -1;
+
+ return dwarf_reg;
+}
+
/* If <BUF..BUF_END] contains DW_FORM_block* with single DW_OP_fbreg(X) fill
in FB_OFFSET_RETURN with the X offset and return 1. Otherwise return 0. */
@@ -1304,12 +1361,27 @@ execute_stack_op (struct dwarf_expr_context *ctx,
{
op_ptr += len;
ctx->funcs->push_dwarf_reg_entry_value (ctx, dwarf_reg,
- 0 /* unused */);
+ 0 /* unused */,
+ -1 /* deref_size */);
+ goto no_push;
+ }
+
+ dwarf_reg = dwarf_block_to_dwarf_reg_deref (op_ptr, op_ptr + len,
+ &deref_size);
+ if (dwarf_reg != -1)
+ {
+ if (deref_size == -1)
+ deref_size = ctx->addr_size;
+ op_ptr += len;
+ ctx->funcs->push_dwarf_reg_entry_value (ctx, dwarf_reg,
+ 0 /* unused */,
+ deref_size);
goto no_push;
}
error (_("DWARF-2 expression error: DW_OP_GNU_entry_value is "
- "supported only for single DW_OP_reg*"));
+ "supported only for single DW_OP_reg* "
+ "or for DW_OP_breg*(0)+DW_OP_deref*"));
}
case DW_OP_GNU_const_type:
@@ -1460,7 +1532,8 @@ ctx_no_get_base_type (struct dwarf_expr_context *ctx, size_t die)
void
ctx_no_push_dwarf_reg_entry_value (struct dwarf_expr_context *ctx,
- int dwarf_reg, CORE_ADDR fb_offset)
+ int dwarf_reg, CORE_ADDR fb_offset,
+ int deref_size)
{
internal_error (__FILE__, __LINE__,
_("Support for DW_OP_GNU_entry_value is unimplemented"));