Using ld on macOS to turn a raw arm64 binary into an executable Mach-O binary

2026-05-12

Stack Overflow: View Question

Tags: macos, linker, mach-o

Score: 0 | Views: 71

The asker is building a Brainfuck-to-arm64 compiler on macOS. Their compiler emits a raw binary — pure arm64 machine code with no headers, no load commands, no segments. They've correctly identified that macOS won't execute this directly: the kernel's execve path on Darwin only knows how to launch Mach-O binaries (or scripts via shebangs). They want to wrap that raw blob into a minimal Mach-O executable using ld.

Why it's harder than it looks: ld on macOS doesn't ingest raw binaries. It consumes Mach-O object files (.o) with symbol tables, relocations, and section metadata. There's no equivalent to GNU ld's -b binary --oformat trick that lets you embed an arbitrary blob as a section. Worse, since around Big Sur, every Mach-O executable on arm64 macOS must be code-signed — even an ad-hoc signature (codesign -s -) is required, or the kernel refuses to launch it with a killed: 9. And the modern ld (the "new linker," ld-prime) is stricter than its predecessor about needing a proper entry point symbol and an LC_MAIN load command.

Direction toward a solution:

Gotchas:

The challenge: macOS's "binary must be a signed Mach-O" requirement turns what would be a one-line objcopy on Linux into an exercise in load-command archaeology.

All newsletters