================
@@ -683,42 +684,143 @@
DEFINE_LIBUNWIND_FUNCTION(__libunwind_Registers_arm64_jumpto)
ldp x28,x29, [x0, #0x0E0]
#if defined(__ARM_FP) && __ARM_FP != 0
- ldp d0, d1, [x0, #0x110]
- ldp d2, d3, [x0, #0x120]
- ldp d4, d5, [x0, #0x130]
- ldp d6, d7, [x0, #0x140]
- ldp d8, d9, [x0, #0x150]
- ldp d10,d11, [x0, #0x160]
- ldp d12,d13, [x0, #0x170]
- ldp d14,d15, [x0, #0x180]
- ldp d16,d17, [x0, #0x190]
- ldp d18,d19, [x0, #0x1A0]
- ldp d20,d21, [x0, #0x1B0]
- ldp d22,d23, [x0, #0x1C0]
- ldp d24,d25, [x0, #0x1D0]
- ldp d26,d27, [x0, #0x1E0]
- ldp d28,d29, [x0, #0x1F0]
- ldr d30, [x0, #0x200]
- ldr d31, [x0, #0x208]
+ ldp d0, d1, [x0, #0x120]
+ ldp d2, d3, [x0, #0x130]
+ ldp d4, d5, [x0, #0x140]
+ ldp d6, d7, [x0, #0x150]
+ ldp d8, d9, [x0, #0x160]
+ ldp d10,d11, [x0, #0x170]
+ ldp d12,d13, [x0, #0x180]
+ ldp d14,d15, [x0, #0x190]
+ ldp d16,d17, [x0, #0x1A0]
+ ldp d18,d19, [x0, #0x1B0]
+ ldp d20,d21, [x0, #0x1C0]
+ ldp d22,d23, [x0, #0x1D0]
+ ldp d24,d25, [x0, #0x1E0]
+ ldp d26,d27, [x0, #0x1F0]
+ ldr d28, [x0, #0x200]
+ ldr d29, [x0, #0x208]
+ ldr d30, [x0, #0x210]
+ ldr d31, [x0, #0x218]
#endif
+
+ // The lr value stored in __pc might be signed with IA/IB key (as described
+ // by __ra_sign.__use_b_key field) and &__pc address as a modifier.
+ // If the lr value is signed, re-sign that with the corresponding key
+ // and initial signing scheme using __sp as a modifier and potentially
+ // involving a second modifier (as described by (__ra_sign.__state & 2)).
+
+ ldr x14, [x0, #0x0F8] // x14 = __sp
+ ldr x15, [x0, #0x110] // x15 = __ra_sign.__second_modifier
+ add x16, x0, #0x100 // x16 = &__pc
+ ldr x17, [x0, #0x100] // x17 = __pc
+
+ ldr x1, [x0, #0x108] // x1 = __ra_sign.__state
+ and x1, x1, #1
+ cbz x1, .Lresign_end
+
+ // lr needs resign
+ ldr x1, [x0, #0x108] // x1 = __ra_sign.__state
+ and x1, x1, #2
+ cbnz x1, .Lresign_with_pc
+
+ // lr needs resign without pc as a second modifier
+ ldr x1, [x0, #0x118] // x1 = __ra_sign.__use_b_key
+ cbnz x1, .Lresign_with_b_key
+
+ // lr needs resign with A key and without pc as a second modifier
+ hint 0xc // autia1716
+ mov x16, x14 // x16 = __sp
+ hint 0x8 // pacia1716
+ b .Lresign_end
+
+.Lresign_with_b_key:
+ // lr needs resign with B key and without pc as a second modifier
+ hint 0xe // autib1716
+ mov x16, x14 // x16 = __sp
+ hint 0xa // pacib1716
+ b .Lresign_end
+
+.Lresign_with_pc:
+ // lr needs resign with pc as a second modifier
+ ldr x1, [x0, #0x118] // x1 = __ra_sign.__use_b_key
+ cbnz x1, .Lresign_with_pc_b_key
+
+ // lr needs resign with A key and pc as a second modifier
+ hint 0xc // autia1716
+ mov x16, x14 // x16 = __sp
+ hint 0x27 // pacm
+ hint 0x8 // pacia1716
+ b .Lresign_end
+
+.Lresign_with_pc_b_key:
+ // lr needs resign with B key and pc as a second modifier
+ hint 0xe // autib1716
+ mov x16, x14 // x16 = __sp
+ hint 0x27 // pacm
+ hint 0xa // pacib1716
+ b .Lresign_end
+
+.Lresign_end:
+ mov lr, x17 // assign final lr value
+ ldp x14,x15, [x0, #0x070] // restore x14,x15
+ ldr x16, [x0, #0x110] // second modifier for auti{a|b}sp with PACM
+
// Finally, restore sp. This must be done after the last read from the
// context struct, because it is allocated on the stack, and an exception
// could clobber the de-allocated portion of the stack after sp has been
// restored.
+ ldr x17, [x0, #0x0F8] // load sp into scratch
- ldr x16, [x0, #0x0F8] // load sp into scratch
- ldr lr, [x0, #0x100] // restore pc into lr
+ ldr x1, [x0, #0x108] // x1 = __ra_sign.__state
+ and x1, x1, #1
+ cbz x1, .Lauth_end
-#if __has_feature(ptrauth_calls)
- // The LR is signed with its address inside the register state. Time
- // to resign to be a regular ROP protected signed pointer
- add x1, x0, #0x100
- autib lr, x1
- pacib lr, x16 // signed the scratch register for sp
-#endif
+ // lr is signed
+ ldr x1, [x0, #0x108] // x1 = __ra_sign.__state
+ and x1, x1, #2
+ cbnz x1, .Lauth_with_pc
+
+ // lr is signed without pc as a second modifier
+ ldr x1, [x0, #0x118] // x1 = __ra_sign.__use_b_key
+ cbnz x1, .Lauth_with_b_key
----------------
ojhunt wrote:
I guess you're choosing between two different signing schemes rather than
signed vs unsigned, but nonetheless you should really make the schema flag be
authenticated as well
https://github.com/llvm/llvm-project/pull/171717
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits