On 12 December 2016 at 09:28, Andreas Arnez <ar...@linux.vnet.ibm.com> wrote: > On Fri, Dec 09 2016, Adrian Prantl wrote: > >> Here's my take on this. > > Thanks! > >>> On Dec 9, 2016, at 11:11 AM, Andreas Arnez <ar...@linux.vnet.ibm.com> wrote: >>> >>> Although I've already created public comments for (most of) this, >>> Michael Eager suggested that I post my questions regarding DWARF pieces >>> on this list (again). >>> >>> All of these questions are related to the definition of DW_OP_piece and >>> DW_OP_bit_piece: >>> >>> * Is "DW_OP_piece(n)" equivalent to "DW_OP_bit_piece(8*n, 0)"? >> >> I would think the answer to this is yes, and if it isn't I would >> really like to see the counterexample added to the Appendix. > > Right, I think clarification would be appropriate either way. > > Does anybody vote for "no"?
>>> * What is the correct placement rule for register pieces? ABI-defined >>> or lsb0-ordered? If lsb0-ordered, how exactly is that order defined >>> for non-integer registers? >> >> "If the location is a register, the offset is from the least >> significant bit end of the register." >> Does this text from the latest draft answer the question? >> If not, can you give an example where it isn't? > > The definition of DW_OP_piece differs, though: "[...] the placement of > the piece within that register is defined by the ABI." Right. For instance, a big-endian ABI (MIPS O32, N32, N64 all come to mind) may specify that small structures are passed "left aligned" in one or more registers (i.e., in the high bytes of the register). This is so that a word-sized load/store of the register puts the struct at the correct address. 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). / (for the record, the GCC MIPS compilers I looked at - up to 6.x - all generated wrong debug info for this case - the never written to memory structure was described as being in memory) >>> * Shall DW_OP_bit_piece ignore the offset for stack- and implicit >>> values? >> >> "If the location is any implicit value or stack value, the >> DW_OP_bit_piece operation describes a sequence of bits using the least >> significant bits of that value." >> >> No. > > Really? IMHO the wording implies that the least significant bit always > belongs to the piece. > >>> * What is the "least significant bit" of an implicit value? And is it >>> intentional that the placement rule differs between implicit- and >>> memory values? >> >> I don't know. >> >>> >>> * Some DWARF producers describe a register pair just with a single >>> DW_OP_reg<n>. Can a register piece reach into the next register like >>> that as well? >> >> You mean for a pair of r1,r2 they would emit only DW_OP_reg1? I don't >> think this use is supported by the DWARF specification. > > OK. Are there other opinions? STABS, and early DWARF emitters liked to do this. For instance, a 64-bit value passed in two adjacent 32-bit registers would only have the first (even) register specified and then rely on "magic". DWARF introduced DW_OP_piece et.al. as a way to get away from this so a modern ABI trying to recommend the old behaviour will likely get laughed at :-) BTW a variation of this is still standard. For instance, something like: float f; // DW_OP_reg st0 While st0 is 80-bit, f is 32-bit, and it is assumed that the consumer performs an implicit conversion. >>> * Is "DW_OP_reg*" followed by "DW_OP_piece(size of object type)" always >>> equivalent to omitting the piece operation? >> >> If sizeof(obj) == sizeof(reg) it is obviously. >> If sizeof(obj) > sizeof(reg) the expression is malformed because there >> are undefined bits in the object that should have been represented >> with an empty DW_OP_piece. > > GCC may describe a long double struct member on x86 as > > DW_OP_regx: 33 (st0); DW_OP_piece: 16 > > where st0 is only 10 bytes wide. Is that invalid then? While something like: DW_OP_reg st0; DW_OP_piece 12; DW_OP_piece 4; might be less ambiguous and safer on a big-endian architecture, the above does have a reasonable little-endian interpretation. Since these existing operations are long standing these edge cases will have already been defined (perhaps implicitly) by the existing ABIs. >> If sizeof(obj) < sizeof(reg) the expression is overspecified, but >> still sound, so I would say yes. > > So you'd say the placement rules for DW_OP_reg* and DW_OP_piece shall be > compatible, both defined by the ABI -- not necessarily lsb0-ordered? > And the bytes referred to by a "DW_OP_reg*"-location may depend on the > object's size, but not its type, right? > > Note that this wouldn't work well with cases like the "SPU preferred > slots"; see https://sourceware.org/ml/gdb/2016-01/msg00013.html, section > 2.2. 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. Andrew _______________________________________________ Dwarf-Discuss mailing list Dwarf-Discuss@lists.dwarfstd.org http://lists.dwarfstd.org/listinfo.cgi/dwarf-discuss-dwarfstd.org