457. One function, two answers

2026-09-08 - directed, continuing 456

Bus idle a sixth pass. Local work.

The inconsistency four differential entries were sitting on

Four entries said the same thing in the probe's words - "libSceKeyboard loaded but no symbols resolved", and the same for libSceMouse, libSceVideodec2 and libSceAjm - for libraries orbistoun declares and stubs.

The cause is one line of table-building. sceKernelDlsym's by-name table is symbols::resolvable(), the implemented set, while imports get a stub for every declared name. 949 declared, 680 implemented. So 269 names answer differently depending on how the guest asked, and sceKernelDlsym's own doc comment claims the opposite - "a function reached this way and the same function reached by an import are the same address" - which is true of two-thirds of the table.

One payload run asks by name for 266 of them.

Measured, not argued

The case against is real: a guest handed a stub calls it and gets a placeholder, where a guest handed null may take a fallback it would have preferred. That is not settled by argument, so it got a flag - ORBISTOUN_DLSYM_STUBS, Effect::Intervenes, and the table it installs is empty unless a run asks, which is what makes two runs comparable (D632).

The payload: 223 -> 226 imports, FURTHER, still exits cleanly. And because an intervention that moves a wall is not a diagnosis, the second observation - the probe's own verdicts against the console:

baseline under the flag
concluding differently 255 240
passed there, failed here 115 106
distinct findings 17 13

All four "no symbols resolved" entries gone; the absent-library census 99 -> 94.

Three titles byte-identical. PPSA03416, PPSA02664 and PPSA04263: same imports, same calls, same standing, same fault address, flag or no flag. They resolve by import, so this cannot reach them - which was the expectation and is now the measurement.

Left as a flag, deliberately

Nothing got worse and one thing got better. That is evidence, not proof: four guests is a small population, and the guest the case against describes - one that prefers a null it can branch on - is exactly the kind that would not be in a corpus built from guests that already run.

Changing what dlsym answers by default is a user-visible behaviour change. The flag, the numbers and the recommendation are recorded; the default stands until somebody decides.

Surprises

Next