Flash 38 lines
// Recursive stack-blower for the [TEST] stack-overflow scenario.
// Built as a separate aarch64-freestanding ET_EXEC alongside hello.elf
// (build.zig) and embedded into the kernel image via .incbin
// (tools/stackbomb_elf.S) so the in-kernel harness can hand its bytes
// to sys_exec without an initramfs.
//
// _start jumps into a trivial recursion that pushes 1 KiB per frame
// (sub sp, #1024 + str x30, [sp]) so each `bl 1b` deepens the stack
// by exactly that amount. After ~64 frames SP crosses STACK_LOW and
// the next store enters the guard page; the kernel's do_data_abort
// detects the guard fault, prints `[KERN] stack overflow at 0x<hex>`,
// and zombies the task. The parent's sys_wait then reaps as usual.
//
// Source is Flash (tools/stackbomb.flash) — flashc transpiles it to Zig
// at build time via addFlashSource.
use user_layout
comptime {
// Each frame pushes 1 KiB; ensure the stack budget allows at
// least 16 frames so the recursion depth is representative
// before it crosses STACK_LOW into the guard. Current budget
// (16 pages = 64 KiB) allows 64 frames.
if user_layout.STACK_BUDGET / 1024 < 16 {
#compileError("STACK_BUDGET too small for representative recursion depth")
}
}
export fn _start() callconv(.naked) noreturn {
asm volatile (
\\.balign 8
\\1:
\\ sub sp, sp, #1024
\\ str x30, [sp]
\\ bl 1b
)
}