diff options
author | Ammar Faizi <ammarfaizi2@gnuweeb.org> | 2023-08-30 08:02:23 +0700 |
---|---|---|
committer | Thomas Weißschuh <linux@weissschuh.net> | 2023-10-12 21:10:37 +0200 |
commit | d873a364ef2182af40110869f9c62813ce6f9386 (patch) | |
tree | c9786185287ee20830cd48dd87a90cf6f5f0e584 /fs | |
parent | 0bb80ecc33a8fb5a682236443c1e740d5c917d1d (diff) |
tools/nolibc: i386: Fix a stack misalign bug on _start
The ABI mandates that the %esp register must be a multiple of 16 when
executing a 'call' instruction.
Commit 2ab446336b17 ("tools/nolibc: i386: shrink _start with _start_c")
simplified the _start function, but it didn't take care of the %esp
alignment, causing SIGSEGV on SSE and AVX programs that use aligned move
instruction (e.g., movdqa, movaps, and vmovdqa).
The 'and $-16, %esp' aligns the %esp at a multiple of 16. Then 'push
%eax' will subtract the %esp by 4; thus, it breaks the 16-byte
alignment. Make sure the %esp is correctly aligned after the push by
subtracting 12 before the push.
Extra:
Add 'add $12, %esp' before the 'and $-16, %esp' to avoid over-estimating
for particular cases as suggested by Willy.
A test program to validate the %esp alignment on _start can be found at:
https://lore.kernel.org/lkml/ZOoindMFj1UKqo+s@biznet-home.integral.gnuweeb.org
[ Thomas: trim Fixes tag commit id ]
Cc: Zhangjin Wu <falcon@tinylab.org>
Fixes: 2ab446336b17 ("tools/nolibc: i386: shrink _start with _start_c")
Reported-by: Nicholas Rosenberg <inori@vnlx.org>
Acked-by: Thomas Weißschuh <linux@weissschuh.net>
Signed-off-by: Ammar Faizi <ammarfaizi2@gnuweeb.org>
Reviewed-by: Alviro Iskandar Setiawan <alviro.iskandar@gnuweeb.org>
Signed-off-by: Willy Tarreau <w@1wt.eu>
Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
Diffstat (limited to 'fs')
0 files changed, 0 insertions, 0 deletions