A ABI inteira é diferente, não apenas o formato binário (Mach-O versus ELF) como sepp2k mencionou.
Por exemplo, enquanto Linux e Darwin / XNU (o kernel do OS X) usam sc
no PowerPC e int 0x80
/ sysenter
/ syscall
no x86 para entrada syscall, não há muito mais em comum a partir daí.
Darwin direciona números syscall negativos no microkernel Mach e números syscall positivos no kernel monolítico BSD - veja xnu / osfmk / mach / syscall_sw.h e xnu / bsd / kern / syscalls.master . Os números de syscall do Linux variam de acordo com a arquitetura - veja linux / arch / powerpc / include / asm / unistd.h , linux/arch/x86/include/asm/unistd_32.h e linux / arch / x86 / include / asm / unistd_64.h - mas são todos não-negativos. Então, obviamente, os números syscall, os argumentos syscall e até mesmo quais os syscalls existem são diferentes.
As bibliotecas de tempo de execução padrão C também são diferentes; Na maioria das vezes, o Darwin herda a libc do FreeBSD, enquanto o Linux normalmente usa o glibc (mas existem alternativas, como eglibc e dietlibc e uclibc e Bionic).
Sem mencionar que toda a pilha de gráficos é diferente; ignorando todas as bibliotecas Objective-C do Cocoa, os programas GUI no OS X conversam com o WindowServer sobre as portas do Mach, enquanto no Linux, os programas GUI geralmente conversam com o servidor X sobre os soquetes do domínio UNIX usando o protocolo X11. Claro que existem exceções; você pode executar o X no Darwin, e você pode ignorar o X no Linux, mas os aplicativos do OS X definitivamente não falam sobre o X.
Como Wine, se alguém colocar o trabalho em
- implementando um carregador binário para o Mach-O
- capturar todo o syscall do XNU e convertê-lo em syscalls apropriados do Linux
- escrevendo substituições para bibliotecas do OS X, como CoreFoundation, conforme necessário
- escrevendo substituições para serviços do OS X, como WindowServer, conforme necessário
então é possível executar um programa OS X "nativamente" no Linux. Anos atrás, Kyle Moffet fez algum trabalho no primeiro item, criando um protótipo binfmt_mach-o para Linux, mas nunca foi concluído e não conheço nenhum outro projeto semelhante.
(Em teoria isso é bem possível, e esforços semelhantes foram feitos muitas vezes; além do Wine, o próprio Linux tem suporte para executar binários de outros UNIXs como HP-UX e Tru64, e o O projeto Glendix visa trazer a compatibilidade do Plan 9 para o Linux.)
Alguém fez esforço para implementar um carregador binário Mach-O e um tradutor de API para Linux!
shinh / maloader - GitHub adota a abordagem Wine de carregar o binário e capturar / traduzir todas as chamadas da biblioteca no userspace. Ele ignora completamente o syscalls e todas as bibliotecas relacionadas a gráficos, mas é o suficiente para fazer com que muitos programas de console funcionem.
ODarling baseia-se no maloader, adicionando bibliotecas e outros bits de tempo de execução de suporte.