* dwarf2loc.c (struct piece_closure) <arch>: New field.
	(dwarf2_evaluate_loc_desc): Update.
	(dwarf2_loc_desc_needs_frame): Likewise.
	(allocate_piece_closure): Initialize new field.
	(read_pieced_value): Update.
	(write_pieced_value): Update.
	(copy_pieced_value_closure): Update.
	* dwarf2expr.h (enum dwarf_value_location): New.
	(struct dwarf_expr_context) <in_reg>: Remove.
	<location, len, data>: New fields.
	(struct dwarf_expr_piece) <in_reg, value>: Remove.
	<location, v>: New fields.
	* dwarf2expr.c (add_piece): Remove in_reg, value arguments.
	Update.
	(require_composition): New function.
	(execute_stack_op): Update.
	<DW_OP_implicit_value, DW_OP_stack_value>: New cases.
	<DW_OP_reg0>: Set location, not in_reg.
	<DW_OP_regx>: Likewise.  Use require_composition.
	<DW_OP_fbreg>: Update.
	<DW_OP_piece>: Likewise.
	* dwarf2-frame.c (execute_stack_op): Update.
gdb/testsuite
	* gdb.dwarf2/valop.S: New file.
	* gdb.dwarf2/valop.exp: New file.
This commit is contained in:
Tom Tromey
2009-09-11 18:38:39 +00:00
parent a05e8785c7
commit cec03d703f
8 changed files with 822 additions and 80 deletions

View File

@@ -23,6 +23,19 @@
#if !defined (DWARF2EXPR_H)
#define DWARF2EXPR_H
/* The location of a value. */
enum dwarf_value_location
{
/* The piece is in memory. */
DWARF_VALUE_MEMORY,
/* The piece is in a register. */
DWARF_VALUE_REGISTER,
/* The piece is on the stack. */
DWARF_VALUE_STACK,
/* The piece is a literal. */
DWARF_VALUE_LITERAL
};
/* The expression evaluator works with a dwarf_expr_context, describing
its current state and its callbacks. */
struct dwarf_expr_context
@@ -80,9 +93,13 @@ struct dwarf_expr_context
depth we'll tolerate before raising an error. */
int recursion_depth, max_recursion_depth;
/* Non-zero if the result is in a register. The register number
will be on the expression stack. */
int in_reg;
/* Location of the value. */
enum dwarf_value_location location;
/* For VALUE_LITERAL, a the current literal value's length and
data. */
ULONGEST len;
gdb_byte *data;
/* Initialization status of variable: Non-zero if variable has been
initialized; zero otherwise. */
@@ -93,9 +110,9 @@ struct dwarf_expr_context
Each time DW_OP_piece is executed, we add a new element to the
end of this array, recording the current top of the stack, the
current in_reg flag, and the size given as the operand to
DW_OP_piece. We then pop the top value from the stack, clear the
in_reg flag, and resume evaluation.
current location, and the size given as the operand to
DW_OP_piece. We then pop the top value from the stack, rest the
location, and resume evaluation.
The Dwarf spec doesn't say whether DW_OP_piece pops the top value
from the stack. We do, ensuring that clients of this interface
@@ -106,12 +123,11 @@ struct dwarf_expr_context
If an expression never uses DW_OP_piece, num_pieces will be zero.
(It would be nice to present these cases as expressions yielding
a single piece, with in_reg clear, so that callers need not
distinguish between the no-DW_OP_piece and one-DW_OP_piece cases.
But expressions with no DW_OP_piece operations have no value to
place in a piece's 'size' field; the size comes from the
surrounding data. So the two cases need to be handled
separately.) */
a single piece, so that callers need not distinguish between the
no-DW_OP_piece and one-DW_OP_piece cases. But expressions with
no DW_OP_piece operations have no value to place in a piece's
'size' field; the size comes from the surrounding data. So the
two cases need to be handled separately.) */
int num_pieces;
struct dwarf_expr_piece *pieces;
};
@@ -120,13 +136,22 @@ struct dwarf_expr_context
/* A piece of an object, as recorded by DW_OP_piece. */
struct dwarf_expr_piece
{
/* If IN_REG is zero, then the piece is in memory, and VALUE is its address.
If IN_REG is non-zero, then the piece is in a register, and VALUE
is the register number. */
int in_reg;
enum dwarf_value_location location;
/* This piece's address or register number. */
CORE_ADDR value;
union
{
/* This piece's address or register number. */
CORE_ADDR value;
struct
{
/* A pointer to the data making up this piece, for literal
pieces. */
gdb_byte *data;
/* The length of the available data. */
ULONGEST length;
} literal;
} v;
/* The length of the piece, in bytes. */
ULONGEST size;