On Wed, Jan 25 2017, Andrew Cagney wrote:
>>>> The definition of DW_OP_piece differs, though: "[...] the placement of
>>>> the piece within that register is defined by the ABI."
>>>>>> Right.
>>>> Right, and...? Is it intentional that DW_OP_piece(n)" is not
>> necessarily equivalent to "DW_OP_bit_piece(8*n, 0)?
>> There is no intent.
OK, I guess...? Will some clarifying text be added then?
>>> I'm suggesting non-normative text along the lines of:
>>>>>> / For instance, so that structure variables passed by register can be
>>> loaded and stored
>>> using register-sized transfers, a big-endian ABI may specify that the
>>> pieces of a structure are "left aligned" within a register (located in
>>> the most significant bytes of the register). /
>>>> Do you mean that such an ABI would take a DW_OP_piece from a register
>> according to the "structure parameter passing" rule *whenever* the
>> composite location describes an object with structure type? But this
>> would be wrong, wouldn't it? For instance, modern compilers may
>> optimize a 'short' structure field into a register, then usually
>> aligning it towards the other end of the register instead. How should a
>> DWARF consumer distinguish these cases?
>> To quote DWARF 3 (where it first appears, dwarf 4 has similar if not
> identical text):
>> DW_OP_bit_piece is used instead of DW_OP_piece when the piece to be
> assembled into a value or assigned to is not byte-sized or is not at
> the start of a register or addressable unit of memory.
I thought your example specifically addressed DW_OP_piece (not
DW_OP_bit_piece), and that it illustrated the usefulness of involving
the resulting object's DW_AT_type into the ABI-dependent placement rule.
If that's what you meant, then the example is flawed. If that's *not*
what you meant, then the example is probably misleading (at least to
me). So I suggest to use a different example, or to adjust it so it
actually works.
(Now I wonder how a MIPS big-endian ABI *really* defines DWARF piece
placement in registers. Do you know?)
>>> Also, I suggest to avoid the terms "left" and "right", since I
>> encountered various occasions where they caused more confusion than they
>> helped. And the term "most significant" can not generally be applied to
>> registers either, so in this case I'd prefer something like "located in
>> the lowest-addressed bytes of the register when stored in memory".
>> I've not found this to be true.
Really? I usually refer to lower- and higher-addressed memory units by
"left" and "right", respectively. However, all diagrams in the Intel 64
and IA-32 architectures have this reversed and show lower addresses
below/right and higher addresses above/left. Similarly, when referring
to the bytes in a register I'd call the lower- and higher-addressed
bytes (in natural memory representation) "left" and "right",
respectively. But at least for integer registers some people call the
most significant bytes "left", independently from byte ordering. I had
a lengthy discussion with Jian Xu, where one of our misunderstandings
was centered around the definition of "left" and "right". How do you
interpret these terms?
>>> It is probably worth pointing out that DWARF is tied to an ABI and the
>>> ABI is, in turn, tied to an underlying hardware architecture (UAE in
>>> PowerPC speak).
>>>>>> For instance, 32-bit ELF x86 binary would be described using 32-bit
>>> ELF x86 DWARF. If that binary were to be run on a 64-bit machine say,
>>> then the 64-bit hardware designer, ABI designer, 64-bit operating
>>> system and DWARF consumer all get to figure out exactly what that
>>> means and how it works. For instance, it is the DWARF consumer et.al.
>>> that get to figure out how to map the 32-bit DWARF specified "eax"
>>> onto onto "rax"; not DWARF.
>>>> Right, and I certainly don't expect DWARF to define that relationship.
>> Did you get that impression somewhere?
>> From https://sourceware.org/ml/gdb/2016-01/msg00013.html> You refer to precluding "register growth".
Exactly: the current DWARF text *differs* from the usual "defined by the
ABI"-principle when it states for DW_OP_bit_piece: "If the location is a
register, the offset is from the least significant bit end of the
register". This definition limits the ABI's freedom such that register
growth can only be anchored at the "least significant bit".
>> So what about the original question, whether "DW_OP_reg*" followed by
>> "DW_OP_piece(size of object type)" is always equivalent to omitting the
>> piece operation? Yes or no?
>> While this might be true of a specific ABI - I'd not assume that this
> is true in general.
OK.
>> Note that this question was originally triggered by a question from
>> Adrian Prantl regarding DW_OP_reg*:
>>>>http://lists.dwarfstd.org/private.cgi/dwarf-discuss-dwarfstd.org/2016-March/004201.html>>>> To me it seems that DWARF's definition of the placement of the object
>> addressed by DW_OP_reg* may be lacking. Currently it just says: "The
>> object addressed is in register n", whereas the definition of
>> DW_OP_piece at least states that "the placement of the piece within that
>> register is defined by the ABI." IMO, the amount of detail in these two
>> definitions should be similar, and it would also be helpful to indicate
>> their relationship, such as addressed by my question above.
>> From the spec (DWARF 3 is where it first appeared):
>> 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.
>> Presumably this mapping onto the given architecture's actual registers
> defines (either explicitly or implicitly) the size and other
> attributes of the DWARF registers.
Yes, here the DWARF standard gives a useful explanation of the intended
use and interpretation of register numbers. But it does not give any
hint about placement *within* a register. I'm just saying that a
similar clarification might be useful for that aspect as well.
Maybe Adrian can comment on this as well, since he brought this up
first?
--
Andreas