Flash 63 lines
// 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()
}