[hare] Hare compiler, written in C11 for POSIX OSs
Log | Files | Refs | README | LICENSE

commit 62d4204f21332d97ad7697f628eade9137e9c3bc
parent de9d0c8926b01712f924bccd731415f96a1bffce
Author: Sebastian <sebastian@sebsite.pw>
Date:   Thu, 23 Jun 2022 19:19:43 -0400

gen: fix segfault when allocating multiple of 2^32

In QBE, the jnz instruction only checks the lower 32 bits of its first
argument (i.e. it's treated as a word). Since the passed size was being
checked directly, any multiple of 2^32 would be treated as zero,
resulting in a segfault at runtime.

	let n: size = 64 * 64 * 1024 * 1024;
	let x: []u8 = alloc([0...], n);

This has been fixed by first using cnel to compare the size to zero, and
then using the result of that in the jnz instruction.

Fixes: https://todo.sr.ht/~sircmpwn/hare/739
Signed-off-by: Sebastian <sebastian@sebsite.pw>

Msrc/gen.c | 4+++-
1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/gen.c b/src/gen.c @@ -430,9 +430,11 @@ gen_alloc_slice_at(struct gen_context *ctx, struct qbe_value rtfunc = mkrtfunc(ctx, "rt.malloc"); struct qbe_value data = mkqtmp(ctx, ctx->arch.ptr, ".%d"); + struct qbe_value cmpres = mkqtmp(ctx, &qbe_word, ".%d"); struct qbe_value zero = constl(0); pushi(ctx->current, &data, Q_COPY, &zero, NULL); - pushi(ctx->current, NULL, Q_JNZ, &size, &bnonzero, &bzero, NULL); + pushi(ctx->current, &cmpres, Q_CNEL, &size, &zero, NULL); + pushi(ctx->current, NULL, Q_JNZ, &cmpres, &bnonzero, &bzero, NULL); push(&ctx->current->body, &lnonzero); pushi(ctx->current, &data, Q_CALL, &rtfunc, &size, NULL);