AnyPS5 exports some libkernel functions, such as __error, from
libc.prx, which libkernel.prx links. On Linux they resolve through that
dependency. On Windows, the import stubs search only the listed
modules, and libc.prx was listed only when libSceLibcInternal.prx was
needed. A PS4 homebrew that needs libkernel.prx but no C library (the
OpenOrbis graphics sample) failed with "unresolved ELF import
9BcDykPmo1I". libc.prx is now also listed when libkernel.prx is needed.
PS5 executables need libSceLibcInternal.prx and convert unchanged.
The Windows startup stub stopped at the first import it could not
resolve, so a title missing several functions showed one
"FAIL: unresolved ELF import" line per run and needed a run per
missing function to list them all.
The stub now counts unresolved imports, writes the FAIL line of each
and goes on with the next import. After the last import it fails once,
with the searched library list and the last Windows error as before,
and exits with STATUS_ENTRYPOINT_NOT_FOUND. Weak imports, lazy binding
and a startup where every import resolves are unchanged.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01V1W4jdNSKTV7xwuS6xQPJV
When a relinked executable fails to load a staged module, the dependency
diagnostics routine maps the same path as an image resource to walk its
imports. If that mapping failed it printed only "FAIL: dependency
diagnostics Windows API failed". The log then did not say whether the
staged module itself (libs\libSceRegMgr.prx in #4720) was absent or was
not a Windows image, and a module reached through another module's
imports was not named at all.
The register routine now reads GetLastError when LoadLibraryExW fails.
ERROR_FILE_NOT_FOUND and ERROR_PATH_NOT_FOUND print "dependency module
not found", ERROR_BAD_EXE_FORMAT prints "dependency module is not a
Windows PE image"; both name the module path, its importer and the
chain from the executable, like the existing missing-module report.
Other errors keep the generic message. An API set contract that
LoadLibraryExA reports as ERROR_MOD_NOT_FOUND now gets the
missing-module report too.
Refs #4720
Co-Authored-By: Claude Opus 5.5 <[email protected]>
ComputeExtraBlockVaddr kept the ELF congruence p_vaddr == p_offset (mod 0x1000)
and bumped the result by one page only when it fell below the highest guest
load end as a byte address. When that end is not page aligned and the extra
block's file offset remainder reaches it, the extra RWX PT_LOAD landed in the
same 4 KiB page that holds the tail of the highest guest segment. The kernel
maps each PT_LOAD page by page with MAP_FIXED in program-header order, so the
extra block's file page replaced the guest's .data tail and zero-filled .bss
there.
Round the highest kept PT_LOAD end up to the page before adding the offset
remainder, which is the placement GuestModuleWriter::WriteLinux already uses
for the guest module. Only the overlapping case changes; an end that is page
aligned or a remainder below it yields the same address as before.
The extra PT_LOAD now also spans to the end of its own page in p_memsz, so the
page it takes over is fully covered, and its vaddr is derived in WriteLayout
instead of being taken from the request. The header block load carries the
same flags as before.
The macOS executable patcher dropped PeImport::Weak, so every bind was
written without flags and dyld refused to load a binary whose weak
import no module exports. Carry the flag into MacOsBind and set
BIND_SYMBOL_FLAGS_WEAK_IMPORT for those binds, as Linux and Windows
already bind a missing weak import to 0.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
A PS5 eboot can keep initial-exec TLS as R_X86_64_TPOFF64 GOT relocations
(SuperTuxKart, STKT00001, has 13, all without a symbol), which the
relocation allowlist rejected. Relocations against the executable's own
TLS block (no symbol, or a defined STT_TLS symbol folded into the addend)
now go to the Linux ELF as symbolless dynamic relocations that the
dynamic loader resolves against where it placed the block; one against an
import stays named and is typed STT_TLS. The Windows and macOS images
resolve TPOFF64 and DTPOFF64 statically against the block
AlignUp(p_memsz, p_align) below the thread pointer, the offset
WindowsTlsBuilder and MacOsImage use, and reject DTPMOD64 and imported
TLS. TPOFF32 stays unsupported.
New test executable_tls_relocations covers the Linux, Windows and macOS
outputs and the rejected cases.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
With --trace-imports the entry stub resolves TraceImport_nid_no_patch
in libc.prx and passes each function import through it before writing
the slot: every PLT slot, and a GOT slot only when the original symbol
is a function, so data imports such as __stdoutp keep their address.
Without the option the output is unchanged.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Linux output reused the input program header table in place, so it could
hold no more entries than the input declared. A title whose kept segments
and the five synthetic headers did not fit lost PT_GNU_EH_FRAME with a
warning, or failed with "Not enough program header slots". When more
headers are needed, the table is now written at the end of the extra block,
e_phoff points there and PT_PHDR maps it through the extra block PT_LOAD;
the header block then maps only the ELF header. Bytes after the input table
are left as they were.
Co-Authored-By: Claude Opus 5.5 <[email protected]>