forked from Imagelibrary/binutils-gdb
gdb
* 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:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user