mirror of
https://github.com/janet-lang/janet
synced 2026-10-08 16:51:41 +00:00
Protect against different vector widths (#1909)
GCC aligns alloca to the widest enabled vector type (16 bytes, 32 with avx, 64 with avx-512). With AVX the block address is `lea 0x1f(%rsp)` rounded down to the nearest 32-divisible, but half the time the block starts 16 bytes higher so the function reads the stack arguments 2 slots away from where it should. Without AVX the address is `lea 0xf(%rsp)` which is the stack pointer.
This commit is contained in:
@@ -1225,7 +1225,15 @@ static Janet janet_ffi_sysv64(JanetFFISignature *signature, void *function_point
|
||||
ret_mem = alloca(type_size(signature->ret.type));
|
||||
regs[0] = (uint64_t) ret_mem;
|
||||
}
|
||||
/* GCC aligns alloca to the widest allowed vector type (32 bytes for AVX) which can pad
|
||||
* between the stack pointer and this block, but stack args start at the stack pointer,
|
||||
* so we must ask for the calling convention's 16 byte alignment */
|
||||
/* Both GCC and CLANG define GNUC. */
|
||||
#if defined(__GNUC__)
|
||||
uint64_t *stack = __builtin_alloca_with_align(sizeof(uint64_t) * signature->stack_count, 128);
|
||||
#else
|
||||
uint64_t *stack = alloca(sizeof(uint64_t) * signature->stack_count);
|
||||
#endif
|
||||
for (uint32_t i = 0; i < signature->arg_count; i++) {
|
||||
uint64_t *to;
|
||||
int32_t n = i + 2;
|
||||
|
||||
Reference in New Issue
Block a user