This is an archive of the discontinued LLVM Phabricator instance.

[llvm-readobj] [ARMWinEH] Print ARM64 packed unwind info
ClosedPublic

Authored by mstorsjo on Sep 9 2020, 4:45 AM.

Details

Summary

In addition to printing the individual fields, synthesize and print the corresponding prolog for the unwind info (in reverse order, to match how it's printed for non-packed unwind info).

Diff Detail

Event Timeline

mstorsjo created this revision.Sep 9 2020, 4:45 AM
mstorsjo requested review of this revision.Sep 9 2020, 4:45 AM
efriedma added inline comments.Sep 9 2020, 2:17 PM
llvm/tools/llvm-readobj/ARMWinEHPrinter.cpp
1162

Maybe add a comment noting the source of this algorithm.

I guess the steps are in reverse order from the documentation?

1191

I don't understand the if (RF.RegI() + RF.RegF() > 0) check; if the function homes registers, the homing region have to be contiguous.

That said, the compiler could stick any sequence of four instructions here, really; maybe we should just print them as nops.

mstorsjo added inline comments.Sep 9 2020, 11:51 PM
llvm/tools/llvm-readobj/ARMWinEHPrinter.cpp
1162

Yes, that's right; will mention that in a comment.

1191

Normally, if RegI or RegF are nonzero (that was just an obscure way of writing if (RegI() > 0 || RegF() > 0)), either of them will have done the predecrement, e.g. like in the testcase for func5, in forward order:

str x19, [sp, #-80]!
stp x0, x1, [sp, #8]
stp x2, x3, [sp, #24]
stp x4, x5, [sp, #40]
stp x6, x7, [sp, #56]

However, if both RegI and RegF are zero (and CR != 1, I think I haven't covered that case), neither of the instructions that normally would have done the predecrement by decrementing the stack by SavSZ (which includes the homing area) have existed, and the only sensible way of writing that prologue would be

stp x0, x1, [sp, #-64]!
stp x2, x3, [sp, #16]
stp x4, x5, [sp, #32]
stp x6, x7, [sp, #48]
sub sp, sp, #LocSZ

(which is func6 in the testcase). For that case, one would have SavSZ = 64 and LocSZ = FrameSize - 64, and the final stack decrement doesn't include the 64 bytes that are expected to have been decremented as SavSZ. So for that case, the equivalent unwinding opcodes would be "alloc_s 64, nop, nop, nop", instead of four nops.

Technically yes, the compiler could stick any sequence of instructions there as it just is nops, unwidning-wise, but I think printing this makes it clearer, as to where exactly the homing region is relative to the stack pointer.

mstorsjo updated this revision to Diff 290883.Sep 9 2020, 11:53 PM

Added a comment about the reference for synthesizing the prologue, fixed the homing area stack adjustment check for RegI=0, RegF=0, CR=1, added a testcase for that case and expanded on the comment for that bit in the code.

efriedma added inline comments.Sep 10 2020, 6:05 PM
llvm/test/tools/llvm-readobj/COFF/arm64-packed-unwind.s
59

"sub sp, sp, #0" is a no-op. Is that really the right interpretation?

llvm/tools/llvm-readobj/ARMWinEHPrinter.cpp
1191

Hmm. I guess that makes sense.

mstorsjo added inline comments.Sep 11 2020, 12:24 AM
llvm/test/tools/llvm-readobj/COFF/arm64-packed-unwind.s
59

If strictly following the steps for the equivalent prologue in the docs for the packed format, the "sub sp, sp, #0" corresponds to step 5d/5e. But I guess it's a matter of taste whether to print it or not (and I don't feel strongly about it).

As this is the last instruction in the prologue/first in the epilogue, it shouldn't really matter whether it's included or not, even when unwinding. If it's considered included in the synthesized prologue, the prologue becomes one instruction longer. If unwinding from that particular location, it could consider the unwind part starting from an unfinished prologue and skip the "sub sp, sp, #0" synthesized instruction, which has no effect. Or if it's not included in the synthesized prologue, the unwind is considered originating in the body of the function, and executing the full prologue, with the same effect.

So it's just a matter of taste and/or trying to stick closely to the spec where possible.

efriedma added inline comments.Sep 11 2020, 3:45 PM
llvm/test/tools/llvm-readobj/COFF/arm64-packed-unwind.s
59

I'd prefer to match what MSVC would actually generate where possible.

mstorsjo updated this revision to Diff 291374.Sep 11 2020, 10:39 PM

Removed superfluous "sub sp, sp, #0".

This revision is now accepted and ready to land.Sep 14 2020, 2:05 PM
This revision was automatically updated to reflect the committed changes.