--- /dev/null
+// REQUIRES: aarch64-registered-target
+// RUN: llvm-mc -filetype=obj -triple aarch64-windows %s -o %t.o
+// RUN: llvm-readobj --unwind %t.o | FileCheck %s
+
+// CHECK: UnwindInformation [
+// CHECK-NEXT: RuntimeFunction {
+// CHECK-NEXT: Function: func
+// CHECK-NEXT: Fragment: No
+// CHECK-NEXT: FunctionLength: 44
+// CHECK-NEXT: RegF: 0
+// CHECK-NEXT: RegI: 0
+// CHECK-NEXT: HomedParameters: No
+// CHECK-NEXT: CR: 2
+// CHECK-NEXT: FrameSize: 32
+// CHECK-NEXT: Prologue [
+// CHECK-NEXT: mov x29, sp
+// CHECK-NEXT: stp x29, lr, [sp, #-32]!
+// CHECK-NEXT: pacibsp
+// CHECK-NEXT: end
+// CHECK-NEXT: ]
+// CHECK-NEXT: }
+// CHECK-NEXT: ]
+
+ .text
+ .globl func
+func:
+ ret
+
+ .section .pdata,"dr"
+ .long func@IMGREL
+ .long 0x0140002d // FunctionLength=11 RegF=0 RegI=0 H=0 CR=2 FrameSize=2
--- /dev/null
+// REQUIRES: aarch64-registered-target
+// RUN: llvm-mc -filetype=obj -triple aarch64-windows %s -o %t.o
+// RUN: llvm-readobj --unwind %t.o | FileCheck --strict-whitespace %s
+
+// CHECK: Prologue [
+// CHECK-NEXT: 0xd600 ; stp x19, lr, [sp, #0]
+// CHECK-NEXT: 0x01 ; sub sp, #16
+// CHECK-NEXT: 0xfc ; pacibsp
+// CHECK-NEXT: 0xe4 ; end
+// CHECK-NEXT: ]
+// CHECK-NEXT: Epilogue [
+// CHECK-NEXT: 0x01 ; add sp, #16
+// CHECK-NEXT: 0xfc ; autibsp
+// CHECK-NEXT: 0xe4 ; end
+// CHECK-NEXT: ]
+
+.section .pdata,"dr"
+ .long func@IMGREL
+ .long "$unwind$func"@IMGREL
+
+ .text
+ .globl func
+func:
+ pacibsp
+ sub sp, sp, #16
+ stp x19, x30, [sp]
+ mov w19, w1
+ blr x0
+ mov w0, w19
+ ldp x19, x30, [sp]
+ add sp, sp, #16
+ autibsp
+ ret
+
+.section .xdata,"dr"
+"$unwind$func":
+.byte 0x0a, 0x00, 0xa0, 0x10
+.byte 0xd6, 0x00, 0x01, 0xfc
+.byte 0xe4, 0xe3, 0xe3, 0xe3
{0xff, 0xe9, 1, &Decoder::opcode_machine_frame},
{0xff, 0xea, 1, &Decoder::opcode_context},
{0xff, 0xec, 1, &Decoder::opcode_clear_unwound_to_call},
+ {0xff, 0xfc, 1, &Decoder::opcode_pac_sign_return_address},
};
static void printRange(raw_ostream &OS, ListSeparator &LS, unsigned First,
return false;
}
+bool Decoder::opcode_pac_sign_return_address(const uint8_t *OC,
+ unsigned &Offset, unsigned Length,
+ bool Prologue) {
+ if (Prologue)
+ SW.startLine() << format("0x%02x ; pacibsp\n", OC[Offset]);
+ else
+ SW.startLine() << format("0x%02x ; autibsp\n", OC[Offset]);
+ ++Offset;
+ return false;
+}
+
void Decoder::decodeOpcodes(ArrayRef<uint8_t> Opcodes, unsigned Offset,
bool Prologue) {
assert((!Prologue || Offset == 0) && "prologue should always use offset 0");
int SavSZ = (IntSZ + FpSZ + 8 * 8 * RF.H() + 0xf) & ~0xf;
int LocSZ = (RF.FrameSize() << 4) - SavSZ;
- if (RF.CR() == 3) {
+ if (RF.CR() == 2 || RF.CR() == 3) {
SW.startLine() << "mov x29, sp\n";
if (LocSZ <= 512) {
SW.startLine() << format("stp x29, lr, [sp, #-%d]!\n", LocSZ);
if (LocSZ > 4080) {
SW.startLine() << format("sub sp, sp, #%d\n", LocSZ - 4080);
SW.startLine() << "sub sp, sp, #4080\n";
- } else if ((RF.CR() != 3 && LocSZ > 0) || LocSZ > 512) {
+ } else if ((RF.CR() != 3 && RF.CR() != 2 && LocSZ > 0) || LocSZ > 512) {
SW.startLine() << format("sub sp, sp, #%d\n", LocSZ);
}
if (RF.H()) {
19 + 2 * I + 1, 16 * I);
}
}
+ // CR=2 is yet undocumented, see
+ // https://github.com/MicrosoftDocs/cpp-docs/pull/4202 for upstream
+ // progress on getting it documented.
+ if (RF.CR() == 2)
+ SW.startLine() << "pacibsp\n";
SW.startLine() << "end\n";
return true;