The post-argc user_sp -= user_sp % 16 created an 8-byte padding gap
between the stack pointer and argc on the user stack. glibc's RISC-V
_start reads argc from *sp and computes argv as sp+8, so the gap caused:
- argc read as 0 (the padding byte) instead of the actual count
- argv offset 8 bytes too low
- __libc_start_main computed a wrong auxv pointer (landing on envp NULL instead of AT_BASE)
- glibc init function 0x11d1e8 received *a0=0 (AT_NULL), took early return, and never wrote the function pointer at 0x1b7bc0
- Subsequent deref of that NULL function pointer → LoadPageFault(1)
The alignment is unnecessary because glibc's _start already does
andi sp, sp, -16 to re-align the stack before calling into C code.
This happened to work for argc=1 (basic tests) because the arithmetic
coincidentally left no padding.
Also:
- syscall: log tid for thread-level debugging; return ENOSYS instead of panicking on unknown syscall IDs
- from_elf: pre-initialize dtv array in the main-thread TCB so glibc can find _dl_static_dtv during TLS bootstrap
- initproc: switch to busybox for debugging