[Dwarf-discuss] register name operators recap

David B. Anderson davea
Fri Nov 17 17:48:58 GMT 2006



Marcel Mettes started a discussion 15 November, 2006
on register name operators and identified a problem in the existing document.
Unfortunately dwarf-discuss dropped off the cc-list during the email
exchange.  With Marcel's permission I'm putting the entire
exchange together here for the list.
(Jim Blandy's contribution is already on the list, but 
duplicated here to keep it all together in sequence).

This is a bit long, sorry. 

David Anderson


SUMMARY: the description of DW_OP_piece (DW_OP_bit_piece) and
DW_OP_reg<n> are somewhat lacking.
Jim Blandy's document-fix-suggestion is concise and
he noticed a second issue in the document too.
An alternative syntax-oriented approach is provided 
by Marcel Mettes.


======================================
DETAILS follow.

====Marcel Mettes writes:
We have a question regarding the register name expression operator, e.g. 
DW_OP_reg0.

In the DWARF 3 document as released last december, 2005 it says on 
DW_reg0 and the like:

----------------------------------------------------------------------------------


      2.6.1       Register Name Operators

The following DWARF operations can be used to name a register. They can 
be used only in location expressions. Each register name operator must 
be used alone (as a DWARF expression consisting of just that one 
operation).

/Note that the register number represents a DWARF specific mapping of 
numbers onto the actual registers of a given architecture. The mapping 
should be chosen to gain optimal density and should be shared by all 
users of a given architecture. It is recommended that this mapping be 
defined by the ABI authoring committee for each architecture./

1.      *DW_OP_reg0**, DW_OP_reg1**, ..., DW_OP_reg31*
The DW_OP_reg/n/ operations encode the names of up to 32 registers, 
numbered from 0 through 31, inclusive. The object addressed is in 
register /n/.

2.      *DW_OP_regx*
The DW_OP_regx operation has a single unsigned LEB128 literal operand 
that encodes the name of a register.

----------------------------------------------------------------------------------

This paragaph of the document has been extended since 2.0.0.

The statement that these DW_OP_reg have to be used "Each register name 
operator must be used alone (as a DWARF expression consisting of just 
that one operation)." seems to conflict with the examples given below in 
2.6.5:

----------------------------------------------------------------------------------
DW_OP_reg0 
<http://tsw.tasking.nl/doc/dwarf/dwarf3/Dwarf3-20051220.htm#DW_OP_reg0> DW_OP_piece 
<http://tsw.tasking.nl/doc/dwarf/dwarf3/Dwarf3-20051220.htm#DW_OP_piece> 4 
DW_OP_piece 
<http://tsw.tasking.nl/doc/dwarf/dwarf3/Dwarf3-20051220.htm#DW_OP_piece> 4 
DW_OP_fbreg 
<http://tsw.tasking.nl/doc/dwarf/dwarf3/Dwarf3-20051220.htm#DW_OP_fbreg> -12 
DW_OP_piece 
<http://tsw.tasking.nl/doc/dwarf/dwarf3/Dwarf3-20051220.htm#DW_OP_piece> 4
----------------------------------------------------------------------------------

This expression was valid in DWARF 2.0.0. Can I still use complex 
expressions with DW_reg register name operators?


======================================
========David Anderson writes:


DW_OP_piece, DW_OP_bit_piece are very special.
In effect these two composition operators 'separate'
distinct DWARF expressions.

The wording (in 2.6.2, perhaps) needs a change/clarification to reflect
this special-ness. 
The right wording does not occur to me right now.

======================================
====David Anderson writes:
>
>DW_OP_piece, DW_OP_bit_piece are very special.
>In effect these two composition operators 'separate'
>distinct DWARF expressions.

Of course that's wrong :-(   'separate' is the wrong concept.
A composition operator 'terminates' a dwarf expression,
sort of.  

Or perhaps delineates a dwarf-expression?

Since the composition operator operates on the stack as a whole
(not some fraction)  it's not really  a block-scope terminator,
or at least not a very flexible one  (not clear to me how
a more flexible one would be meaningful so I do not see any problem
with the current definition other than the issue
Marcel Mettes brought up).



======================================
===========Marcel Mettes writes:
I think I understand why DW_OP_piece is not an operator. Given that a 
location
expression must be used for both reading and writing, one cannot
implement DW_OP_piece as a mask+shift operation. That would not
work when writing. (not something I thought of the first time I studied 
this :-)

However, in the example in the DWARF3 document, 2.6.5, there is also an 
DW_OP_fbreg operator
in the last example:

	DW_OP_reg0 DW_OP_piece 4 DW_OP_piece  4 DW_OP_fbreg  -12 DW_OP_piece  4


DW_OP_fbreg is a regular operator. Is that also valid given the register 
name operator restriction?
I must confess that I do not really understand why the DW_OP_regx and 
DW_OP_reg0
have been restricted in the DWARF 3, except for perhaps making it work 
with incomplete
(older?) expression interpreters?

In the 8th example, two DW_OP_reg's appear in one expression

    DW_OP_reg3 DW_OP_piece 4 DW_OP_reg10 DW_OP_piece 2

So I wonder how to interprete this limitation as described for 
DW_OP_regx/DW_OP_reg3 in 2.6.1 .

======================================
====David Anderson writes:

Marcel Mettes writes:
|DW_OP_fbreg is a regular operator. Is that also valid given the register 
|name operator restriction?

Yes. In effect
	DW_OP_reg0
	<empty>
        DW_OP_fbreg  -12 
are 3 distinct dwarf expressions.
Each dwarf expresion supplying a part of the result 'independently'.
So the restriction on DW_OP_reg<n> applies independently in
each of the 3 distinct dwarf expressions.
        

Marcel Mettes writes:
|I must confess that I do not really understand why the DW_OP_regx and 
|DW_OP_reg0
|have been restricted in the DWARF 3, except for perhaps making it work 
|with incomplete
|(older?) expression interpreters?

No. It's because nothing else makes sense.
	DW_OP_reg0 says the variable is  *in* the register.
All other dwarf-expressions compute an address and the variable
is at that computed address.

There is no way to combine DW_OP_reg3 (for example) with any other
operator (DW_OP_piece and DW_OP_bit_piece being the exceptions).
It makes no sense to do so. DW_OP_reg<n> do NOT say to dereference the register,
they just say 'register number <n>'.   Since (for most architectures)
a register has no address the  normal dwarf expression result
of 'address of the variable' makes no sense.  DW_OP_reg<n>
provides a way to deal with the special case.


|In the 8th example, two DW_OP_reg's appear in one expression
|
|    DW_OP_reg3 DW_OP_piece 4 DW_OP_reg10 DW_OP_piece 2



|So I wonder how to interprete this limitation as described for 
|DW_OP_regx/DW_OP_reg3 in 2.6.1 .

These are *independent* as DW_OP_piece (DW_OP_bit_piece) delineate
the end of a simple expression (well sort of) and 
with each simple expresson these are unique.

The problem is that there's no language in the document (that I recognize) that
really distinquishes the two categories of simple expressions:
   simple simple expression
   simple expression of a set of simple expressions terminated
	by DW_OP_piece.

Difficult to state.
Maybe 
	simple-expression0:
	    operators..... (left as exercise)

	piece:
	      simple-expression0 DW_OP_piece <n>
		|
	      simple-expression0 DW_OP_bit_piece <n>

	simple-expression-n:
	      piece
	       | 
	      simple-expression-n  piece

	where the restriction applies to simple-expression0

Hmm. Then the <empty> needs to be accounted for. 
And then the DW_OP_reg<n> restriction applies to simple-expression0
(not to simple-expression-n).


======================================
====Jim Blandy writes:
We did clarify some of the language regarding this point, but clearly
we missed a spot.

Marcel, the first paragraph of 2.6.1 ought to be saying that DWARF
register name operators must appear as a complete *simple* location
expression.  That is, the paragraph should say:

The following DWARF operations can be used to name a register. They
can be used only in
location expressions. Each register name operator is a complete simple
location expression; it cannot be combined with other DWARF expression
operators within a simple location expression.

Then, the next sections discuss simple location expressions and
composition operators.

I was surprised to see that point 3 in section 2.6.2, Simple Location
Expressions, is the first place it's actually explained that the
register name operations denote (possibly partial) values stored *in*
the register itself, rather than having its address computed using the
register's value.  This seems obscure; I think 2.6.1 should come out
and say it.  As it stands, you need to have already noticed the need
for register name operators ("hey, location expressions compute
addresses --- but what about variables that don't have addresses?") in
order to recognize that they're what you're looking for.


======================================
======Marcel Mettes writes:

I like the syntax idea. If I wonder about a specific case,
I can simply parse it using the syntax and see if that allows it.

Therefore I have taken the libery to try to come up with a syntax that 
describes both
the PIECE operator acting as a terminator and the DW_OP_regx limitation 
to simple expressions.
To capture the nature of the DW_OP_reg* operators limitation, different 
tokens are used
for the various sets of operators:

Tokens

    OP_ALL:
        all operators, including DW_OP_reg[0-31], DW_OP_regx, 
DW_OP_piece and DW_OP_bit_piece

    OP_TERMINATOR:
         DW_OP_piece and DW_OP_bit_piece

    OP_REG:
         DW_OP_reg[0-31] and DW_OP_regx

    OP_COMP:
         all operators that can be used in compositions,
         being all operators other than those in OP_TERMINATOR and OP_REG

Syntax

    start : expression

    expression : subexpression_list

    subexpression_list : <empty>
                       | subexpression subexpression_list

    subexpression : simple_expression
                  | composite_expression

    simple_expression : OP_TERMINATOR
                      | OP_REG
                      | OP_REG OP_TERMINATOR

    composite_expression : OP_COMP
                         | OP_COMP OP_TERMINATOR
                         | OP_COMP composite_expression



===end.





More information about the Dwarf-discuss mailing list