ajhahn.de
← FlashOS
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
    )
}