D556 - The out-parameter is the whole of the wall, and the capture that could answer it does not exist yet
Status: measured Date: 2026-09-04
The question
sceAgcCreateShader is where PPSA02664 stops:
read of 0x50 at image+0xf56e09. Three things about it were
unknown, and each would be answered differently.
- Is it the return value? A stub answers
0x7fff0001, which has the high bit clear and is therefore positive; a guest checkingif (ret < 0)would read that as success. - Is it the out-parameter, or is the out-parameter merely the first thing that goes wrong after some earlier mistake?
- Can obSCEne's existing captures say what the object looks like, or is a console day needed?
What was measured
The return value is not it, and this was already written
down. orbistoun-cli knows sceAgcCreateShader
records that the caller tests the answer against 0x8a6c003d
specifically rather than for failure. Before reading that, this
session forced a negative vendor-shaped return with
ORBISTOUN_RETURN="sceAgcCreateShader:0xffffffff80d11000"
and got the same fault at the same address - which confirms the record,
at the cost of a run. Third time this session that an experiment
re-derived something knows already held (D547,
D555, and this). The habit that would have caught all three is one
command, and it is now the first step in the worklog's method.
The out-parameter is the whole of it, and that is measured
rather than argued. At the fault rsp is
0x6000007fc4e0, and the faulting rsi was
loaded by mov rsi,[rsp+0x38] - 0x6000007fc518,
which is byte-for-byte the arg0 the call was given. So arg0 is a
pointer-to-pointer: the call is expected to write a pointer
into it, and the guest dereferences what it finds there.
Planting any readable pointer -
ORBISTOUN_WRITE=sceAgcCreateShader:0+0:0x6000007fc000 -
carries the guest past image+0xf56e09
entirely, to a different fault elsewhere.
Under D227 that is an extent, not a diagnosis: the guest is now walking a structure that is not one, so where it stops next says nothing at all and is not recorded as progress. What the experiment establishes is the narrow thing it can - that nothing else about this call site is blocking, so no further work on arguments, arity or return values can move this wall.
Two fields of the object are observed, by decoding
the guest's own instructions rather than by inference:
8b 46 50 reads a dword at +0x50 and
0f b6 d0 keeps only its low byte, so +0x50 is
read wide and used as one byte; 48 8b 46 30 then reads a
quadword at +0x30. Nothing here says what either means, and
both are recorded as edges rather than as a layout.
obSCEne cannot answer it as its probe runs today.
Four captures record 472 libSceAgc symbols as
absent - including
OBS|sym|libSceAgc|sceAgcCreateShader|absent|current in each
- and OBS|sysinfo|modlink/gpu states that no GPU library is
mapped in the probe's process. This is the sixth stated blocker checked
against what the sibling repository already has in eight ticks, and the
first of the six that turned out not to be stale.
The decision
Record the structure and the extent; do not implement a
shader object. Principle 3 forbids exactly the move that is
available here - inventing a plausible object and a plausible pointer to
put in a place a guest will dereference. The wall is not moved by a
better guess about the layout; it is moved by a capture taken where
libSceAgc is mapped, and that ask is now written in obSCEne's
docs/backlog/022 as a condition on the probe rather than as
a symbol to census.
What this does not establish
What the object is for, how large it is, or whether
+0x30 and +0x50 are two fields of one
structure or one field read two ways by two paths. Only that two offsets
are read, in that order, by a guest that was given nothing.
Nor that the same layout holds for any other title. This is one caller in one binary. The knowledge base already notes PPSA28061 calls the function eleven times with arg0 at an image address rather than on the stack, and nothing here was checked against it.