https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128297
Bug ID: 128297
Summary: [LoongArch] loongarch_emit_probe_stack_range omits
RTX_FRAME_RELATED_P/CFI notes on intermediate SP
adjustments
Product: gcc
Version: 16.2.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: target
Assignee: unassigned at gcc dot gnu.org
Reporter: 220245569 at seu dot edu.cn
CC: 220255623 at seu dot edu.cn, jianhao.xu at seu dot edu.cn
Target Milestone: ---
Target: loongarch64-*-*
Summary
-------
Under `-O2 -fstack-clash-protection` (with default
`-fasynchronous-unwind-tables`),
the LoongArch prologue emits intermediate stack-pointer decrements during stack
probing without `RTX_FRAME_RELATED_P` or `REG_CFA_*` notes.
In `gcc/config/loongarch/loongarch.cc:1177-1221`
(`loongarch_emit_probe_stack_range`),
every `sub.d $r3, $r3, $r14` instruction is emitted via plain `emit_insn (...)`
without marking the insn frame-related. The total frame adjustment is only
recorded retroactively on the trailing blockage insn via
`loongarch_set_frame_expr`
(`loongarch.cc:1354-1360`).
Because `dwarf2cfi` only inspects frame-related instructions, the DWARF FDE
claims `CFA = $r3 + 16` across the entire multi-instruction (or multi-iteration
loop) probe sequence even after `$r3` has been decremented by thousands of
bytes.
Any asynchronous unwind (e.g. `perf`, `SIGPROF`, crash backtrace, or debugger
step) landing inside the probe sequence computes a bogus CFA.
Reproducer
----------
$ cat trigger.c
__attribute__((noinline)) void leaf (void);
void caller (void) {
volatile char pad[8160];
leaf ();
pad[0] = 1;
}
Compile flag: loongarch64-linux-gnu-gcc -O2 -fstack-clash-protection
-fasynchronous-unwind-tables -S trigger.c
$ cat trigger.s
caller:
.LFB0:
.cfi_startproc
addi.d $r3,$r3,-16
.cfi_def_cfa_offset 16
lu12i.w $r14,1
st.d $r1,$r3,8
sub.d $r3,$r3,$r14 # sp -= 4096 (missing
.cfi_def_cfa_offset!)
st.d $r0,$r3,0
ori $r14,$r0,4064
sub.d $r3,$r3,$r14 # sp -= 4064 (missing
.cfi_def_cfa_offset!)
.cfi_def_cfa_offset 8176 # emitted only at the end of the probe
sequence
la.local $r12,leaf
jirl $r1,$r12,0
Suggested Fix
-------------
Attach `RTX_FRAME_RELATED_P` and `REG_CFA_ADJUST_CFA` notes to each
stack-pointer
adjustment emitted in `loongarch_emit_probe_stack_range` (or switch to a
frame-related scratch register for loop probing).