D218
- MIN_DEFINES, and what the importless control turned out
not to prove
Status: decided, 2026-08-29.
eboot-min grew a hook for the variants already in
src/min.c, because once an eboot loads the
question changes: a fault inside libkernel is either the
platform library's own initialisation or our first call into it, and
those need opposite fixes.
The importless build cannot answer it. It was meant
to be the control - loads libkernel, carries the vendor
segment and the process parameters, calls nothing - but it does not load
at all, and the loader says why:
[rtld] ERROR preprocess_dt_entries:9632: C: ah 1 pg 0 jr 0 pr 1 prs 0 rl 0
[rtld] ERROR preprocess_dt_entries:9636: C: rls 0 rle 0 stt 1 sts 1 st 1 se 1
With no imports there are no relocations, so PLTGOT,
JMPREL, PLTRELSZ, RELA,
RELASZ and RELAENT are absent - and this
loader requires the full set unconditionally, empty or not. That is a
fact about the format worth having, and it retires the control.
The file-writing variant answered it instead, and negatively. Built
with three imports rather than one and a different code path, it faults
at the same instruction and the same address as the
one-import build - rip 0x80003333b, writing to
0x28 - and leaves no file. Identical failure from different
code means our code is not running: the fault is in
libkernel's initialisation, before our entry point.
The next thing to look at is the process parameter block, which is
what libkernel reads before a single instruction of ours
executes. Ours is 0x50 bytes and zero after the magic; a
real one is 0x60, declares an SDK version of
0x08008011 and an entry count of five, and carries three
non-null pointers at +0x38, +0x40 and
+0x48 into its RELRO segment. A write to
null + 0x28 is what taking one of those pointers and
finding zero looks like.