lumbda/asm
russell@unturf.com 698a5d5f04
asm: gc_sweep page-fault on chunk-abandonment gap (segfault at chunk_end)
When heap_alloc walks off the end of a chunk with < 16 tail bytes,
.ha_grow_no_pad skips padding and mmaps a fresh chunk — but
gc_chunk_end[N] for the abandoned chunk stayed at its full mmap
end while %r15 (high-water) sat 1..15 bytes short. The gap held
mmap-zeros that gc_sweep's .gsw_walk decoded as fake dead blocks
(header == 0, payload size == 0, mark == 0). The walker stepped
through the zeros 8 bytes at a time, and on the iteration where
%rbx == chunk_end - 8 the .gsw_dead path stored the free-list
next-pointer to 0x8(%rbx) == chunk_end — the first byte of an
unmapped page — and segfaulted with error 7.

Reproducer (inside QEMU guest, was crashing all three asm
binaries):

  lumbda-full tests/unit/test-mod-solinas.lsp
  → segfault at <ptr ending 000> ip:4017d9
    (.gsw_dead: mov %rdx, 0x8(%rbx))

Fix: at .ha_grow_no_pad, snapshot %r15 into gc_chunk_end[N] before
allocating the new chunk. In the padded path above the label this
is a no-op (r15 already == r13). In the un-padded path it pins
the walk bound to the high-water mark so the sweep never enters
the gap.

After fix, on lumbda-full inside the ecdsa QEMU guest:
  - ecdsa test-mod-solinas: 39/39 PASS (Solinas vs Litinski
    byte-equal at p ∈ {11, 13, 251})
  - upstream asm test.sh: 158/158 PASS

Discovered while diagnosing ecdsa task #45.
2026-06-05 08:21:34 -04:00
..
lumbda asm: argv script-mode + always-on eq? prelude (defects #28, #30) 2026-06-04 12:49:13 -04:00
lumbda-full asm: argv script-mode + always-on eq? prelude (defects #28, #30) 2026-06-04 12:49:13 -04:00
lumbda-full.o asm: argv script-mode + always-on eq? prelude (defects #28, #30) 2026-06-04 12:49:13 -04:00
lumbda-gc asm: argv script-mode + always-on eq? prelude (defects #28, #30) 2026-06-04 12:49:13 -04:00
lumbda-gc.o asm: argv script-mode + always-on eq? prelude (defects #28, #30) 2026-06-04 12:49:13 -04:00
lumbda.o asm: argv script-mode + always-on eq? prelude (defects #28, #30) 2026-06-04 12:49:13 -04:00
lumbda.s asm: gc_sweep page-fault on chunk-abandonment gap (segfault at chunk_end) 2026-06-05 08:21:34 -04:00
Makefile asm/lumbda-full: quasiquote + define-macro + prelude (ticket 0005) 2026-04-24 12:02:12 -04:00
test.sh asm: rest args, cadr, sort, let* — Scheme port of Zoë's favorites runs 2026-04-24 09:01:32 -04:00