Skip to content

feat(runtime/darwin): arm64 entry via LC_MAIN register convention#325

Merged
octalide merged 2 commits into
devfrom
feat/324-darwin-lcmain-entry
Jun 29, 2026
Merged

feat(runtime/darwin): arm64 entry via LC_MAIN register convention#325
octalide merged 2 commits into
devfrom
feat/324-darwin-lcmain-entry

Conversation

@octalide

Copy link
Copy Markdown
Collaborator

Part of briar-systems/mach#1718 (the dynamic/PIE darwin epic). Pairs with the mach PIE-writer child (briar-systems/mach#1722).

What

mach is moving darwin arm64 executables to PIE LC_MAIN images (required to exec on Apple Silicon — proven in mach#1718). LC_MAIN hands control to a C-main-style entry with arguments in registers, not on the stack. This rewrites the darwin arm64 _start to capture argc/argv/envp from x0/x1/x2 (the LC_MAIN register ABI dyld enters with) instead of reading them off [sp].

Everything else is unchanged: still stores into _rt_argc/_rt_argv/_rt_envp, calls _rt_init then main, exits via raw svc 0x80 (no libSystem). The x86_64 darwin entry is untouched (it keeps the LC_UNIXTHREAD stack convention until the paired mach writer switches it too).

Validation

The darwin runtime is cross-compile-only on the Linux CI host, so this is validated end-to-end on the mach side: the paired PIE writer (mach#1722) cross-builds an aarch64-darwin compiler and execs it on a macos-14 runner (no Killed: 9) where it self-hosts. mach-std CI stays green (the darwin arm64 file is $if-guarded off non-darwin builds).

Closes #324

🤖 Generated with Claude Code

octalide added 2 commits June 28, 2026 20:37
darwin arm64 executables become PIE LC_MAIN images (briar-systems/mach#1718,
#1722). dyld enters an LC_MAIN program like main(argc, argv, envp) with the
arguments in registers, not on the stack, so the entry captures argc/argv/envp
from x0/x1/x2 instead of reading them off [sp]. raw svc 0x80 is retained; the
x86_64 darwin entry is unchanged.

Closes #324
darwin mkdirat is 475 (464 is openat_nocancel), unlinkat is 472, and faccessat
is 466 - the previous 464/466/468 were wrong. these only surfaced once arm64
darwin binaries actually run (briar-systems/mach#1722): the native self-host build
failed to create its object directory because mkdirat hit the wrong trap.

Refs #324.
@octalide

Copy link
Copy Markdown
Collaborator Author

Added a second commit to this branch: fix(os/darwin): correct mkdirat/unlinkat/faccessat syscall numbers.

mkdirat was 464 (that number is openat_nocancel), unlinkat was 466, faccessat was 468 — all wrong. The authoritative XNU values are mkdirat=475, unlinkat=472, faccessat=466. These only surfaced once arm64 darwin binaries actually run (the mach PIE writer, briar-systems/mach#1722): the native self-host build on a macos-14 runner failed at "failed to create object directory" because mkdirat hit the wrong trap. With the fix, the native a→b→c self-host fixpoint converges on Apple Silicon and mach test . runs (425/426 pass).

These are latent darwin-runtime bugs that were never exercised before (darwin binaries couldn't run); folding them in here keeps all the "make arm64 darwin actually run" runtime work in one PR. Happy to split into a separate PR if preferred.

@octalide octalide marked this pull request as ready for review June 29, 2026 02:33
@octalide octalide merged commit e6b5ea5 into dev Jun 29, 2026
2 checks passed
@octalide octalide deleted the feat/324-darwin-lcmain-entry branch June 29, 2026 02:33
This was referenced Jun 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

runtime/darwin: arm64 entry via LC_MAIN register convention (PIE darwin support)

1 participant