https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119610
Bug ID: 119610 Summary: aarch64: Wrong unwind info with -fstack-clash-protection -fstack-protector-strong Product: gcc Version: 15.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: acoplan at gcc dot gnu.org Target Milestone: --- The following fails: $ cat t.cc void foo() { int c[1024*128]; throw 1; } int main() { try { foo(); } catch(int x) { return 0; } } $ g++ t.cc -fstack-clash-protection -fstack-protector-strong $ ./a.out Segmentation fault GDB shows us crashing in the unwinder at runtime: (gdb) bt #0 0x0000fffff7ee5ec4 in aarch64_fallback_frame_state (context=0xfffffff7e938, fs=0xfffffff7ecf8) at ./md-unwind-support.h:74 #1 uw_frame_state_for (context=context@entry=0xfffffff7e938, fs=fs@entry=0xfffffff7ecf8) at /home/alecop01/toolchain/src/gcc/libgcc/unwind-dw2.c:1016 #2 0x0000fffff7ee73d8 in _Unwind_RaiseException (exc=0x424310) at /home/alecop01/toolchain/src/gcc/libgcc/unwind.inc:104 #3 0x0000fffff7cb7174 in __cxxabiv1::__cxa_throw (obj=0x424330, tinfo=0x410d90 <typeinfo for int@CXXABI_1.3>, dest=<optimized out>) at /home/alecop01/toolchain/src/gcc/libstdc++-v3/libsupc++/eh_throw.cc:93 #4 0x0000000000400a44 in foo() () #5 0xdcbbeb69daccf500 in ?? () compiling to an object file and looking at the codegen we have: 0000000000000000 <_Z3foov>: 0: a9bf7bfd stp x29, x30, [sp, #-16]! 4: 910003fd mov x29, sp 8: d14203ed sub x13, sp, #0x80, lsl #12 c: d14043ff sub sp, sp, #0x10, lsl #12 10: f90203ff str xzr, [sp, #1024] 14: eb2d63ff cmp sp, x13 18: 54ffffa1 b.ne c <_Z3foov+0xc> // b.any 1c: d10043ff sub sp, sp, #0x10 20: f90203ff str xzr, [sp, #1024] 24: 90000000 adrp x0, 0 <__stack_chk_guard> 28: 91000000 add x0, x0, #0x0 2c: 914203e1 add x1, sp, #0x80, lsl #12 30: f9400002 ldr x2, [x0] 34: f9000422 str x2, [x1, #8] 38: d2800002 mov x2, #0x0 // #0 3c: d2800080 mov x0, #0x4 // #4 40: 94000000 bl 0 <__cxa_allocate_exception> 44: 52800021 mov w1, #0x1 // #1 48: b9000001 str w1, [x0] 4c: 90000001 adrp x1, 0 <__stack_chk_guard> 50: 91000021 add x1, x1, #0x0 54: 914203e3 add x3, sp, #0x80, lsl #12 58: f9400464 ldr x4, [x3, #8] 5c: f9400022 ldr x2, [x1] 60: eb020084 subs x4, x4, x2 64: d2800002 mov x2, #0x0 // #0 68: 54000040 b.eq 70 <_Z3foov+0x70> // b.none 6c: 94000000 bl 0 <__stack_chk_fail> 70: d2800002 mov x2, #0x0 // #0 74: 90000001 adrp x1, 0 <_ZTIi> 78: 91000021 add x1, x1, #0x0 7c: 94000000 bl 0 <__cxa_throw> and readelf -w shows the following DWARF for this function: 00000014 0000000000000024 00000018 FDE cie=00000000 pc=0000000000000000..0000000000000080 DW_CFA_advance_loc: 4 to 0000000000000004 DW_CFA_def_cfa_offset: 16 DW_CFA_offset: r29 (x29) at cfa-16 DW_CFA_offset: r30 (x30) at cfa-8 DW_CFA_advance_loc: 8 to 000000000000000c DW_CFA_def_cfa: r13 (x13) ofs 524288 DW_CFA_advance_loc: 16 to 000000000000001c DW_CFA_def_cfa_register: r31 (sp) DW_CFA_advance_loc: 4 to 0000000000000020 DW_CFA_def_cfa_offset: 524304 DW_CFA_nop DW_CFA_nop so after the first stp insn we have: DW_CFA_def_cfa_offset: 16 which tells us the CFA is the value of the sp on entry to the function. Things get more interesting with: DW_CFA_advance_loc: 8 to 000000000000000c DW_CFA_def_cfa: r13 (x13) ofs 524288 This tells us that at foo+0xc, we should have: x13 + 524288 == CFA, but looking at the generated code, we actually have: x13 + 524288 == CFA - 16 since x13 is computed with: 8: d14203ed sub x13, sp, #0x80, lsl #12 i.e. x13 = sp - 524288. But at this point we should have: sp + 16 == CFA due to the initial adjustment from the stp. Hence the unwind info is inconsistent. Looking at the generated code with: $ g++ -fstack-protector-strong -fstack-clash-protection t.cc -c -S -o - _Z3foov: .LFB0: .cfi_startproc stp x29, x30, [sp, -16]! .cfi_def_cfa_offset 16 .cfi_offset 29, -16 .cfi_offset 30, -8 mov x29, sp sub x13, sp, #524288 .cfi_def_cfa 13, 524288 // shouldn't this be 524304? This seems to reproduce with at least GCC 14 and trunk.