@@ -401,10 +401,12 @@ enum {
401
401
DWRF_CFA_nop = 0x0 , // No operation
402
402
DWRF_CFA_offset_extended = 0x5 , // Extended offset instruction
403
403
DWRF_CFA_def_cfa = 0xc , // Define CFA rule
404
+ DWRF_CFA_def_cfa_register = 0xd , // Define CFA register
404
405
DWRF_CFA_def_cfa_offset = 0xe , // Define CFA offset
405
406
DWRF_CFA_offset_extended_sf = 0x11 , // Extended signed offset
406
407
DWRF_CFA_advance_loc = 0x40 , // Advance location counter
407
- DWRF_CFA_offset = 0x80 // Simple offset instruction
408
+ DWRF_CFA_offset = 0x80 , // Simple offset instruction
409
+ DWRF_CFA_restore = 0xc0 // Restore register
408
410
};
409
411
410
412
/* DWARF Exception Handling pointer encodings */
@@ -868,17 +870,22 @@ static void elf_init_ehframe(ELFObjectContext* ctx) {
868
870
* conventions and register usage patterns.
869
871
*/
870
872
#ifdef __x86_64__
871
- /* x86_64 calling convention unwinding rules */
873
+ /* x86_64 calling convention unwinding rules with frame pointer */
872
874
# if defined(__CET__ ) && (__CET__ & 1 )
873
- DWRF_U8 (DWRF_CFA_advance_loc | 8 ); // Advance location by 8 bytes when CET protection is enabled
874
- # else
875
- DWRF_U8 (DWRF_CFA_advance_loc | 4 ); // Advance location by 4 bytes
875
+ DWRF_U8 (DWRF_CFA_advance_loc | 4 ); // Advance past endbr64 (4 bytes)
876
876
# endif
877
- DWRF_U8 (DWRF_CFA_def_cfa_offset ); // Redefine CFA offset
878
- DWRF_UV (16 ); // New offset: SP + 16
879
- DWRF_U8 (DWRF_CFA_advance_loc | 6 ); // Advance location by 6 bytes
880
- DWRF_U8 (DWRF_CFA_def_cfa_offset ); // Redefine CFA offset
881
- DWRF_UV (8 ); // New offset: SP + 8
877
+ DWRF_U8 (DWRF_CFA_advance_loc | 1 ); // Advance past push %rbp (1 byte)
878
+ DWRF_U8 (DWRF_CFA_def_cfa_offset ); // def_cfa_offset 16
879
+ DWRF_UV (16 );
880
+ DWRF_U8 (DWRF_CFA_offset | DWRF_REG_BP ); // offset r6 at cfa-16
881
+ DWRF_UV (2 );
882
+ DWRF_U8 (DWRF_CFA_advance_loc | 3 ); // Advance past mov %rsp,%rbp (3 bytes)
883
+ DWRF_U8 (DWRF_CFA_def_cfa_register ); // def_cfa_register r6
884
+ DWRF_UV (DWRF_REG_BP );
885
+ DWRF_U8 (DWRF_CFA_advance_loc | 3 ); // Advance past call *%rcx (2 bytes) + pop %rbp (1 byte) = 3
886
+ DWRF_U8 (DWRF_CFA_def_cfa ); // def_cfa r7 ofs 8
887
+ DWRF_UV (DWRF_REG_SP );
888
+ DWRF_UV (8 );
882
889
#elif defined(__aarch64__ ) && defined(__AARCH64EL__ ) && !defined(__ILP32__ )
883
890
/* AArch64 calling convention unwinding rules */
884
891
DWRF_U8 (DWRF_CFA_advance_loc | 1 ); // Advance location by 1 instruction (stp x29, x30)
0 commit comments