@@ -851,19 +851,31 @@ static void elf_init_ehframe(ELFObjectContext* ctx) {
851851 DWRF_U32 (0 ); // CIE ID (0 indicates this is a CIE)
852852 DWRF_U8 (DWRF_CIE_VERSION ); // CIE version (1)
853853 DWRF_STR ("zR" ); // Augmentation string ("zR" = has LSDA)
854- DWRF_UV (1 ); // Code alignment factor
854+ #ifdef __x86_64__
855+ DWRF_UV (1 ); // Code alignment factor (x86_64: 1 byte)
856+ #elif defined(__aarch64__ ) && defined(__AARCH64EL__ ) && !defined(__ILP32__ )
857+ DWRF_UV (4 ); // Code alignment factor (AArch64: 4 bytes per instruction)
858+ #endif
855859 DWRF_SV (- (int64_t )sizeof (uintptr_t )); // Data alignment factor (negative)
856860 DWRF_U8 (DWRF_REG_RA ); // Return address register number
857861 DWRF_UV (1 ); // Augmentation data length
858862 DWRF_U8 (DWRF_EH_PE_pcrel | DWRF_EH_PE_sdata4 ); // FDE pointer encoding
859863
860864 /* Initial CFI instructions - describe default calling convention */
865+ #ifdef __x86_64__
866+ /* x86_64 initial CFI state */
861867 DWRF_U8 (DWRF_CFA_def_cfa ); // Define CFA (Call Frame Address)
862868 DWRF_UV (DWRF_REG_SP ); // CFA = SP register
863869 DWRF_UV (sizeof (uintptr_t )); // CFA = SP + pointer_size
864870 DWRF_U8 (DWRF_CFA_offset |DWRF_REG_RA ); // Return address is saved
865871 DWRF_UV (1 ); // At offset 1 from CFA
866-
872+ #elif defined(__aarch64__ ) && defined(__AARCH64EL__ ) && !defined(__ILP32__ )
873+ /* AArch64 initial CFI state */
874+ DWRF_U8 (DWRF_CFA_def_cfa ); // Define CFA (Call Frame Address)
875+ DWRF_UV (DWRF_REG_SP ); // CFA = SP register
876+ DWRF_UV (0 ); // CFA = SP + 0 (AArch64 starts with offset 0)
877+ // No initial register saves in AArch64 CIE
878+ #endif
867879 DWRF_ALIGNNOP (sizeof (uintptr_t )); // Align to pointer boundary
868880 )
869881
@@ -911,19 +923,18 @@ static void elf_init_ehframe(ELFObjectContext* ctx) {
911923 DWRF_UV (8 ); // New offset: SP + 8
912924#elif defined(__aarch64__ ) && defined(__AARCH64EL__ ) && !defined(__ILP32__ )
913925 /* AArch64 calling convention unwinding rules */
914- DWRF_U8 (DWRF_CFA_advance_loc | 1 ); // Advance location by 1 instruction (stp x29, x30)
915- DWRF_U8 (DWRF_CFA_def_cfa_offset ); // Redefine CFA offset
916- DWRF_UV (16 ); // CFA = SP + 16 (stack pointer after push)
917- DWRF_U8 (DWRF_CFA_offset | DWRF_REG_FP ); // Frame pointer (x29) saved
918- DWRF_UV (2 ); // At offset 2 from CFA (2 * 8 = 16 bytes)
919- DWRF_U8 (DWRF_CFA_offset | DWRF_REG_RA ); // Link register (x30) saved
920- DWRF_UV (1 ); // At offset 1 from CFA (1 * 8 = 8 bytes)
921- DWRF_U8 (DWRF_CFA_advance_loc | 3 ); // Advance by 3 instructions (mov x16, x3; mov x29, sp; ldp...)
922- DWRF_U8 (DWRF_CFA_offset | DWRF_REG_FP ); // Restore frame pointer (x29)
923- DWRF_U8 (DWRF_CFA_offset | DWRF_REG_RA ); // Restore link register (x30)
924- DWRF_U8 (DWRF_CFA_def_cfa_offset ); // Final CFA adjustment
925- DWRF_UV (0 ); // CFA = SP + 0 (stack restored)
926-
926+ DWRF_U8 (DWRF_CFA_advance_loc | 1 ); // Advance by 1 instruction (4 bytes)
927+ DWRF_U8 (DWRF_CFA_def_cfa_offset ); // CFA = SP + 16
928+ DWRF_UV (16 ); // Stack pointer moved by 16 bytes
929+ DWRF_U8 (DWRF_CFA_offset | DWRF_REG_FP ); // x29 (frame pointer) saved
930+ DWRF_UV (2 ); // At CFA-16 (2 * 8 = 16 bytes from CFA)
931+ DWRF_U8 (DWRF_CFA_offset | DWRF_REG_RA ); // x30 (link register) saved
932+ DWRF_UV (1 ); // At CFA-8 (1 * 8 = 8 bytes from CFA)
933+ DWRF_U8 (DWRF_CFA_advance_loc | 3 ); // Advance by 3 instructions (12 bytes)
934+ DWRF_U8 (DWRF_CFA_restore | DWRF_REG_RA ); // Restore x30 - NO DWRF_UV() after this!
935+ DWRF_U8 (DWRF_CFA_restore | DWRF_REG_FP ); // Restore x29 - NO DWRF_UV() after this!
936+ DWRF_U8 (DWRF_CFA_def_cfa_offset ); // CFA = SP + 0 (stack restored)
937+ DWRF_UV (0 ); // Back to original stack position
927938#else
928939# error "Unsupported target architecture"
929940#endif
0 commit comments