D076 - The dynamic table lives at the tail of the vendor segment, not in the image
Status: decided, 2026-08-29.
On an ordinary system PT_DYNAMIC is a window onto a
mapped PT_LOAD and the loader reads it at its virtual
address. A console executable does the opposite, and the arithmetic in a
real one is exact rather than suggestive:
PT_SCE_DYNLIBDATA offset 0x8c130 filesz 0x3760 vaddr 0 -> ends 0x8f890
PT_DYNAMIC offset 0x8f450 filesz 0x0440 vaddr 0 -> ends 0x8f890
The dynamic table is the last 0x440 bytes of the vendor
segment, immediately after the hash table, with nothing between them.
Both carry no address; neither is placed. PT_DYNAMIC is
sized to exactly sixty-seven tags and a terminator, not to a
reservation.
That is also why the loader's frames are named the way they are:
preprocess_dt_entries is reached from
calcurate_sce_dynlibdata_layout, because walking the
dynamic entries is how the vendor blob's layout is
computed. With the table left behind in a PT_LOAD, the
loader walks the region it expects, finds no vendor tag anywhere, and
reports the first one it needed:
[rtld] ERROR preprocess_dt_entries:9589: does not have DT_SCE_SYMTABSZ or DT_SCE_HASHSZ tabs.
naming two tags that were present, correct, and a hundred kilobytes
from where it was looking. So install appends the table to
the segment, points PT_DYNAMIC at it with no address, and
erases the one the linker left behind - walking to the linker's own
terminator rather than clearing the whole reservation, because a script
that gives .dynamic the rest of its segment declares a
p_filesz covering live data.