// Payload for [TEST] flibc — exercises three flibc layers: // printf (comptime format + sys_writeConsole flush), // malloc (bump-over-sbrk), and exit (sys_exit). fork/wait/execve are // covered indirectly by the existing fork-stress / exec-elf scenarios // running through their flibc-equivalent SVC wrappers, so the demo // stays single-PT_LOAD by avoiding a self-fork. // // Build: aarch64-freestanding ET_EXEC via build.zig (pie=false, strip, // ReleaseSmall, hello-style page caps). Embedded in the kernel image // via .incbin in tools/flibc_demo_elf.S so the harness can hand its // bytes to sys_exec without an initramfs. // // Trace contract verified by the test scenario in // user_space/kernel_tests.zig: // "flibc hello 42\n" — printf %d round-trip // "flibc malloc ok\n" — bump-allocate 32 B, write+verify pattern // // Bespoke `_start` (entry .disabled in build.zig, no flibc_start shim): // a Flash `export fn` lowers to the C-ABI export Zig already gives an // `export fn`, and the kernel erets straight to the symbol, so the // calling convention of a no-arg noreturn entry is immaterial. Uses an // `orelse { … }` block handler on malloc and a value `if` for the // pass/fail string — both land 1:1 in the lowered Zig. use flibc const ALLOC_BYTES u64 = 32 export fn _start() noreturn { flibc.printf("flibc hello %d\n", .{#as(u32, 42)}) maybe := flibc.malloc(ALLOC_BYTES) if maybe == null { flibc.puts("flibc malloc fail") flibc.exit() } buf := maybe.? // Demand-allocate the heap page on first write — do_data_abort // classifies the fault as in-range heap and stamps a fresh RW+UXN // page before retrying. The pattern is round-trip-verified below // so a stale TLB / wrong-PA bug surfaces as a "flibc malloc bad" // line in the trace instead of a silent pass. var i u64 = 0 while i < ALLOC_BYTES { buf[i] = #as(u8, #intCast(i)) +% 0x55 i += 1 } var ok bool = true i = 0 while i < ALLOC_BYTES { expected := #as(u8, #intCast(i)) +% 0x55 if buf[i] != expected { ok = false } i += 1 } flibc.puts(if (ok) "flibc malloc ok" else "flibc malloc bad") flibc.exit() }