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