boot2

Playing with the boostrap
git clone https://git.ryansepassi.com/git/boot2.git
Log | Files | Refs | README

commit c6a82a3a2bc1166329ee461d9c9d152ee5709ea6
parent 3d4a605868477322720da30bfb1ce9e6abbcecb1
Author: Ryan Sepassi <rsepassi@gmail.com>
Date:   Wed, 29 Apr 2026 23:22:47 -0700

entry-libc: save argc/argv across __libc_init

__libc_init may return through a0; if the callee-saved path through the
P1 ABI doesn't preserve a0/a1 across the call, main receives garbage
arguments. Allocate a 16-byte frame in p1_main and spill/reload argc
(a0) and argv (a1) around the __libc_init call.

Diffstat:
MP1/entry-libc.P1pp | 10+++++++---
1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/P1/entry-libc.P1pp b/P1/entry-libc.P1pp @@ -5,15 +5,19 @@ # main. __libc_init (boot2-syscall.c) reads argv's NULL terminator # to populate `environ` so getenv()/etc don't dereference a NULL # environment pointer on the first call. argc/argv arrive in a0/a1 -# from the bootstrap _start; %call doesn't clobber them, so the -# second %call delivers them to main unchanged. +# from the bootstrap _start; save them across __libc_init so main sees +# the original process arguments even if libc init returns through a0. # # Cat this in exactly once at the head of a libc-using catm chain # and pair with P1/elf-end.P1pp at the tail. Library TUs (libc, # client) should be built with cc.scm --lib=PFX so they don't # also try to define :p1_main. -%fn(p1_main, 0, { +%fn(p1_main, 16, { + %st(a0, sp, 0) + %st(a1, sp, 8) %call(&__libc_init) + %ld(a0, sp, 0) + %ld(a1, sp, 8) %call(&main) })