import argparse import hashlib import json import os import shutil import struct import subprocess import sys import tempfile from pathlib import Path from import_audit import read_host_imports from unwrap_self import Refused, unwrap ROOT = Path(__file__).resolve().parent.parent sys.path.insert(0, str(ROOT / "core/relinker/relinker/tests")) from guest_import_fixtures import executable CASES = ("memory", "owned_state", "concurrent_wait", "validation", "dispatch", "ordering", "nested", "limits", "node_pool", "priority", "shutdown", "worker_policy", "worker_wake", "worker_wait", "worker_count", "worker_spin") PARITY_CASES = tuple(case for case in CASES if case not in ("node_pool", "worker_wait")) def stage_libraries(directory, build, toolchain, dependencies): providers = {path.name.lower(): path for path in (build / "core/libs/libs").glob("*.prx")} if toolchain is not None: providers.update({path.name.lower(): path for path in toolchain.glob("*.dll")}) pending = list(dependencies) staged = set() while pending: name = pending.pop().lower() if name in staged: continue staged.add(name) source = providers.get(name) if source is None: if name.endswith(".prx"): raise RuntimeError(f"Missing patched runtime {name}; build core/libs/libs/{name}") continue shutil.copy2(source, directory / source.name) pending.extend(read_host_imports(source)) def run(args, directory): libraries = directory / "libs" libraries.mkdir() helper = args.build / "tests/job_manager_reference.prx" if not helper.is_file(): raise RuntimeError("Build the job_manager_reference target first") shutil.copy2(helper, libraries / "jobref.prx") suffix = ".exe" if sys.platform == "win32" else "" subprocess.run([str(args.build / f"core/libs/nid_patcher{suffix}"), "jobref", "--preserve-export-list", str(args.build / "core/libs/libc.exports"), str(libraries / "jobref.prx")], check=True, capture_output=True) module_hash = None if args.module: module_data = args.module.read_bytes() module_hash = hashlib.sha256(module_data).hexdigest() modules = directory / "sce_module" modules.mkdir() target = modules / "libSceJobManager.prx" if module_data[:4] == b"\x7fELF": shutil.copy2(args.module, target) else: unwrap(args.module, target) source = directory / "input.elf" entry = executable("jobref.prx", symbol="Run_nid_no_patch") entry[0x4000:0x400f] = b"\x48\x83\xec\x08\xff\x15" + struct.pack("