================================================================================ K8 signals-model — source-site snapshot ================================================================================ Generated by linux-wasm/tools/k8-signals-model-probe/snapshot-sources.sh from Documentation/wasm/signals-model.rst §8. Pinned at K8-A2 sub-phase close (per §11 K8-A2). Snapshots across five trees: [LIN] upstream linux/ tree (kernel/signal.c, kernel/entry/, x86 ref) [WAS] our wasm32-port/ tree (kernel/signal.c K0 stub, include/asm/signal.h K0 stub, include/asm/clone.h spawn-ring ABI, kernel/spawn.c kernel-side producer) [UPS] wackywasm-tools/musl-1.2.5/src/signal/ (upstream musl signal surface) [OVR] wackywasm-tools/musl-src/src_overrides/ (existing K7-pattern src_overrides; K8-B3 will add signal/wasm32/) [HWJ] hardwarejs/src/ (worker.mjs handleFutex insertion site, spawnRingConsumer.ts mirror, kernelSpawnHandler.ts registry to extend) Section legend: [DEF] the function definition (file:line + leading prose) [CALL] call sites in the relevant tree [SITE] inline excerpt of a load-bearing site (no function definition but a code shape we depend on) [K8-B] where K8-B-phases will insert NEW code (annotation only; does not exist in any tree yet) Snapshot taken against: upstream linux: v6.12 upstream musl: 1.2.5 wackywasm-tools/musl-src: K7 src_overrides state (no K8-B3 signal/ override yet) Generated: 2026-05-25 (UTC, deterministic stamp from `date -u`) Note: snapshot file deliberately omits HH:MM:SS in the stamp so re-runs on the same day produce byte-identical output. Drift detection is at line-number granularity. ================================================================================ 1. linux/kernel/signal.c — upstream send/receive + sigaction (K8-B1/K8-B5) ================================================================================ Module: upstream signal-delivery core. K8-B1 lands the arch_signal_wake_target hook into __send_signal_locked (after the bit is set in t->pending.signal but before the existing signal_wake_up call). K8-B5 reuses do_sigaction unchanged. get_signal is the load-bearing receiver-side function called from do_signal/arch_do_signal_or_restart on syscall exit. [DEF] linux/kernel/signal.c::__send_signal_locked(...) kernel/signal.c:1073 static int __send_signal_locked(int sig, struct kernel_siginfo *info, [DEF] linux/kernel/signal.c::complete_signal(int, struct task_struct *, enum pid_type) kernel/signal.c:994 static void complete_signal(int sig, struct task_struct *p, enum pid_type type) [DEF] linux/kernel/signal.c::signal_wake_up_state(struct task_struct *t, unsigned int state) kernel/signal.c:759 void signal_wake_up_state(struct task_struct *t, unsigned int state) [CALL] signal_wake_up_state call sites in linux/kernel/signal.c: [DEF] linux/kernel/signal.c::get_signal(struct ksignal *) kernel/signal.c:2683 bool get_signal(struct ksignal *ksig) [DEF] linux/kernel/signal.c::do_sigaction(int sig, struct k_sigaction *, struct k_sigaction *) kernel/signal.c:4170 int do_sigaction(int sig, struct k_sigaction *act, struct k_sigaction *oact) [DEF] linux/kernel/signal.c::SYSCALL_DEFINEx(rt_sigaction|rt_sigprocmask|rt_sigsuspend|rt_sigtimedwait): kernel/signal.c:3202:SYSCALL_DEFINE4(rt_sigprocmask, int, how, sigset_t __user *, nset, kernel/signal.c:3233:COMPAT_SYSCALL_DEFINE4(rt_sigprocmask, int, how, compat_sigset_t __user *, nset, kernel/signal.c:3688:SYSCALL_DEFINE4(rt_sigtimedwait, const sigset_t __user *, uthese, kernel/signal.c:4493:SYSCALL_DEFINE4(rt_sigaction, int, sig, kernel/signal.c:4518:COMPAT_SYSCALL_DEFINE4(rt_sigaction, int, sig, kernel/signal.c:4716:SYSCALL_DEFINE2(rt_sigsuspend, sigset_t __user *, unewset, size_t, sigsetsize) kernel/signal.c:4730:COMPAT_SYSCALL_DEFINE2(rt_sigsuspend, compat_sigset_t __user *, unewset, compat_size_t, sigsetsize) ================================================================================ 2. linux/kernel/entry/common.c — TIF_SIGPENDING exit-to-user loop (K8-B1 ref) ================================================================================ Module: upstream syscall-exit hook. The loop checks _TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL and calls arch_do_signal_or_restart. K8 does NOT modify this path directly — wasm32 syscall exit is on the JS-Worker side (per signals-model.rst §2(a)+(b)) — but the upstream shape is the spec we must mirror semantically. [DEF] linux/kernel/entry/common.c::exit_to_user_mode_loop(struct pt_regs *, unsigned long ti_work) kernel/entry/common.c:90 __always_inline unsigned long exit_to_user_mode_loop(struct pt_regs *regs, [SITE] linux/kernel/entry/common.c — TIF_SIGPENDING branch: kernel/entry/common.c:83:void __weak arch_do_signal_or_restart(struct pt_regs *regs) { } kernel/entry/common.c:110: if (ti_work & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL)) kernel/entry/common.c:111: arch_do_signal_or_restart(regs); ================================================================================ 3. linux/arch/x86/kernel/signal*.c — setup_rt_frame reference (K8-B3 shape ref) ================================================================================ Reference shape: x86 builds a signal frame on the user stack with siginfo_t, sigcontext, and the rt_sigreturn trampoline. On wasm32 we cannot construct frames "on top of" the wasm shadow stack (signals-model.rst §4); the K8-B3 trampoline __wasm_signal_dispatch is the wasm32-shaped equivalent. [DEF] linux/arch/x86/kernel/signal.c::arch_do_signal_or_restart(struct pt_regs *) arch/x86/kernel/signal.c:333 void arch_do_signal_or_restart(struct pt_regs *regs) [SITE] linux/arch/x86/kernel/signal.c — setup_rt_frame dispatch: arch/x86/kernel/signal.c:236:setup_rt_frame(struct ksignal *ksig, struct pt_regs *regs) arch/x86/kernel/signal.c:294: failed = (setup_rt_frame(ksig, regs) < 0); [DEF] linux/arch/x86/kernel/signal_64.c::x64_setup_rt_frame(...) arch/x86/kernel/signal_64.c:164 int x64_setup_rt_frame(struct ksignal *ksig, struct pt_regs *regs) ================================================================================ 4. wasm32-port/kernel/signal.c — K0 stub (K8-B1 fills in) ================================================================================ The K0 scaffold. The body is a TODO placeholder. K8-B1 turns this into a real arch_signal_wake_target implementation that composes a wasm_signal_request (mirror of wasm_spawn_request shape from include/asm/clone.h) and submits it through a new signal ring sibling of the spawn ring. [SITE] wasm32-port/kernel/signal.c — full file (K0 stub): kernel/signal.c:1 // SPDX-License-Identifier: GPL-2.0 kernel/signal.c:2 /* kernel/signal.c:3 * arch/wasm32: signal delivery on syscall exit. v0.1 scaffold; real kernel/signal.c:4 * implementation is filled in here in later phases (see plan U1+). kernel/signal.c:5 */ kernel/signal.c:6 #include kernel/signal.c:7 #include kernel/signal.c:8 kernel/signal.c:9 void do_signal(struct pt_regs *regs) kernel/signal.c:10 { kernel/signal.c:11 (void)regs; kernel/signal.c:12 /* TODO: walk current->pending; invoke registered handler via kernel/signal.c:13 * call_indirect into user's sigaction.sa_handler (a WASM function kernel/signal.c:14 * table index); save/restore arch state. */ kernel/signal.c:15 } ================================================================================ 5. wasm32-port/include/asm/signal.h — K0 stub (K8-B1 extends) ================================================================================ The K0 scaffold. Pulls in uapi + asm-generic. K8-B1 extends this header with: * struct wasm_signal_pending_region (40 bytes per Worker) * static_asserts pinning offsets vs hardwarejs/test/k8-a1 SR_OFF_* constants * wasm_signal_request layout (K8-B2 ring payload) * arch_signal_wake_target prototype [SITE] wasm32-port/include/asm/signal.h — full file (K0 stub): include/asm/signal.h:1 /* SPDX-License-Identifier: GPL-2.0 */ include/asm/signal.h:2 #ifndef _ASM_WASM32_SIGNAL_H include/asm/signal.h:3 #define _ASM_WASM32_SIGNAL_H include/asm/signal.h:4 include/asm/signal.h:5 #include include/asm/signal.h:6 #include include/asm/signal.h:7 include/asm/signal.h:8 #endif ================================================================================ 6. wasm32-port/include/asm/clone.h — spawn-ring ABI (K8-B2 ABI mirror) ================================================================================ K5-frozen ABI: wasm_thread_arg_region, wasm_spawn_request, wasm_spawn_request_ring, WASM_THREAD_ARG_MAGIC. K8-B2's signal ring follows the IDENTICAL shape (header layout, slot index seq+ack pattern, magic-number framing). K8 does not modify this header; it mirrors it for the signal channel. [DEF] wasm32-port/include/asm/clone.h — load-bearing structs/enums: include/asm/clone.h:87:struct wasm_clone_fn_arg { include/asm/clone.h:123:struct wasm_thread_arg_region { include/asm/clone.h:153:enum wasm_spawn_mode { include/asm/clone.h:186:struct wasm_spawn_request { include/asm/clone.h:257:struct wasm_spawn_request_ring { [DEF] wasm32-port/include/asm/clone.h — magic + size pins: include/asm/clone.h:60:#define WASM_THREAD_ARG_MAGIC 0x4441455252485457ULL include/asm/clone.h:99:#define WASM_THREAD_ARG_VERSION 1u include/asm/clone.h:226:#define WASM_SPAWN_RING_SLOTS 16 include/asm/clone.h:273:#define WASM_THREAD_ARG_REGION_V1_SIZE 112 include/asm/clone.h:274:#define WASM_SPAWN_REQUEST_V1_SIZE 64 include/asm/clone.h:275:#define WASM_SPAWN_RING_HEADER_V1_SIZE 32 ================================================================================ 7. wasm32-port/kernel/spawn.c — kernel-side ring producer (K8-B2 mirror site) ================================================================================ The K5-pattern producer. K8-B2's signal-ring producer follows the IDENTICAL submit-and-bump shape (slot allocation by atomic seq increment, payload write, ack-wait by Atomics.wait on the ack word). The producer signature for K8 is: int wasm_signal_submit(pid_t tid, int sig, pid_t sender_pid) [DEF] wasm32-port/kernel/spawn.c — exported submit functions: [SITE] wasm32-port/kernel/spawn.c — first 80 lines (header + slot acquire): kernel/spawn.c:1 // SPDX-License-Identifier: GPL-2.0 kernel/spawn.c:2 /* kernel/spawn.c:3 * arch/wasm32/kernel/spawn.c — kernel→HardwareJS Worker-spawn upcall. kernel/spawn.c:4 * kernel/spawn.c:5 * Documentation/wasm/threading-model.rst §§3-6 + §11 R7. The kernel kernel/spawn.c:6 * communicates with HardwareJS via a shared ring in env.kernel_memory: kernel/spawn.c:7 * kernel/spawn.c:8 * - Kernel side (this file): producer. Allocates a slot, fills kernel/spawn.c:9 * mode + tid + image fields, advances head, increments kernel/spawn.c:10 * spawn_notify_word + Atomics.notify. Blocks on kernel/spawn.c:11 * result_notify_word until HardwareJS writes the result. kernel/spawn.c:12 * kernel/spawn.c:13 * - HardwareJS side (hardwarejs/src/spawnRingConsumer.ts): kernel/spawn.c:14 * consumer. Atomics.wait on spawn_notify_word, processes kernel/spawn.c:15 * slot[tail], writes result, increments result_notify_word kernel/spawn.c:16 * + Atomics.notify. kernel/spawn.c:17 * kernel/spawn.c:18 * The ring lives in static .bss so wasm-ld can emit a Global export kernel/spawn.c:19 * containing its env.kernel_memory offset. HardwareJS reads the kernel/spawn.c:20 * offset from the exports map at instantiation time (see kernel/spawn.c:21 * hardwarejs/src/kernelWorker.mjs's wasm32_spawn_ring lookup) and kernel/spawn.c:22 * starts a consumer loop that runs for the lifetime of the kernel kernel/spawn.c:23 * Worker. kernel/spawn.c:24 * kernel/spawn.c:25 * K5 producer surface: host_spawn_process_worker() is the only kernel/spawn.c:26 * issuer; binfmt_wasm.c::load_wasm_binary calls it with fork-mode kernel/spawn.c:27 * requests for execve. K6+ adds clone(CLONE_VM, ...) → thread-mode kernel/spawn.c:28 * via arch_clone (not yet implemented). kernel/spawn.c:29 * kernel/spawn.c:30 * K5 consumer surface: HardwareJS-side consumer handles BOTH kernel/spawn.c:31 * fork-mode and thread-mode requests, even though K5 kernel C kernel/spawn.c:32 * never produces thread-mode. The R1 sub-test bypasses kernel C kernel/spawn.c:33 * and constructs a thread-mode request by hand to verify the kernel/spawn.c:34 * HardwareJS path works in isolation (this is the kernel/spawn.c:35 * no-precluding-K6 verification from §3 K5-enforcement). kernel/spawn.c:36 */ kernel/spawn.c:37 kernel/spawn.c:38 #include kernel/spawn.c:39 #include kernel/spawn.c:40 #include kernel/spawn.c:41 #include kernel/spawn.c:42 #include kernel/spawn.c:43 #include kernel/spawn.c:44 #include kernel/spawn.c:45 #include kernel/spawn.c:46 kernel/spawn.c:47 #include kernel/spawn.c:48 kernel/spawn.c:49 /* kernel/spawn.c:50 * Atomic wait/notify wrappers. These use the WASM intrinsics kernel/spawn.c:51 * directly (not the linux.atomic_wait_i32 host import, which in kernel/spawn.c:52 * the current K4/K5 wiring is a stub returning 0). The intrinsics kernel/spawn.c:53 * route through V8's futex table on a SharedArrayBuffer, which is kernel/spawn.c:54 * exactly what we need to coordinate with HardwareJS-main's kernel/spawn.c:55 * Atomics.wait / Atomics.notify on the same SAB-backed memory. kernel/spawn.c:56 * kernel/spawn.c:57 * Mirrors the idle-path helpers in arch/wasm32/kernel/asyncify.c kernel/spawn.c:58 * (private to that file). Duplicated here rather than moved into kernel/spawn.c:59 * a shared header to keep arch/wasm32/include layering clean kernel/spawn.c:60 * (asyncify.c's are local concerns; spawn.c's are independent kernel/spawn.c:61 * concerns; only converge if a third consumer appears). kernel/spawn.c:62 */ kernel/spawn.c:63 static __always_inline int wasm_atomic_wait32(volatile u32 *addr, kernel/spawn.c:64 u32 expected, kernel/spawn.c:65 long long timeout_ns) kernel/spawn.c:66 { kernel/spawn.c:67 return __builtin_wasm_memory_atomic_wait32((int *)addr, kernel/spawn.c:68 (int)expected, kernel/spawn.c:69 (int64_t)timeout_ns); kernel/spawn.c:70 } kernel/spawn.c:71 kernel/spawn.c:72 static __always_inline u32 wasm_atomic_notify(volatile u32 *addr, u32 count) kernel/spawn.c:73 { kernel/spawn.c:74 return __builtin_wasm_memory_atomic_notify((int *)addr, count); kernel/spawn.c:75 } kernel/spawn.c:76 kernel/spawn.c:77 /* kernel/spawn.c:78 * The ring itself. .bss-allocated so wasm-ld can give us a stable kernel/spawn.c:79 * env.kernel_memory offset to export. Aligned to 8 bytes for clean kernel/spawn.c:80 * u64 access (in case K6+ extends slot fields to u64). ================================================================================ 8. wasm32-port/kernel/ — surface inventory (what exists at K8-A2 time) ================================================================================ [SITE] wasm32-port/kernel/ files at K8-A2: wasm32-port/kernel/asm-offsets.c wasm32-port/kernel/asyncify.c wasm32-port/kernel/binfmt_wasm.c wasm32-port/kernel/clone.c wasm32-port/kernel/entry.c wasm32-port/kernel/fork.c wasm32-port/kernel/head.c wasm32-port/kernel/init.c wasm32-port/kernel/k6_a1_probes.c wasm32-port/kernel/k6_b1_probes.c wasm32-port/kernel/k6_b2_probes.c wasm32-port/kernel/k6_b4_probes.c wasm32-port/kernel/k7_u4b_probes.c wasm32-port/kernel/percpu.c wasm32-port/kernel/percpu_anchors.c wasm32-port/kernel/process.c wasm32-port/kernel/sched.c wasm32-port/kernel/sections.c wasm32-port/kernel/setup.c wasm32-port/kernel/signal.c wasm32-port/kernel/smp.c wasm32-port/kernel/spawn.c wasm32-port/kernel/switch_to.c wasm32-port/kernel/syscall_table.c wasm32-port/kernel/time.c wasm32-port/kernel/traps.c wasm32-port/kernel/wasm_module.c [SITE] wasm32-port/include/asm/ files at K8-A2: wasm32-port/include/asm/asyncify.h wasm32-port/include/asm/atomic.h wasm32-port/include/asm/barrier.h wasm32-port/include/asm/boot.h wasm32-port/include/asm/bug.h wasm32-port/include/asm/cache.h wasm32-port/include/asm/clone.h wasm32-port/include/asm/cmpxchg.h wasm32-port/include/asm/current.h wasm32-port/include/asm/elf.h wasm32-port/include/asm/futex.h wasm32-port/include/asm/host.h wasm32-port/include/asm/io.h wasm32-port/include/asm/irq.h wasm32-port/include/asm/irqflags.h wasm32-port/include/asm/linkage.h wasm32-port/include/asm/mmu_context.h wasm32-port/include/asm/page.h wasm32-port/include/asm/pgalloc.h wasm32-port/include/asm/pgtable.h wasm32-port/include/asm/processor.h wasm32-port/include/asm/ptrace.h wasm32-port/include/asm/signal.h wasm32-port/include/asm/smp.h wasm32-port/include/asm/switch_to.h wasm32-port/include/asm/syscall.h wasm32-port/include/asm/thread_info.h wasm32-port/include/asm/tlbflush.h wasm32-port/include/asm/uaccess.h wasm32-port/include/asm/vmalloc.h wasm32-port/include/asm/wasm_module.h ================================================================================ 9. wackywasm-tools/musl-1.2.5/src/signal/ — upstream musl signal surface ================================================================================ Module: the musl-side signal sources we link against. K8-B3's src_override targets the per-arch restore.s shape (every real arch has a restore.s emitting an SYS_rt_sigreturn syscall stub). wasm32 cannot use a .s file — the wasm assembly model has no syscall return instruction. K8-B3 provides src_overrides/signal/wasm32/restore.c that calls the trampoline __wasm_signal_dispatch. [SITE] wackywasm-tools/musl-1.2.5/src/signal/ — top-level files: ../wackywasm-tools/musl-1.2.5/src/signal/block.c ../wackywasm-tools/musl-1.2.5/src/signal/getitimer.c ../wackywasm-tools/musl-1.2.5/src/signal/kill.c ../wackywasm-tools/musl-1.2.5/src/signal/killpg.c ../wackywasm-tools/musl-1.2.5/src/signal/psiginfo.c ../wackywasm-tools/musl-1.2.5/src/signal/psignal.c ../wackywasm-tools/musl-1.2.5/src/signal/raise.c ../wackywasm-tools/musl-1.2.5/src/signal/restore.c ../wackywasm-tools/musl-1.2.5/src/signal/setitimer.c ../wackywasm-tools/musl-1.2.5/src/signal/sigaction.c ../wackywasm-tools/musl-1.2.5/src/signal/sigaddset.c ../wackywasm-tools/musl-1.2.5/src/signal/sigaltstack.c ../wackywasm-tools/musl-1.2.5/src/signal/sigandset.c ../wackywasm-tools/musl-1.2.5/src/signal/sigdelset.c ../wackywasm-tools/musl-1.2.5/src/signal/sigemptyset.c ../wackywasm-tools/musl-1.2.5/src/signal/sigfillset.c ../wackywasm-tools/musl-1.2.5/src/signal/sighold.c ../wackywasm-tools/musl-1.2.5/src/signal/sigignore.c ../wackywasm-tools/musl-1.2.5/src/signal/siginterrupt.c ../wackywasm-tools/musl-1.2.5/src/signal/sigisemptyset.c ../wackywasm-tools/musl-1.2.5/src/signal/sigismember.c ../wackywasm-tools/musl-1.2.5/src/signal/siglongjmp.c ../wackywasm-tools/musl-1.2.5/src/signal/signal.c ../wackywasm-tools/musl-1.2.5/src/signal/sigorset.c ../wackywasm-tools/musl-1.2.5/src/signal/sigpause.c ../wackywasm-tools/musl-1.2.5/src/signal/sigpending.c ../wackywasm-tools/musl-1.2.5/src/signal/sigprocmask.c ../wackywasm-tools/musl-1.2.5/src/signal/sigqueue.c ../wackywasm-tools/musl-1.2.5/src/signal/sigrelse.c ../wackywasm-tools/musl-1.2.5/src/signal/sigrtmax.c ../wackywasm-tools/musl-1.2.5/src/signal/sigrtmin.c ../wackywasm-tools/musl-1.2.5/src/signal/sigset.c ../wackywasm-tools/musl-1.2.5/src/signal/sigsetjmp.c ../wackywasm-tools/musl-1.2.5/src/signal/sigsetjmp_tail.c ../wackywasm-tools/musl-1.2.5/src/signal/sigsuspend.c ../wackywasm-tools/musl-1.2.5/src/signal/sigtimedwait.c ../wackywasm-tools/musl-1.2.5/src/signal/sigwait.c ../wackywasm-tools/musl-1.2.5/src/signal/sigwaitinfo.c [SITE] wackywasm-tools/musl-1.2.5/src/signal/ — per-arch restore.s shapes: ../wackywasm-tools/musl-1.2.5/src/signal/aarch64/restore.s ../wackywasm-tools/musl-1.2.5/src/signal/arm/restore.s ../wackywasm-tools/musl-1.2.5/src/signal/i386/restore.s ../wackywasm-tools/musl-1.2.5/src/signal/loongarch64/restore.s ../wackywasm-tools/musl-1.2.5/src/signal/microblaze/restore.s ../wackywasm-tools/musl-1.2.5/src/signal/powerpc/restore.s ../wackywasm-tools/musl-1.2.5/src/signal/powerpc64/restore.s ../wackywasm-tools/musl-1.2.5/src/signal/riscv32/restore.s ../wackywasm-tools/musl-1.2.5/src/signal/riscv64/restore.s ../wackywasm-tools/musl-1.2.5/src/signal/s390x/restore.s ../wackywasm-tools/musl-1.2.5/src/signal/sh/restore.s ../wackywasm-tools/musl-1.2.5/src/signal/x32/restore.s ../wackywasm-tools/musl-1.2.5/src/signal/x86_64/restore.s [DEF] musl-1.2.5/src/signal/sigaction.c — __libc_sigaction + __sigaction: src/signal/sigaction.c:20 int __libc_sigaction(int sig, const struct sigaction *restrict sa, struct sigaction *restrict old) src/signal/sigaction.c:63 int __sigaction(int sig, const struct sigaction *restrict sa, struct sigaction *restrict old) [DEF] musl-1.2.5/src/signal/raise.c — raise(): src/signal/raise.c:6 int raise(int sig) [DEF] musl-1.2.5/src/signal/kill.c — kill(): src/signal/kill.c:4 int kill(pid_t pid, int sig) [CALL] musl-1.2.5 sigprocmask call sites (K8-B5 surface): src/signal/block.c:33: __syscall(SYS_rt_sigprocmask, SIG_BLOCK, &all_mask, set, _NSIG/8); src/signal/block.c:38: __syscall(SYS_rt_sigprocmask, SIG_BLOCK, &app_mask, set, _NSIG/8); src/signal/block.c:43: __syscall(SYS_rt_sigprocmask, SIG_SETMASK, set, 0, _NSIG/8); src/signal/sigaction.c:37: __syscall(SYS_rt_sigprocmask, SIG_UNBLOCK, src/signal/sigsetjmp_tail.c:8: __syscall(SYS_rt_sigprocmask, SIG_SETMASK, ret?p:0, ret?0:p, _NSIG/8); ================================================================================ 10. wackywasm-tools/musl-src/src_overrides/ — K7-state overrides (K8-B3 extends) ================================================================================ Existing src_overrides at K8-A2 (K7's state). K8-B3 adds a new signal/wasm32/ subtree: [K8-B] musl-src/src_overrides/signal/wasm32/restore.c (replaces upstream restore.s for wasm32; calls __wasm_signal_dispatch) [K8-B] musl-src/src_overrides/internal/wasm32/__wasm_signal_dispatch.c (the trampoline itself; called from worker.mjs after a syscall returns when pending_signals != 0) The K8-B3 overrides land alongside the existing K7 thread/wasm32/{__set_thread_area.c,clone.c} and env/wasm32/__init_tls.c overrides; same disposition table (toolchain-model.rst §5). [SITE] wackywasm-tools/musl-src/src_overrides/ — files at K8-A2: ../wackywasm-tools/musl-src/src_overrides/env/wasm32/__init_tls.c ../wackywasm-tools/musl-src/src_overrides/thread/wasm32/__set_thread_area.c ../wackywasm-tools/musl-src/src_overrides/thread/wasm32/clone.c [SITE] wackywasm-tools/musl-src/arch/wasm32/ — arch port files at K8-A2: ../wackywasm-tools/musl-src/arch/wasm32/atomic_arch.h ../wackywasm-tools/musl-src/arch/wasm32/bits/alltypes.h.in ../wackywasm-tools/musl-src/arch/wasm32/bits/fenv.h ../wackywasm-tools/musl-src/arch/wasm32/bits/float.h ../wackywasm-tools/musl-src/arch/wasm32/bits/ipcstat.h ../wackywasm-tools/musl-src/arch/wasm32/bits/msg.h ../wackywasm-tools/musl-src/arch/wasm32/bits/posix.h ../wackywasm-tools/musl-src/arch/wasm32/bits/reg.h ../wackywasm-tools/musl-src/arch/wasm32/bits/sem.h ../wackywasm-tools/musl-src/arch/wasm32/bits/setjmp.h ../wackywasm-tools/musl-src/arch/wasm32/bits/shm.h ../wackywasm-tools/musl-src/arch/wasm32/bits/signal.h ../wackywasm-tools/musl-src/arch/wasm32/bits/stat.h ../wackywasm-tools/musl-src/arch/wasm32/bits/stdint.h ../wackywasm-tools/musl-src/arch/wasm32/bits/syscall.h.in ../wackywasm-tools/musl-src/arch/wasm32/bits/user.h ../wackywasm-tools/musl-src/arch/wasm32/bits/wasm_thread.h ../wackywasm-tools/musl-src/arch/wasm32/crt1.c ../wackywasm-tools/musl-src/arch/wasm32/crt1_musl.c ../wackywasm-tools/musl-src/arch/wasm32/crt_arch.h ../wackywasm-tools/musl-src/arch/wasm32/kstat.h ../wackywasm-tools/musl-src/arch/wasm32/pthread_arch.h ../wackywasm-tools/musl-src/arch/wasm32/pthread_stub.c ../wackywasm-tools/musl-src/arch/wasm32/reloc.h ../wackywasm-tools/musl-src/arch/wasm32/runtime.c ../wackywasm-tools/musl-src/arch/wasm32/syscall_arch.h ../wackywasm-tools/musl-src/arch/wasm32/syscall_nr.h ../wackywasm-tools/musl-src/arch/wasm32/wasm_thread.S ================================================================================ 11. hardwarejs/src/worker.mjs — handleFutex (K8-B1 EINTR insertion site) ================================================================================ The K7-U4e in-Worker SYS_futex dispatch. K8-B1 extends handleFutex with pre/post-check of pending_signals (per signals-model.rst §7 race-resolution shape). The insertion is two atomic loads and two early-returns; no other K7-U4e logic changes. [DEF] hardwarejs/src/worker.mjs::handleFutex(...) worker.mjs:133 function handleFutex(uaddr, futex_op, val, timeout_ptr, _uaddr2, _val3) { [SITE] hardwarejs/src/worker.mjs — FUTEX_WAIT body (K8-B1 wraps this): worker.mjs:75: * Atomics.wait / Atomics.notify against env.user_memory. The worker.mjs:83: * (b) Correctness — Atomics.wait on the MAIN thread is worker.mjs:87: * of which break the wasm-level Atomics.wait blocking worker.mjs:91: * (c) Same-SAB semantic — Atomics.wait/notify against a shared worker.mjs:94: * contract maps SYS_futex(FUTEX_WAIT/WAKE) → this primitive worker.mjs:98: * FUTEX_WAIT = 0 worker.mjs:106: * Atomics.wait's relative-timeout semantics). worker.mjs:109: const FUTEX_WAIT = 0; worker.mjs:116: * -EAGAIN = -11 (FUTEX_WAIT saw mismatched value — caller's worker.mjs:127: * imports as env.user_memory. Atomics.wait/notify operate on worker.mjs:136: /* uaddr must be 4-byte-aligned for Atomics.wait. Misalignment worker.mjs:141: if (op === FUTEX_WAIT) { worker.mjs:154: const result = Atomics.wait(userI32, i32_idx, val | 0, timeout_ms); worker.mjs:158: /* Defensive: unknown return from Atomics.wait. */ worker.mjs:164: * Atomics.notify returns the number actually woken. */ worker.mjs:166: const woken = Atomics.notify(userI32, i32_idx, count); worker.mjs:225: Atomics.wait(ctrl, C.STATE, REQUEST); ================================================================================ 12. hardwarejs/src/spawnRingConsumer.ts — ring consumer pattern (K8-B2 mirror) ================================================================================ The K5-pattern consumer. K8-B2's signalRingConsumer.ts follows the IDENTICAL poll-and-dispatch shape; only the slot payload type and the dispatched handler change. [DEF] hardwarejs/src/spawnRingConsumer.ts — exported types/classes: spawnRingConsumer.ts:76:export interface SpawnRequest { spawnRingConsumer.ts:109:export interface SpawnRingConsumerOptions { spawnRingConsumer.ts:139:export class SpawnRingConsumer { ================================================================================ 13. hardwarejs/src/kernelSpawnHandler.ts — per-pid registry (K8-B2 extends) ================================================================================ The K7-U4c registry: tid → { wasmBytes, userMemory }. K8-B2 either extends this map (adding a signalPendingOffset field per record) or adds a sibling per-tid signal registry. K8-B2 picks the cleanest variant; either way, the lookup happens by the same tid that wasm_signal_submit publishes through the signal ring. [DEF] hardwarejs/src/kernelSpawnHandler.ts — exported types/functions: kernelSpawnHandler.ts:172:export interface KernelSpawnParentRecord { kernelSpawnHandler.ts:199:export type KernelSpawnHandler = SpawnHandler & { kernelSpawnHandler.ts:205:export interface KernelSpawnHandlerOptions { kernelSpawnHandler.ts:255:export function makeKernelSpawnHandler( [SITE] hardwarejs/src/kernelSpawnHandler.ts — registry data structures: kernelSpawnHandler.ts:186: * spawnHandler option directly). Also exposes a small registry- kernelSpawnHandler.ts:197: * the registry automatically. kernelSpawnHandler.ts:258: /* Parent-process registry: tid → { wasmBytes, userMemory }. kernelSpawnHandler.ts:263: const parents = new Map(); kernelSpawnHandler.ts:265: /* CLONE_CHILD_CLEARTID registry: tid → { ctid, userMemory }. kernelSpawnHandler.ts:269: const cloneCleartidMap = new Map(); kernelSpawnHandler.ts:363: /* Tracking only — not awaited here. K6+ pid registry uses kernelSpawnHandler.ts:475: * process group — so we reuse the parent registry. ================================================================================ 14. K8-B insertion-point summary (annotation only; no code yet) ================================================================================ [K8-B1] linux-wasm/patches/0008-signal-add-arch_signal_wake_target-hook.patch Upstream weak-hook in kernel/signal.c::__send_signal_locked, invoked AFTER the bit-set in t->pending.signal. [K8-B1] arch/wasm32/include/asm/signal.h — extend with struct wasm_signal_pending_region (40 bytes, layout per signals-model.rst §3) + static_asserts pinning SR_OFF_PENDING_LO/HI/WAKE_WORD/SIGMASK_LO/HI. [K8-B1] arch/wasm32/kernel/signal.c — replace K0 stub with arch_signal_wake_target(struct task_struct *t) implementation. Composes a wasm_signal_request payload, submits via the new signal ring. [K8-B1] hardwarejs/src/worker.mjs::handleFutex — pre-Atomics.wait check on signal-pending region; post-Atomics.wait re-check; both return -EINTR (-4) when set. [K8-B2] arch/wasm32/include/asm/signal.h — extend with struct wasm_signal_request + wasm_signal_request_ring (mirror of clone.h spawn-ring shape). [K8-B2] arch/wasm32/kernel/spawn.c (or new signal_ring.c) — kernel-side ring producer. [K8-B2] hardwarejs/src/signalRingConsumer.ts (NEW) — JS-side ring consumer. [K8-B2] hardwarejs/src/signalHandler.ts (NEW) — per-tid registry lookup + Worker signal-pending-region update + wake_word Atomics.notify. [K8-B3] musl-src/src_overrides/internal/wasm32/__wasm_signal_dispatch.c (NEW) — Worker-side trampoline; saves sigmask, applies sa_mask, indirect-calls sa_handler, restores sigmask, clears the dispatched bit in pending_signals. [K8-B3] musl-src/src_overrides/signal/wasm32/restore.c (NEW) — replaces upstream restore.s; calls __wasm_signal_dispatch. [K8-B4] musl-src/src_overrides/signal/wasm32/default_disp.c (NEW) — SIG_DFL terminate-vs-ignore-vs-stop disposition dispatch; SIGKILL/SIGSTOP non-catchability check. [K8-B5] musl-src/src_overrides/signal/wasm32/sigsuspend.c (NEW or upstream-direct) — sigsuspend / sigprocmask / rt_sigtimedwait surface against the per-Worker sigmask slot in the pending region. ================================================================================ END OF SNAPSHOT ================================================================================