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.
This commit is contained in:
Jan Kratochvil
2011-10-09 19:43:41 +00:00
parent 36b11add17
commit a471c5941e
15 changed files with 496 additions and 47 deletions

View File

@@ -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"));