https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124538
Bug ID: 124538
Summary: gcc/g++ -S target x86_64: unreliable local frame stack
unwinding and alloca
Product: gcc
Version: 12.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: target
Assignee: unassigned at gcc dot gnu.org
Reporter: grizlyk1 at yandex dot ru
Target Milestone: ---
1.
$ g++ --version
g++ (GCC) 11.4.0
Copyright (C) 2021 Free Software Foundation, Inc.
$ uname -a
CYGWIN_NT-6.1-7601 w7x64t0p-vm 3.4.10-1.x86_64 2023-11-29 12:12 UTC x86_64
Cygwin
this is not mostly resent gcc version, but i suspect the newest version does
the same, i can not check newer gcc version online (inet provider uses
"firewall" and silly servers drops network requests without reply) and it is
hard to me to install new gcc version into the VM just to find out the bug the
same
2.
consider C/C++ compiled to asm function code example
_Z2f1v:
pushq %rbp
.seh_pushreg %rbp
movq %rsp, %rbp
.seh_setframe %rbp, 0
subq $48, %rsp
.seh_stackalloc 48
.seh_endprologue
movl $0, -4(%rbp)
movl $4, %edx
leaq .LC0(%rip), %rax
movq %rax, %rcx
call printf
nop
addq $48, %rsp
# here incorrect "add SP, value" opcode
popq %rbp
ret
function local frame stack pointer (SP) should be restored to external frame
pointer not by addition to current SP value, but by reserved for the purpose SP
value stored in BP
funcion should implement "leave" behaviour, not "add SP, value" opcode
instead of
addq $48, %rsp
compiler should always do
movq %rbp, %rsp # here %rbp contains correct value of external
SP
because in general case current SP value can be damaged by the function broken
code, signal handlers, etc and funcion should always try to limit the possible
damage memory area by own local stack frame, funcion should not return own
possible damaged frame pointer to external contex
2.1
note, if we try to use "alloca", compiler will do correct implementaion of
"leave" behaviour, not "add SP, value" opcode
movq %rbp, %rsp
popq %rbp
ret
2.2
the simplest workwaround is always unconditionally insert "movq %rbp, %rsp"
before "popq %rbp", so the original example will be
call printf
nop
addq $48, %rsp
# old useless "add SP, value" opcode, but no harm
movq %rbp, %rsp
# unconditionally inserted "leave" behaviour
popq %rbp
ret
===