2026-09-03 - (/loop) dlsym never knew the guest's own exports; the wall did not move

before   182 distinct, 415,331 calls, read of 0xa0 at image+0x1389269
after    181 distinct, 415,415 calls, read of 0xa0 at image+0x1389269
suites 124   tests 2006   clippy/fmt/identity clean

Third cron tick. Two findings, and the second is the honest half.

sceKernelDlsym resolved against orbistoun's table and nothing else

name_thunk holds what orbistoun implements, so a guest asking for a symbol its own binary exports was told it did not exist:

orbistoun: the guest asked for the address of scriptingGetMem - which nothing here implements

The eboot's export table has exactly one entry and it is scriptingGetMem, at +0xf25330. Orbistoun had that table all along - raw_exports reads it, exports prints it, PlacedTitleModules indexes it for binding. dlsym was the one consumer that never asked.

Now: answered 0x400000f25330.

The lookup has to hash at the call - a guest asks by name, every export table is keyed by a hash, and the loader cannot precompute a map for names it has not seen. So the loader registers (nid, address) plus the suffix and the kernel hashes on arrival; orbistoun-kernel takes orbistoun-nid, downhill on the spine. Thunk table first, guest exports second - purely additive, so no name that resolved before changes its answer.

And it did not move the wall

Three identical runs: same instruction, same fault. sceKernelDlsym is called once in the whole run, so it was never going to be worth much to this title. It is worth having because it is a real gap in a real mechanism - dlsym is the fourth-most-called import across the corpus, 141,717 calls over six modules - but for this wall it is not the answer, and saying otherwise because the change was satisfying is the failure principle 3 is about.

What the wall is, as far as it has been read

4c 8b 35 a7 73 6a 00    mov r14, [rip+0x6a73a7]   <- r14 from a global at image+0x1A30610
49 8b 9e a0 00 00 00    mov rbx, [r14+0xa0]       <- FAULT
49 2b 9e 98 00 00 00    sub rbx, [r14+0x98]

A global holding a structure pointer, holding zero. The two fields are subtracted, which is the shape of a used/allocated or end/start pair - a memory accounting read.

Two hypotheses killed by measurement:

Breaks watched to fail

dlsym does not consult guest exports  -> "its own symbol did not exist"      FAILED
the lookup answers the first entry    -> "worse than no lookup"              FAILED

Two instrument notes, because both cost time

ORBISTOUN_RETURN reaches unnamed functions by hash and named ones by name. Given five hashes for functions the symbol database has named, it matched nothing - it compares against a label that carries the name. It said so, once per target, and I believed the negative for a minute because my own grep filtered the warning out. Third time a filter's silence has been read as the tree's.

ORBISTOUN_BSS_FILL is too blunt here - it killed the run at nine calls, because many globals legitimately start at zero. It answers "does this run depend on uninitialised static data", not "which global", which is what was wanted.

Decision: D517.