Skip to content

Commit e2219a1

Browse files
committed
Fix DWARF CFI to account for aarch64 PAC/BTI instructions
1 parent acae86e commit e2219a1

1 file changed

Lines changed: 13 additions & 0 deletions

File tree

Python/jit_unwind.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ enum {
6060
DWRF_CFA_offset_extended_sf = 0x11, // Extended signed offset
6161
DWRF_CFA_advance_loc = 0x40, // Advance location counter
6262
DWRF_CFA_offset = 0x80, // Simple offset instruction
63+
#if defined(__aarch64__)
64+
DWRF_CFA_AARCH64_negate_ra_state = 0x2d, // Toggle return address signing state
65+
#endif
6366
DWRF_CFA_restore = 0xc0 // Restore register
6467
};
6568

@@ -562,6 +565,13 @@ static void elf_init_ehframe_perf(ELFObjectContext* ctx) {
562565
DWRF_UV(8); // New offset: SP + 8
563566
#elif defined(__aarch64__) && defined(__AARCH64EL__) && !defined(__ILP32__)
564567
/* AArch64 calling convention unwinding rules */
568+
#if defined(__ARM_FEATURE_PAC_DEFAULT) || \
569+
(defined(__ARM_FEATURE_BTI_DEFAULT) && __ARM_FEATURE_BTI_DEFAULT == 1)
570+
DWRF_U8(DWRF_CFA_advance_loc | 1); // Advance past SIGN_LR (4 bytes)
571+
#endif
572+
#if defined(__ARM_FEATURE_PAC_DEFAULT)
573+
DWRF_U8(DWRF_CFA_AARCH64_negate_ra_state); // Saved LR is PAC-signed from here
574+
#endif
565575
DWRF_U8(DWRF_CFA_advance_loc | 1); // Advance by 1 instruction (4 bytes)
566576
DWRF_U8(DWRF_CFA_def_cfa_offset); // CFA = SP + 16
567577
DWRF_UV(16); // Stack pointer moved by 16 bytes
@@ -570,6 +580,9 @@ static void elf_init_ehframe_perf(ELFObjectContext* ctx) {
570580
DWRF_U8(DWRF_CFA_offset | DWRF_REG_RA); // x30 (link register) saved
571581
DWRF_UV(1); // At CFA-8 (1 * 8 = 8 bytes from CFA)
572582
DWRF_U8(DWRF_CFA_advance_loc | 3); // Advance by 3 instructions (12 bytes)
583+
#if defined(__ARM_FEATURE_PAC_DEFAULT)
584+
DWRF_U8(DWRF_CFA_AARCH64_negate_ra_state); // LR is authenticated, no longer PAC-signed
585+
#endif
573586
DWRF_U8(DWRF_CFA_def_cfa_register); // CFA = FP (x29) + 16
574587
DWRF_UV(DWRF_REG_FP);
575588
DWRF_U8(DWRF_CFA_restore | DWRF_REG_RA); // Restore x30 - NO DWRF_UV() after this!

0 commit comments

Comments
 (0)