Skip to content

Commit 885509b

Browse files
authored
[llvm-readobj] [ARMWinEH] Fix the interpretation of packed unwind CR=01 RegI=1 (#169676)
Even though the table for how to expand packed unwind info at [1] doesn't explicitly say this, this case is mentioned at [2] under the case "Only x19 saved": sub sp,sp,#16 // reg save area allocation* stp x19,lr,[sp] // save x19, lr sub sp,sp,#(framesz-16) // allocate the remaining local area This was discussed and clarified at [3]. [1] https://learn.microsoft.com/en-us/cpp/build/arm64-exception-handling?view=msvc-170#packed-unwind-data [2] https://learn.microsoft.com/en-us/cpp/build/arm64-exception-handling?view=msvc-170#arm64-stack-frame-layout [3] #169588 (comment)
1 parent 96c69b7 commit 885509b

File tree

2 files changed

+10
-5
lines changed

2 files changed

+10
-5
lines changed

llvm/test/tools/llvm-readobj/COFF/arm64-packed-unwind.s

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,8 @@
139139
// CHECK-NEXT: FrameSize: 32
140140
// CHECK-NEXT: Prologue [
141141
// CHECK-NEXT: sub sp, sp, #16
142-
// CHECK-NEXT: INVALID!
142+
// CHECK-NEXT: stp x19, lr, [sp]
143+
// CHECK-NEXT: sub sp, sp, #16
143144
// CHECK-NEXT: end
144145
// CHECK-NEXT: ]
145146
// CHECK-NEXT: }

llvm/tools/llvm-readobj/ARMWinEHPrinter.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1457,10 +1457,14 @@ bool Decoder::dumpPackedARM64Entry(const object::COFFObjectFile &COFF,
14571457
// The last register, an odd register without a pair
14581458
if (RF.CR() == 1) {
14591459
if (I == 0) { // If this is the only register pair
1460-
// CR=1 combined with RegI=1 doesn't map to a documented case;
1461-
// it doesn't map to any regular unwind info opcode, and the
1462-
// actual unwinder doesn't support it.
1463-
SW.startLine() << "INVALID!\n";
1460+
// CR=1 combined with RegI=1 maps to a special case; there's
1461+
// no unwind info opcode that saves a GPR together with LR
1462+
// with writeback to sp (no save_lrpair_x).
1463+
// Instead, this case expands to two instructions; a preceding
1464+
// (in prologue execution order) "sub sp, sp, #16", followed
1465+
// by a regular "stp x19, lr, [sp]" (save_lrpair).
1466+
SW.startLine() << format("stp x%d, lr, [sp]\n", 19);
1467+
SW.startLine() << format("sub sp, sp, #%d\n", SavSZ);
14641468
} else
14651469
SW.startLine() << format("stp x%d, lr, [sp, #%d]\n", 19 + 2 * I,
14661470
16 * I);

0 commit comments

Comments
 (0)