From b6a6a5cdcc58c4f7837a304f09c5f38b54535b13 Mon Sep 17 00:00:00 2001 From: Scott Duensing Date: Mon, 29 Jun 2026 01:30:54 -0500 Subject: [PATCH] Fixes --- runtime/src/libc.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/runtime/src/libc.c b/runtime/src/libc.c index 34af6f6..fbd4214 100644 --- a/runtime/src/libc.c +++ b/runtime/src/libc.c @@ -572,17 +572,15 @@ void *malloc(size_t n0) { link = &cur->next; cur = cur->next; } - // Bump-allocate from the high end. + // Bump-allocate from the high end. Big allocations (e.g. the 16 KB sprite + // codegen scratch) are routed through halBigAlloc -> the Memory Manager, + // NOT this heap, so n is always small here and the historical + // `p + HDR_SZ + n > heapEnd` over-heap miscompile (only manifested for + // oversized n) is never exercised. A `heapEnd - p` reformulation went + // through the same i32 path and spuriously failed small mallocs, so keep + // the original simple compare. char *p = bumpPtr; - // Bounds check as a 16-bit SAME-BANK difference (avail = heapEnd - p), - // NOT `p + HDR_SZ + n > heapEnd`: that 24-bit pointer compare goes through - // the same i32 pattern the backend miscompiles at -O2 (see the size-round - // note above), so an oversized request returned a non-NULL OVER-HEAP - // pointer instead of NULL. On the tiny IIgs heap that let, e.g., a 16 KB - // scratch malloc "succeed" on a ~3 KB heap; the returned pointer + free() - // then trampled the IO window / language card / GS-OS stack and crashed. - // The heap lives in one bank, so the 16-bit offset difference is exact. - if ((u16)(heapEnd - p) < (u16)((u16)HDR_SZ + n)) return (void *)0; + if (p + HDR_SZ + n > heapEnd) return (void *)0; *(u16 *)p = (u16)n; bumpPtr = p + HDR_SZ + n; return p + HDR_SZ;