Skip to content

feat: macOS host support (Apple Silicon via Rosetta 2, Vulkan on MoltenVK) - #8658

Closed
iamthehimansh wants to merge 289 commits into
boykopovar:mainfrom
iamthehimansh:feat/macos-port
Closed

iamthehimansh wants to merge 289 commits into
boykopovar:mainfrom
iamthehimansh:feat/macos-port

Conversation

@iamthehimansh

@iamthehimansh iamthehimansh commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

What

macOS host support for AnyPS5 on Apple Silicon: the emulator runs as x86_64 under Rosetta 2 and renders through Vulkan on MoltenVK. The relinker and the web converter build natively.

Every platform-specific change is behind __APPLE__ / elseif(APPLE) or sits in specifics/macos/. Before every commit I compared the Linux and Windows preprocessed views of each changed file against main; they are unchanged.

Graphics driver address

  • macOS reserves the AGC driver's fixed 2 MB window at 0xfe0000000 for itself; mmap there fails with EPERM even in an empty process, natively and under Rosetta.
  • On macOS the driver memory moves to 0xee0000000, and the converted shaders are retargeted to that address.

Kernel, libc and networking

  • Directory listing and directory-relative paths.
  • Disk-space queries, rename and same-file checks.
  • Memory locking and unlocking, and write watching.
  • Per-thread CPU time from the Mach thread counter.
  • nanosleep errno, precise waits, and kqueue file and socket events.
  • Socket options, SO_ACCEPTCONN, the UDP pending-bytes count and the stream-send error after a peer close.
  • EPROTOTYPE → NET_EPROTONOSUPPORT in sceNetSocket, which is what FreeBSD reports.
  • IPv4 parsing that rejects leading zeros.
  • acosf precision under Rosetta.
  • The guest TLS entry points, and guest unwinding over Mach-O __eh_frame.

Graphics and video output

  • The macOS Vulkan loader name and portability enumeration.
  • Integer colour targets on Metal, which need uint/int fragment outputs.
  • A shutdown-order fix: the registration-preparation lifecycle mutex outlives static destruction.

Relinker

  • 1 KB of header room in the Mach-O image, so code signing does not overlap the entry stub.

Build

  • macOS-only fixes for headers and linker flags that only exist on Linux, such as link.h, if_link.h, AF_PACKET and --exclude-libs.
  • A few tests use macOS names where the macOS SDK defines a macro with the same name (SIGUSR1).

Tested

Machine: macOS 26 (Darwin 25.6, arm64) on an Apple M2 Pro. The emulator ran as x86_64 under Rosetta 2, with the Vulkan SDK 1.4.363.0 and MoltenVK 1.4.2. To test the GPU path, source setup-env.sh from the SDK and point VK_DRIVER_FILES at MoltenVK_icd.json. The SDK also installs the arm64-only KosmicKrisp ICD, which an x86_64 process cannot load; with VK_DRIVER_FILES set, it no longer logs that.

Builds and conventions:

  • cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=ON with the full build: 0 failed objects.
  • The relinker-only build: 230/230 tests pass.
  • The web converter build: tools/test_web.py passes.
  • python3 tools/check_conventions.py --base origin/main: all checks pass.

Full ctest on this machine (M2 Pro, macOS 26.6, at 51a06b126): 1,804 tests; 90 are skipped by the tests themselves, and 19 fail. Main does not build on macOS, so before this branch none of these ran. Full runs on an M1 (@Mauro42K) and an M4 (@prosperkartik) are in the thread.

16 of the 19 failures are graphics features that Apple GPUs or MoltenVK do not provide, or graphics paths still open:

  • clip and cull distances (4)
  • denormal and tininess handling (2)
  • sampler min/max reduction, multisample storage images, robust reads past a pooled buffer's end
  • pixel interlock, per-sample masks and sample iteration
  • agc_driver_sample_order, which passes with feat(recompiler): read I/J from barycentric built-ins on MoltenVK #9193
  • image-table descriptor reuse: MoltenVK's image limits keep the table in the shared pools, which are not kept
  • tessellation of a merged LS+HS hull program, and indexed indirect rect-list draws (both still open)

The other 3:

  • guest_floating_point: Rosetta ignores the MXCSR exception mask bits.
  • guest_math_exact: Rosetta canonicalises x87 pseudo-denormals.
  • agc_write_tracking: on macOS a host import opens its whole range for writing, so an untouched block in the import window is reported as possibly written by the CPU.

On the M4, agc_driver_ds_permute also fails. SPIRV-Cross forwards the recompiler's unconditional OpGroupNonUniformShuffle into a short-circuit &&/?: operand, which makes the shuffle conditional in MSL; @prosperkartik reduced and filed it as KhronosGroup/SPIRV-Cross#2722.

On the M1 (@Mauro42K, macOS 27.0.1), agc_driver_pass_input_hazard and agc_driver_uint8x4_color_target also fail; both pass on the M2 Pro and the M4 with the same MoltenVK, and the cause is still open.

I have not tested on Linux or Windows. For every changed C/C++ file I compare its Linux and Windows preprocessor views (unifdef with __APPLE__ undefined) with main. 14 files are not macOS-only, and they change what Linux and Windows compile:

  • Whitespace or a comment only: ExportMacros.hpp, DisplayWindow.cpp, ApplicationProcessParameters.cpp.
  • New headers that are empty off macOS: MainThread.hpp, DriverMemory.hpp.
  • The same behaviour, written portably:
    • FileStream.hpp calls feof_unlocked/ferror_unlocked unqualified, so macOS can supply them.
    • CxxAbiSupport.cpp names the __cxa_thread_atexit lambda.
    • Jit.cpp adds #include <filesystem>.
    • QueuedIndexReadOrder.cpp changes 4 reinterpret_casts to static_cast.
    • GuestGenericCategory.cpp adds const_cast before the vtable casts.
    • Formatting.cpp adds <cstdarg> and a clang __builtin_sysv_va_list alias.
    • GuestRaiseException.cpp renames its SIGUSR1 constant to GuestSigUsr1 and uses the shared assembly macros.
  • New macOS target in shared converter code: the relinker's macOS image writer (MacOsImage.cpp) and the web converter's "macos" target option (wasm/Bindings.cpp).

Every other changed file has identical Linux and Windows views.

Homebrew: ccleste (PPSA59322) converts, gets signed, starts, reads its settings and assets and runs into gameplay. It stops at its first mesh-path draw whose pixel shader reads barycentrics, because MoltenVK exposes neither VK_EXT_mesh_shader nor a usable VK_KHR_fragment_shader_barycentric. That needs a non-mesh fallback and is left for a follow-up PR.

Checklist

cc @boykopovar @oneandonlydean @adriadam10. It would help if one of you could start the full Linux/Windows build for this PR (gh workflow run build.yml --repo boykopovar/AnyPS5 --ref main --field pr=8658).

macOS owns 0xfc0000000-0x1000000000 with maximum protection none, so
the AGC driver's fixed 2 MiB block at 0xfe0000000 can never be mapped
there, even in an empty process. Every driver test stopped with "the
AGC driver memory was not mapped at its fixed address".

On macOS the block sits at 0xee0000000, lower in the same
system-reserved guest range that games are never given. It replaces
only the guest arena's own inaccessible reservation; anything else
mapped there is reported instead of overwritten.

Guest compute shaders build the FS table pointer from two s_mov_b32
immediates. FindTableCalls records which instructions write it, and on
macOS LinkUserDataCallees moves a pointer that falls inside the
console block to the macOS block, both for the callee lookup and in the
code the GPU runs. A move that cannot hold the new value is reported
rather than left pointing at unmapped memory.

DriverMemory.hpp holds both bases and the translation. Linux and
Windows preprocessed sources are unchanged.

Full macOS suite: 84 of 1,599 tests fail, down from 210; the 126
driver-memory failures pass and nothing newly fails.
compute FS table calls tests pass.
No conflicts. One macOS build fix for new upstream code:
- QueuedIndexReadOrder test: reinterpret_cast from std::uintptr_t to
  std::uint64_t is ill-formed where they are different types (macOS:
  unsigned long vs unsigned long long); static_cast gives the same value
  on every platform.

Checked: the macOS build has 0 failed objects, 208/208 converter tests
pass, the web converter builds and passes tools/test_web.py, and the
new agc_driver_queued_index_read_order test passes under MoltenVK.
GuestMemoryLifetimeSupport, IndirectArgumentsPendingProducer and
PerformanceOverlay opened the Linux loader name on every non-Windows
host, so on macOS they failed with "Failed loading libvulkan.so.1".
They now open libvulkan.1.dylib on Apple, like the driver and the other
tests already do.

The six agc_driver_guest_memory_lifetime* tests and
agc_driver_indirect_arguments_pending_producer now pass under MoltenVK.
Linux and Windows preprocessed sources are unchanged.
The macOS acosf the guest acosf forwarded to is not correctly rounded
under Rosetta: acosf(0.5f) returns 0x3f860a91, one ulp below the
correctly rounded 0x3f860a92 that the console returns and guest_math
checks (native arm64 macOS gets it right). On macOS the guest acosf now
evaluates in double and rounds once, which is correctly rounded for
every float input.

guest_math now passes on macOS. Linux and Windows preprocessed
sources are unchanged.
Darwin's nanosleep returns 0 after a full sleep but leaves errno set to
ETIMEDOUT (60). The guest errno is the host errno, so a guest that
slept successfully saw its errno changed, which guest_nanosleep checks
(GuestNanosleep.cpp:82-84). On macOS the sleep loop now restores the
caller's errno.

guest_nanosleep passes on macOS. Linux and Windows preprocessed sources
are unchanged.
FreeBSD and glibc inet_pton reject a dotted-quad component with a
leading zero ("01.2.3.4"); macOS inet_pton accepts it, so
sceNetInetPton returned 1 where the console returns 0
(GuestSceNet.cpp:738-739). On macOS AF_INET text with such a component
is rejected before the host call; output and errno stay untouched.

guest_sce_net now passes its inet_pton checks on macOS (it still stops
later, at the unbound datagram shutdown check). Linux and Windows
preprocessed sources are unchanged.
…nters

Three macOS differences that stopped guest_sce_net:

- Like Winsock, macOS neither wakes nor fails a receive blocked on an
  unbound datagram socket when the socket is shut down (shutdown even
  fails with ENOTCONN). The existing Windows wait for a local address
  now also applies on macOS, where an unbound socket reports port 0
  from getsockname instead of failing, and it waits with poll().
- macOS answers an AF_INET6 lookup of an IPv4 literal with its
  IPv4-mapped form; FreeBSD and glibc, without AI_V4MAPPED, find no IPv6
  address. The resolver skips IPv4-mapped answers on macOS.
- sceNetCtlGetIfStat had no macOS byte counters and threw. It now sums
  the 64-bit if_data64 counters from the NET_RT_IFLIST2 routing list
  for interfaces that are up and not loopback.

guest_sce_net and guest_net_ctl pass on macOS. Linux and Windows
preprocessed sources are unchanged.
Two macOS differences that stopped guest_udp:

- macOS refuses an address on a connected datagram socket with
  EISCONN; the console accepts it. When the address is the connected
  peer (same family, port and address), the datagram is now sent with
  send(), which goes to the same place. Any other address still fails
  with EISCONN.
- macOS FIONREAD on a datagram socket also counts the queued address
  records (35 for one 19-byte datagram, 86 for two). The console and
  Linux report the next datagram's size, which macOS gives through
  SO_NREAD. FIONREAD, the poll readiness count and the stat-style
  queued byte count now use SO_NREAD for datagram sockets.

guest_udp passes on macOS. guest_socket_read_write is flaky on macOS
with and without this change (line 154, errno 54 or 35 instead of
EPIPE; 2/30 runs fail on the parent commit). Linux and Windows
preprocessed sources are unchanged.
After the peer closes, macOS can fail the next stream send with
ECONNRESET where FreeBSD reports EPIPE, so guest_socket_read_write
(GuestSocketReadWrite.cpp:151-154) failed intermittently with errno 54.
On macOS SendError now maps ECONNRESET on a stream socket to EPIPE; the
receive path is unchanged.

guest_socket_read_write: 0 of 40 runs fail, against 2 to 5 of 30 before.
Linux and Windows preprocessed sources are unchanged.
macOS refuses shutdown(SHUT_RD) with ENOTCONN once the peer has shut
down its sending side, although the socket is still connected
(getpeername succeeds) and queued data stays readable. The console
accepts it, so guest_socket_pair stopped at GuestSocketPair.cpp:146-149.

On macOS a SHUT_RD that fails with ENOTCONN on a socket that still has a
peer is treated as done; the guest's receive-shut state is recorded as
before. A socket that was never connected still fails with ENOTCONN.

guest_socket_pair now passes that check (it next stops at the
SOCK_SEQPACKET socket pair). Linux and Windows preprocessed sources are
unchanged.
macOS has no AF_UNIX SOCK_SEQPACKET (socketpair fails with
EPROTONOSUPPORT), so guest_socket_pair stopped at
GuestSocketPair.cpp:177. A connected AF_UNIX datagram pair keeps the
same record boundaries and reports MSG_TRUNC for a short receive, which
is what the guest relies on; on macOS a SEQPACKET pair is now backed by
one. The guest socket keeps its SEQPACKET type.

guest_socket_pair passes on macOS (3 of 3 runs). Linux and Windows
preprocessed sources are unchanged.
macOS poll() never reports POLLPRI (or POLLRDBAND) for pending TCP
urgent data and does not wake for it, so guest_poll's PollsUrgentData
check (GuestPoll.cpp:202-208) failed. A MSG_OOB | MSG_PEEK check is not
usable on macOS: the peek uses the urgent byte up, so the guest's later
recv(MSG_OOB) fails with EINVAL.

On macOS the guest poll now asks SIOCATMARK, which reports the urgent
byte without consuming it once it is the next byte to read, for every
socket that asked for POLLPRI, and ORs POLLPRI into its revents. While
such a socket waits, the host wait is cut into 10 ms slices so a timed
or infinite poll still returns when urgent data arrives. Other polls
wait exactly as before.

guest_poll passes on macOS (3 of 3 runs), and 48 of 50 networking and
poll tests pass (the two SSL transport tests fail for another reason).
Linux and Windows preprocessed sources are unchanged.
macOS timer coalescing wakes a nanosleep about 25% late on this machine
(1.4 ms takes about 1.76 ms, natively and under Rosetta), so the fixed
100 us spin tail overshot: PreciseSleepUs(1500) took a median of
1.76 ms against precise_wait's 1.65 ms bound
(PreciseWait.cpp:125-131).

On macOS the sleep part now covers 70% of the wait before the spin tail,
so the late wake-up falls inside the spin and the wait ends at the
deadline.

precise_wait passes on macOS (8 of 8 runs); the other 44 timing and
sleep tests are unchanged (guest_itimer and guest_thread_cpu_clock fail
as before). Linux and Windows preprocessed sources are unchanged.
Under Rosetta, clock_gettime(CLOCK_THREAD_CPUTIME_ID) badly under-counts
a thread's CPU time: about 5 ms for 200 ms of busy CPU on this machine,
while thread_info(THREAD_BASIC_INFO) reports 199 ms. The guest's
per-thread CPU clocks already read the Mach counter, so the two clocks
disagreed and guest_thread_cpu_clock failed (GuestThreadCpuClock.cpp:
75-76).

On macOS the guest CLOCK_THREAD_CPUTIME_ID now reads the calling
thread's THREAD_BASIC_INFO user and system time too.

guest_thread_cpu_clock passes on macOS (3 of 3 runs); 46 of 47 timing
and CPU-time tests pass (guest_itimer fails as before). Linux and
Windows preprocessed sources are unchanged.
One conflict, in libSceVideoOut DisplayWindow.cpp: upstream's new
present telemetry (boykopovar#7298) and the macOS main-thread window-title update
are both kept.

Checked: the macOS build has 0 failed objects, 209/209 converter tests
pass, and the web converter builds and passes tools/test_web.py.
No conflicts.

Checked: the macOS build has 0 failed objects, 209/209 converter tests
pass, and the web converter builds and passes tools/test_web.py.
The guest exception runtime (libc/src/exception/Unwind.cpp) walks frames
through __eh_frame, but Apple clang emits compact unwind and ld64 keeps
only __unwind_info, so on macOS a guest throw could not step out of
libc's own frames: guest_bad_optional_access died with "[libc] unhandled
exception 'St19bad_optional_access'". ld64's -keep_dwarf_unwind is
obsolete and has no effect.

configure_windows_unwind already marks every image the guest unwinder
must walk; on Apple it now compiles them with -femit-dwarf-unwind=always
and links with -no_compact_unwind, so __eh_frame is kept.

Full macOS suite: 66 of 1,624 fail, down from 69; guest_bad_optional_
access, unwind_callback_abi_backtrace and unwind_callback_abi_forced_
unwind now pass, nothing newly fails. Linux and Windows builds are
unchanged (the new branch is elseif(APPLE)).
For memory the guest registry does not know (the title's heap blocks,
thread stacks), sceKernelVirtualQuery read /proc/self/maps on every
non-Windows host. macOS has no /proc, so every such query failed with
EACCES, and guest_system_configuration (KERN_PROC vmmap) and
guest_kernel_is_stack failed.

On macOS it now asks mach_vm_region for the region around the address
and reports its extent and read/write/execute protection, like the
Linux maps line. Unmapped or unreadable memory still fails with EACCES,
as on the PS5.

guest_system_configuration and guest_kernel_is_stack pass on macOS; 30
of 36 memory, stack and system tests pass, and the 6 that fail failed
before. Linux and Windows preprocessed sources are unchanged.
No conflicts. One macOS build fix for new upstream code:
- BdaResources test: memfd_create and MFD_CLOEXEC are Linux-only; on
  macOS the 16 KiB views block is backed by an unlinked POSIX shared
  memory object instead.

Checked: the macOS build has 0 failed objects, 209/209 converter tests
pass, the web converter builds and passes tools/test_web.py, and
agc_driver_graphics_tests (which includes BdaResources.cpp) passes under
MoltenVK.
Apple clang inlines the direct Descend call in Worker, so Descend's
4 KiB probe array lands in Worker's own frame (0x1028 bytes, via
__chkstk_darwin), below the local the stack-size check measures from.
The local then sat 4,208 bytes below the top of a 16 KiB guest stack
against a 4,096-byte allowance, and the check at
GuestPthreadStack.cpp:70 failed although the guest got its whole stack.

Descend is marked noinline on Apple, so Worker's frame is 0x18 bytes
again and the test measures the guest stack, as on Linux.

guest_pthread_stack passes on macOS (5 of 5 runs). Linux and Windows
preprocessed sources are unchanged.
The test read page state from /proc/self/maps and re-executed itself
through /proc/self/exe; macOS has neither, so the child checks failed at
line 54 and the parent at line 541. On macOS QueryPage now reads the
Mach region (mach_vm_region) holding the address and encodes its
permissions like the maps line, and the child is started through the
path from _NSGetExecutablePath.

guest_kernel_stack_protect passes on macOS (3 of 3 runs). The two
main-stack-bottom child checks report that they skip, as they do
whenever memory is mapped within 1 MiB of the main stack's bottom, and
the unlimited-stack check skips because the hard stack limit cannot be
raised; the thread-stack guard checks run. Linux and Windows
preprocessed sources are unchanged.
On Linux fflush returns early for a stream that is not writing, so
pushback from ungetc and buffered input survive. Darwin's fflush on a
reading stream discards both, so after fgetc/ungetc('Z')/fflush the
next fread returned "\n" instead of "Zbcdef\n" and guest_standard_streams
aborted. On macOS fflush now likewise returns early unless the FILE's
__SWR (writing) flag is set.

guest_standard_streams, guest_fopen_errors and guest_file_timestamps
pass on macOS. Linux and Windows preprocessed sources are unchanged.
Darwin's readv, writev, preadv and pwritev fail with EINVAL when the
vector count is 0, while FreeBSD (and so the PS5) transfers nothing and
returns 0. sceKernelReadv(file, reads, 0) therefore returned an error and
guest_file_vector aborted at line 245. On macOS the four calls now return
0 for a zero count before reaching the host call; negative and oversized
counts are still rejected by CheckIovecs as before.

guest_file_vector, guest_kernel_sys, guest_standard_streams and
guest_fopen_errors pass on macOS. Linux and Windows preprocessed sources
are unchanged.
installProcessParameters() had only Windows (.procpar section) and Linux
(patched PT_SCE_PROCPARAM program header) branches, so on macOS the
scripting and lazy modes reached _init_env with no process parameters
and aborted with "invalid or missing process parameters".

On macOS libc finds them through dl_iterate_phdr, which reads the
relinker's __APS5DATA,__meta section of the main executable. The test
now places such a section in its own image and fills it with version-2
metadata holding a PT_LOAD and a 0x61000001 header that cover its fake
parameter block, mirroring what the Linux branch does to its headers.

All 9 application_heap tests pass on macOS, including scripting and lazy.
Linux and Windows preprocessed sources are unchanged.
On macOS guest mmap of any descriptor failed with ENOTSUP: the generic
branch only accepted descriptors that IsHostSharedMemoryDescriptor
recognised, and that had no macOS case, so it always said no.

- IsHostSharedMemoryDescriptor now recognises the anonymous objects that
  CreateAnonymousFile makes on macOS: regular files whose last link was
  removed (st_nlink 0) and whose F_GETPATH name starts "anyps5-shm-".
  This also makes shm read/write/seek/truncate use the shared-memory
  rules (writes bounded by the object size), as on Linux.
- mmap on macOS now takes the Linux branch: pin the descriptor, check its
  access mode against the requested protection, and accept shared-memory
  objects and regular files.

guest_shm_open passes on macOS; guest_memory, guest_mmap_fixed_anonymous,
guest_file_vector, guest_kernel_sys, guest_standard_streams and
guest_file_timestamps still pass. Linux and Windows preprocessed sources
are unchanged.
sceKernelJitMapSharedMemory with execute permission failed on macOS:
mmap of a shared file mapping with PROT_EXEC returns EPERM there, so
guest_jit_shared_memory aborted on its first read+execute view.

On macOS DoMapShared now maps executable views in two steps: it maps the
object read-write (shared) at any address, remaps those same pages onto
the placed guest range with mach_vm_remap (VM_INHERIT_SHARE, no copy),
drops the temporary view and sets the requested protection with
mprotect. Writes through other views of the object stay visible to the
executable view, and code written through a writable alias runs.
Non-executable views keep the plain mmap path.

guest_jit_shared_memory passes on macOS; guest_shm_open, guest_memory and
guest_mmap_fixed_anonymous still pass. Linux and Windows preprocessed
sources are unchanged.
guest_memory_lifetime's exit probe calls DoMprotect after the module's
static destructors have run. DoMprotect asks GuestThreadStack whether the
range is a thread stack, which locks the namespace-scope stackLock. With
libc++ ~mutex calls pthread_mutex_destroy, so that lock threw
"mutex lock failed: Invalid argument" (libstdc++'s mutex destructor is
trivial, which is why Linux never hit it).

On macOS stackLock, liveStacks and protectedStackPages are now allocated
once and never destroyed, the same way DirectMemory and GuestAllocations
already keep their state alive for the whole process.

guest_memory_lifetime passes on macOS, and all 36 guest_pthread_*,
guest_thread_*, guest_kernel_is_stack, guest_kernel_stack_protect and
guest_memory tests pass. Linux and Windows preprocessed sources are
unchanged.
ProcessParametersFixture::Install had only Windows and Linux branches and
returned false on macOS, so guest_hmd2 aborted with "process parameters
were not installed".

On macOS it now fills a __APS5DATA,__meta section in the test image with
version-2 relinker metadata (a PT_LOAD and a 0x61000001 header covering
the fake parameter block), which libc's macOS dl_iterate_phdr reports to
the process-parameter lookup — the same approach the application_heap
test uses.

guest_hmd2 passes on macOS and the 9 application_heap tests still pass.
Linux and Windows preprocessed sources are unchanged.
libusb's configure check finds pipe2 in the macOS 27 SDK, but the SDK
marks it available only from macOS 27, so on macOS 26 the weakly linked
symbol is null and libusb_init_context jumped to address 0 from
usbi_create_event. guest_usbd segfaulted in sceUsbdInit.

On Apple HAVE_PIPE2 is now cleared before libusb's checks run, so libusb
uses its pipe + fcntl(FD_CLOEXEC/O_NONBLOCK) fallback. The change sits in
if(APPLE); Linux and Windows configure exactly as before.

guest_usbd passes on macOS.
@iamthehimansh

Copy link
Copy Markdown
Contributor Author

@krishalivaibhav Whenever you have a moment, the GuestAllocations.cpp branch is still ready to open as is: fix/macos-guest-allocations-dyld, one commit on main, which compiles on macOS. You can open it straight from that branch:

gh pr create --repo boykopovar/AnyPS5 --head iamthehimansh:fix/macos-guest-allocations-dyld

I've also sent the one-line depth-plane fix for #10369 as krishalivaibhav#2, based on your current head.

AI-assisted: yes (Cana)

@iamthehimansh

Copy link
Copy Markdown
Contributor Author

@adriadam10 I closed this PR as you suggested. Split PR 1 is open as #10419: the shared-file macOS build fixes, 6 files, all macOS-only, rebased on current main, with the conventions check passing. The libc, libkernel, sockets, AGC and relinker split PRs follow one at a time from the same branch.

AI-assisted: yes (Cana)

maximilianfv added a commit to maximilianfv/AnyPS5 that referenced this pull request Oct 24, 2026
… expiry on macOS

An ITIMER_REAL expiry with a guest SIGALRM handler throws, since guest
handlers are never run from the timer thread. On Linux and Windows that
throw goes through libc's exception runtime, so an uncaught one runs the
guest's std::set_terminate handler. On macOS the host keeps libc++abi,
so the throw ended in libc++abi's terminate and the guest handler never
ran. Throw through the guest runtime there, and record the general
macOS gap in the libc debt file.

Ported from boykopovar#8658.

Co-authored-by: Himansh Raj <iamthehimansh@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
maximilianfv added a commit to maximilianfv/AnyPS5 that referenced this pull request Oct 24, 2026
… expiry on macOS

An ITIMER_REAL expiry with a guest SIGALRM handler throws, since guest
handlers are never run from the timer thread. On Linux and Windows that
throw goes through libc's exception runtime, so an uncaught one runs the
guest's std::set_terminate handler. On macOS the host keeps libc++abi,
so the throw ended in libc++abi's terminate and the guest handler never
ran. Throw through the guest runtime there, and record the general
macOS gap in the libc debt file.

Ported from boykopovar#8658.

Co-authored-by: Himansh Raj <67262056+iamthehimansh@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
oneandonlydean pushed a commit that referenced this pull request Oct 24, 2026
RenamePath compares source and destination with fs::equivalent and
treats ENOENT from it as "not the same file". libc++ reports
errc::not_supported instead when either path does not resolve, so on
macOS renaming a file over a dangling symbolic link failed with EIO
(guest_filesystem). A path that does not resolve cannot be the same file
as the other, so not_supported is cleared the same way on macOS. The same
guard is part of #7201 and #8658.

Co-Authored-By: marion909 <103169397+marion909@users.noreply.github.com>
Co-Authored-By: iamthehimansh <67262056+iamthehimansh@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
krishalivaibhav added a commit to krishalivaibhav/AnyPS5 that referenced this pull request Oct 24, 2026
NativeStat, SharedMemory, Stdio, DynamicLoader, ModuleInfo and Rtld used
Linux-only APIs (st_atim, memfd_create, sys/vfs.h, link.h and dl_iterate_phdr),
so libkernel did not compile on macOS. Add macOS paths behind __APPLE__:
st_*timespec and a long-path fstatat walk, an unlinked temp file for shared
memory, statfs, dlopen/dladdr and Mach-O segment walks for module and rtld
queries. The Linux and Windows paths are unchanged.

Extracted from feat/macos-port (boykopovar#8658).

Co-authored-by: Himansh Raj <iamthehimansh@gmail.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agc libSceAgc* build docs libc libkernel needs rebase Conflicts with main, rebase needed prx relinker shader core/shader

Projects

None yet

Development

Successfully merging this pull request may close these issues.