Re: interface to partial support for DW_OP_piece in dwarf2expr.[ch]

Andrew Cagney
2004-08-04T16:53:07Z

> Full support for the Dwarf DW_OP_piece operator in location
> expressions would require major work on 'struct value' and its users.
> But in many cases, compilers use DW_OP_piece in a restricted way, such
> that all the multi-piece locations actually generated could be
> expressed using the 'struct symbol' and 'struct value' we have today.
>
> For example, on the PowerPC E500, the 32-bit upper and lower halves of
> the 64-bit gprs have separate register numbers in Dwarf information,
> but GDB has (pseudo-)registers that refer to the entire 64 bits. So a
> Dwarf 3 location expression that places one piece in an upper-half
> register and another piece in the corresponding lower-half register
> could be represented by a 'struct value' V where VALUE_LVAL (V) ==
> lval_register and VALUE_REGNO (V) is the pseudo-register number.
>
> Recognizing these cases requires calling out to architecture-specific
> code. When an patch implementing this was first posted, there was
> general agreement that dwarf2expr.[ch] ought not call architecture
> methods directly, as it did in the patch, but should instead return
> the list of pieces; and that dwarf2expr.[ch]'s callers (specifically,
> the code in dwarf2loc.c) should take care of whatever wrangling was
> needed to turn that list of pieces into the right 'struct value',
> architecture-specific or otherwise. That thread starts here:
>
> http://sources.redhat.com/ml/gdb-patches/2003-05/msg00425.html
>
> Here's a sketch of how we might extend the Dwarf expression evaluation
> interface to return piece lists, meant to implement the suggestions in
> that thread. If this looks reasonable, then I'll do some more work
> and post it for further review.

Knowing that GCC 3.5 is going to be a heavy user of DW_OP_piece, means
that we need to start moving on this, and its good to see this happening.

I'm just having trouble getting my head around how this will affect
core-gdb, and seeing how this addresses our need to meet GCC 3.5's
requirements?

Can we expand on that?

--

Looking at the below:

- a single value can have multiple locations (important for store)
- could dwarf2_expr_piece be called ``struct location''? :-)

Andrew

> *** dwarf2expr.h.~1.5.~ 2003-06-08 13:27:13.000000000 -0500
> --- dwarf2expr.h 2004-08-03 02:07:08.000000000 -0500
> *************** struct dwarf_expr_context
> *** 74,79 ****
> --- 74,122 ----
> /* Non-zero if the result is in a register. The register number
> will be on the expression stack. */
> int in_reg;
> +
> + /* An array of pieces. PIECES points to its first element;
> + NUM_PIECES is its length.
> +
> + 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.
> +
> + 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
> + expecting to see a value left on the top of the stack (say, code
> + evaluating frame base expressions or CFA's specified with
> + DW_CFA_def_cfa_expression) will get an error if the expression
> + actually marks all the values it computes as pieces.
> +
> + If an expression never uses DW_OP_piece, num_pieces will be zero.
> + (It would be nice to present these cases as expressions yeilding
> + 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.) */
> + int num_pieces;
> + struct dwarf_expr_piece *pieces;
> + };
> +
> +
> + /* 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;
> +
> + /* This piece's address or register number. */
> + CORE_ADDR value;
> +
> + /* The length of the piece, in bytes. */
> + ULONGEST size;
> };
>
> struct dwarf_expr_context *new_dwarf_expr_context (void);