I noticed an object file with DW_OP_reg4 DW_OP_breg4 0 as a DWARF expression, which I traced to a missing break (and ++I) in this code snippet. While I was at it, I also added support for a few other corner cases along the same lines that I could think of. Please have a look - I've read the DWARF spec, but am I by no means an expert.
Details
Diff Detail
- Repository
- rL LLVM
Event Timeline
Thanks for looking into this! I have a few questions inline.
lib/CodeGen/AsmPrinter/DwarfDebug.cpp | ||
---|---|---|
1565 ↗ | (On Diff #27277) | Hopefully this can become an assertion with Duncan's pending patch. |
lib/CodeGen/AsmPrinter/DwarfExpression.cpp | ||
219 ↗ | (On Diff #27277) | This comment now needs to be moved down to the "if (DW_OP_deref)" block. |
237 ↗ | (On Diff #27277) | The indirection here seems wrong: |
We could also be in the case that N == E. I think the right thing to do is actually to put the AddOpStackValue(); here, AddExpression below will add the DW_OP_piece if there is one.
That's what I meant with the regex-style question at the end of "DW_OP_reg Offset DW_OP_plus (DW_OP_bit_Piece x y)?".
My point was that in either case, the DW_OP_plus is the last arithmetic operation and that in the absence of a DW_OP_deref we should not be emitting an (=breg) register-indirect value.
The IR-expression
[machinereg no. 5] 4 DW_OP_plus
should translate into
DW_OP_reg DW_OP_constu 5 DW_OP_plus
and not into
DW_OP_breg 5 DW_OP_constu 5 DW_OP_plus
Is DW_OP_reg5 DW_OP_plus_uconst 4 actually valid DWARF? My reading of the spec was that you had to express that as
DW_OP_breg5 4 DW_OP_stack_value, but of course I can't argue with a DWARF committee member ;).
Oh you definitely should, especially if they are giving sloppy examples!
What I should have written is: The IR
[machinereg no. 5] 4 DW_OP_plus
should become (in DWARF v5):
DW_OP_regval_type 5 [type ofs] DW_OP_constu 4 DW_OP_plus DW_OP_stack_value
whereas the IR
[machinereg no. 5] 4 DW_OP_plus DW_OP_deref
should become (in any DWARF version):
DW_OP_breg 5
You are absolutely correct that the first expression isn't actually expressible in DWARF 4 and before.
Ok, just for clarity, why wouldn't DW_OP_breg5 4 DW_OP_stack_value work for the first case?
I think you're right. The definition of DW_OP_stack_value is vague but the examples speak a clear language:
DW_OP_breg5 4
is equivalent to
DW_OP_breg5 4 DW_OP_deref DW_OP_stack_value
and means (in C notation)
*(reg5+4)
And
DW_OP_breg5 4 DW_OP_stack_value
indeed means
reg5+4
This convinced me that we really need a much better separation between the DWARF 4 and pre-DWARF 4 expression generation. No need to address this in this patch, but this needs to be fixed.
Thanks!