PSP Module and PRX Loading Lifecycle
Type: REFERENCE Status: MAINTAINED Scope: ELF/PRX modules, lifecycle, visibility, and static translation
PSP software is modular. A PRX is not just another object file permanently concatenated onto the main executable: load, relocate, import-link, start, stop, unload, module identity, and guest-visible address ownership are separate events.
How We Know
- PRIOR ART: PSPSDK Module Manager, kernel module-manager declarations, and PSP PRX format documentation.
- Import reconstruction: Nakagawa import parser.
- Current generated extra-module path: Nakagawa codegen module handling.
load bytes -> validate image -> map segments/BSS -> relocate
-> resolve imports/exports -> assign guest module identity
-> start entry -> resident / non-resident result
-> stop entry -> unload / release guest visibilityELF, PRX, and module metadata
PRIOR ART: ELF describes an executable image; PSP PRX adds module metadata and platform loader conventions. Segment sizes, BSS, entry/module-info offsets, attributes, and relocation information matter to a loader and to static analysis.
Section names are helpful when present but are not a reliable runtime contract. A sectionless or stripped image still has program headers, segments, entry identity, and imported/exported interfaces that the loader can observe.
Load is not start
The public Module Manager API separates locating/loading an image from invoking its start routine. A successful sceKernelLoadModule produces a module UID; sceKernelStartModule then runs the start path and reports module/start status through distinct channels. A start routine returning success does not mean the whole application exits or the module is immediately unloaded.
- Model UID allocation and module-info queries as guest-visible state.
- Do not call
module_startmerely because a PRX was pretranslated. - Track whether the module remains resident and whether its threads/callbacks/resources outlive the start call.
Relocations, GP, imports, and exports
Relocatable PRXs require module-relative identity and a load-base/GP model. Import reconstruction identifies requested NIDs and libraries, but runtime visibility is governed by which modules are logically loaded and which exports are currently published.
For static recompilation, keep these layers separate:
- offline image analysis and relocation records;
- generated host functions and their original guest addresses;
- guest module visibility and export registration;
- HLE/firmware imports versus exports from another loaded game module.
Cross-link to PSP Imports, NIDs, and Stub Tables and PSP Executable Model.
Stop, unload, and self-unload
Stop and unload are semantic operations, not bookkeeping. A stop routine can have side effects and return a status through an output pointer. Unloading may release/reuse guest memory while module-owned threads, callbacks, or indirect targets are still live. Self-unload is especially difficult for a translated native call stack because the currently executing guest module can request its own teardown.
A generalized runtime can pretranslate known modules, but it still needs guest lifecycle gates and a policy for unknown/dynamic modules. A host DLL handle is not a guest SceUID.
Validation and publication boundary
Loader security restrictions, plain-module checks, caller privilege, path provenance, and aligned buffer requirements vary by API and firmware. Do not turn historical loader quirks into timeless PSP specification. Public examples should use source-owned fixtures; retail PRXs and generated commercial-title C remain private.
Do Not Infer
- Pretranslated code is not permanently loaded guest code.
- A module start return value is not application exit.
- Matching NID/name does not prove matching firmware behavior.
- Static linking every known PRX is not proof of dynamic load/start/stop/unload correctness.
Open questions
Source-owned fixture work remains valuable for duplicate loads, module-memory reuse, live-thread unload, self-unload, buffer-load alignment, firmware restrictions, and dynamic modules not known at host build time. Track these in Open Research Questions.