[Dwarf-discuss] Constant expressions in locations lists

Cary Coutant cary@cup.hp.com
Wed Mar 7 23:39:54 GMT 2007


Jim Blandy wrote:
> I think an expression operator might be a nice way to solve this, but
> DW_OP_addressof has some difficulties.  The values on the stack are
> always address-sized, so you would have difficulty producing constant
> values of floating-point, very large integer, or structure types.
>
> Perhaps an operator DW_OP_constant, followed by an LEB128 size,
> followed by that many bytes of data in target form, permitted to
> appear wherever a location expression may occur.

and Daniel Berlin wrote:
> Why not just a DW_OP_constant_value?

Yes, this is probably better.

I did consider that approach, but it seemed potentially confusing,  
given that it would be quite different from the existing DW_OP_const*  
and DW_OP_lit* operators. Nevertheless, Jim's point about large  
values is a good one, and I think it overrides my concern about  
confusion. If this new operator were introduced in Section 2.5.1 (or  
in a new section immediately following), it could be made clear that  
this operator provides a constant value as opposed to a constant to  
be used for address computation. The rules for its use, I think,  
could be exactly the same as those for DW_OP_reg*, and could be used  
as part of a DW_OP_piece construction as well.

> (The spec really needs a grammar for location expressions; writing out
> grammar rules in English is clumsy.)

I think what it needs isn't so much a grammar as a type system. The  
grammar for a postfix expression on a simple stack is trivial.  
Consider introducing four types of values that can exist on the  
stack: integers, register names, constant values, and "pieces". Now  
each operator can be described in terms of what types of values it  
can consume from the stack and what type of value it pushes back onto  
the stack (if any):

- The DW_OP_const* and DW_OP_lit* operators push an integer onto the  
stack.
- The DW_OP_reg* operators push a register name.
- The DW_OP_constant_value operator pushes a constant value.
- The DW_OP_piece (and DW_OP_bit_piece, if that's in yet) operator  
can consume any one of the other three types, and pushes a "piece"  
back onto the stack.
- Most of the remaining operators consume one or two integers and  
push an integer.

At the end of the expression, we must have a stack that has either  
(a) exactly one value of type integer, register name, or constant  
value; or (b) one or more values of type "piece". (In other words, if  
the stack contains more than one value at the end, they must all be  
"pieces".)

(DW_OP_skip and DW_OP_bra may take a little additional descriptive  
effort, but as long as expression validity is defined in terms of  
what kinds of values can be consumed by each operator and what the  
stack has to look like at the end, it should be complete.)

This relates back to an April 2005 discussion on this list about  
DW_OP_piece. That discussion suggested treating DW_OP_piece as  
removing a value from the stack and contributing a piece description  
"somewhere else". I think using separate types makes it conceptually  
clearer, and the allowable expressions are constrained by the types  
that each operator can consume and the requirements for the ending  
contents of the stack.

-cary







More information about the Dwarf-discuss mailing list