Compatibilidade binária entre Mac OS X e Linux

27

Preparem-se, essa pergunta provavelmente parecerá ingênua e / ou tola, visto que eu sou relativamente novo no funcionamento interno de sistemas como o Unix e na programação em geral.

Pronto? Está bem! Vou passar por cerca de três níveis de ludicrosidade, aumentando à medida que avanças.


Temos dois sistemas com hardware semelhante (o ponto principal é o processador, digamos um intel core 2 duo padrão).

Um está em execução (insira sua distribuição Linux aqui: o Ubuntu será usado a partir de agora), e o outro está em execução, digamos, Mac OS X.

Um compila um programa equivalente, digamos algo como:

int main()
{
    int cat = 33;
    int dog = 5*cat;
    return dog;
}

O código é extremamente simples, porque ainda não quero considerar as implicações das bibliotecas compartilhadas.

Quando compilado nos respectivos sistemas. Não é a principal diferença entre a saída uma questão de ELF vs Mach-O? Se alguém tirasse cada binário da formatação, deixando um binário plano, as instruções da máquina desmontada não seriam as mesmas? (talvez com algumas diferenças, dependendo dos hábitos / tendências dos compiladores).

1.) Se alguém desenvolvesse um programa para reembalar o binário plano produzido em nosso sistema Ubuntu, na formatação Mach-O, ele seria executado no sistema Mac OS X? Então, se alguém tivesse o binário compilado do suposto programa acima e se tivesse essa ferramenta mística para reembalar binários simples, programas simples seriam capazes de executar no sistema Mac OS X?


Agora vamos um pouco mais longe.

Agora temos um programa com fonte como:

#include <stdio.h>
int main()
{
    printf("I like tortoises, but not porpoises");
    return 0;
}

2.) Supondo que este programa seja compilado e vinculado estaticamente, nosso programa mágico ainda seria capaz de reembalar o binário bruto no formato Mach-O e fazê-lo funcionar no mac os X? Visto que não precisaria confiar em outros binários (para os quais o sistema mac não teria neste caso)


E agora para o nível final;

3.) E se usássemos esse suposto programa para converter todas as bibliotecas compartilhadas necessárias para o formato Mach-O e, em vez disso, compilássemos o programa acima com vínculo dinâmico. O programa ainda conseguiria executar?

Por enquanto, obviamente, cada passo do absurdo se apóia na base anterior, até para fazer sentido. portanto, se o primeiro pilar for destruído, duvido que haja muito mérito nos demais níveis.

Definitivamente, eu nem chegaria a pensar nisso com programas com GUI em mente. Os sistemas de janelas provavelmente seriam uma dor de cabeça totalmente diferente. Estou apenas considerando programas de linha de comando nesta fase.

Agora, convido o mundo a me corrigir e a contar tudo o que há de errado com minha linha de pensamento absurda.

zec
fonte
o equivalente de vinho por binários OS X é querido: darling.dolezel.info
strugee

Respostas:

25

Você esquece uma coisa crucial, a saber, que seu programa precisará interagir com o sistema operacional para fazer qualquer coisa interessante.

As convenções são diferentes entre o Linux e o OS X, portanto, o mesmo binário não pode ser executado como está sem essencialmente ter um pedaço de código dependente do sistema operacional para poder interagir com ele. Muitas dessas coisas estão ocultas nas bibliotecas, as quais você precisa vincular e isso significa que seu programa precisa ser vinculável, e a vinculação também é diferente entre os dois sistemas.

E assim continua e continua. O que na superfície parece fazer a mesma coisa é muito diferente nos detalhes reais.

Thorbjørn Ravn Andersen
fonte
5
Isso está basicamente correto quanto ao problema, mas o problema não é realmente bibliotecas (que podem ser arrastadas), mas chamadas de sistema, que são solicitações ao kernel do sistema operacional. Se o sistema operacional não fornecer uma interface de chamada do sistema compatível, você estará sem sorte.
mattdm
11
Aah, isso é excelente. Esse é exatamente o tipo de correção construtiva que eu esperava. Muito obrigado: D Você poderia me falar mais sobre essas supostas chamadas de sistema ou me redirecionar para algum lugar onde eu possa aprender mais sobre elas?
zec
3
Eles não são "supostos", são reais. :) Aqui está um bom começo: ibm.com/developerworks/linux/library/l-system-calls
mattdm
7
Dito isto, sua idéia "louca" não é completamente impossível. Apenas muito trabalho. O projeto Wine é essencialmente este para a execução de binários do MS Windows no Linux (ou OS X). Ele fornece uma camada de conversão para chamadas do sistema. wiki.winehq.org/…
mattdm 23/02
11
Bem, achei que não seria completamente impossível, mas também não esperava que fosse tão simples quanto o descrevi. Eu escrevi a pergunta com a intenção de ser corrigida. Às vezes, isso parece ser um método mais eficiente de chegar ao cerne da questão do que fazer uma pergunta direta como "Como converter um binário do linux para rodar no Mac OS". Também usei vinho de vez em quando, mas nunca havia realmente pensado sobre como funcionava antes, acho que vou dar uma olhada nele em algum momento agora.
zec
17

Isso é possível se alguém quiser gastar tempo suficiente para que isso aconteça. O projeto Darling está tentando isso, embora, até o momento, ele esteja em um estado bastante primitivo.

Isso já foi feito com sucesso em outras plataformas:

  • O Solaris e o UnixWare incluem um programa auxiliar chamado lxrunque funciona da seguinte forma sudo: você passa o nome e os parâmetros do executável para o auxiliar e ele corrige as coisas dinamicamente para que o executável possa conversar com o sistema operacional. O site oficial (abaixo, link para o arquivo ) diz que é com taxa de bits .

  • O kernel do Linux já teve um recurso chamado iBCS que fez o inverso, exceto que não precisava de um ajudante porque o kernel reconheceu os binários "estrangeiros" diretamente. Ele caiu em desuso durante a série de desenvolvimento do kernel 2.3 , provavelmente porque a pequena batalha do servidor Unix terminou essencialmente quando o 2.4 foi lançado.

  • O kernel do FreeBSD pode ser configurado para reconhecer os binários do Linux e executá-los como se fossem nativos. Esse recurso parece estar em melhor forma do que os dois acima.

    O OpenBSD e o NetBSD têm recursos semelhantes.

O OS X possui muito FreeBSD , portanto, portar seu suporte ao Linux pode ser simples.

Warren Young
fonte
2
Uma das razões pelas quais isso não é importante para os programas Linux → outras plataformas é: não há aplicativos significativos apenas para Linux para os quais a fonte não está disponível. Você deseja executar seu programa no OS X ou Solaris, recompilá-lo e pronto. Pode haver um pouco de migração para fazer onde o código foi escrito de maneiras específicas do Linux, mas geralmente isso não é muito trabalhoso, especialmente se comparado à manutenção da camada de compatibilidade. A compatibilidade com o Linux do FreeBSD era muito importante quando o Netscape era um binário distribuído apenas para Linux, e provavelmente ainda é usado para o Adobe Flash Player.
mattdm
@ Jörg W Mittag - também, você precisava ter as bibliotecas do sistema da outra plataforma disponível. Essa pode ter sido a base do processo contra a AutoZone. Mas honestamente eu esqueço os detalhes e mal me importo mais. :)
mattdm
Então, o que você diz é essencialmente que, se o sistema operacional X fornecer os mesmos serviços que o sistema operacional Y, um binário poderá ser executado nos dois. Isso é verdade, mas exigem um esforço deliberado para o sistema X. Não tenho conhecimento de qualquer sistema operacional sendo compatível desta forma com o OS X.
Thorbjørn Ravn Andersen
bitrotten? Eu vou me mostrar.
GnP 13/12
3

Eu concordo com todos, mas quero acrescentar que, embora isso leve uma quantidade significativa de tempo e esforço, não seria quase o tempo necessário para desenvolver o Wine.

Grande parte do difícil desenvolvimento do Wine é que eles estão portando um formato binário de um sistema operacional de código fechado e MUITAS chamadas do sistema não são documentadas. Eles tiveram que essencialmente fazer engenharia reversa do sistema operacional.

Se alguém fizesse isso de um sistema operacional aberto para outro, provavelmente poderia fazê-lo em 1/10 do tempo, já que a camada de compatibilidade poderia ser copiada / colada do outro sistema operacional se uma chamada equivalente do sistema nativo não existe. Obviamente, na maioria dos casos em todo o mundo POSIX, haverá uma chamada nativa disponível.

Outro projeto digno de nota é o ReactOS, onde eles estão essencialmente criando uma versão completa do Windows compatível com binários ... sem a necessidade do Wine.

Joe
fonte
1

É tecnicamente factível no macOS, mas não sem um esforço significativo, embora parte desse esforço já tenha sido feito para nós.

  • Tanto o macOS quanto o Red Hat Enterprise Linux renomeado foram certificados como UNIX 03. Isso significa que, em princípio, as chamadas POSIX devem ter a mesma API.
  • O macOS e o Linux usam o System V ABI para a plataforma amd64. Isso significa que para o amd64 o macOS e o Linux devem ter ABI e API compatíveis.
  • O macOS usa o Mach-O como formato executável nativo, enquanto o Linux usa o ELF. Isso facilita as coisas, pois o formato do arquivo executável pode ser usado para distinguir se a camada de compatibilidade deve ser chamada. Isso exigiria algo como isso binfmt_misc.
  • Existe uma extensão do kernel do macOS de terceiros que fornece exatamente isso. Agora, temos uma maneira de convencer o macOS a carregar o ELF, precisamos do nosso especial, ld-linux.soque é um executável Mach-O que carregaria o nosso ELF e o executaria.

Agora, o que precisamos é de pelo menos um especial ld-linux.soque possa fazer o seguinte:

  • Seja um executável do Mach-O ou dyldele próprio,
  • Pode carregar arquivos ELF do Linux na memória no endereço correto,
  • Esperemos que tenha a capacidade de mapear o soname do Linux para os do macOS (exemplo /lib/libc.so.6para /lib/libSystem.B.dylib) e carregar o Mach-O correspondente quando um ELF correspondente não for encontrado, para que possamos reutilizar as bibliotecas do macOS

Com esse carregador acima do ELF que não produz syscalls diretos, há uma boa chance de funcionar, mas o ELF com syscalls pode não funcionar. Um segundo componente que pode ser útil seria uma extensão do kernel que captura esses syscalls do Linux e os mapeia para os do macOS. Como nos desktops, é necessária uma implementação especial do mesa para mapear as chamadas gráficas do Linux para OpenGL.frameworke Metal.framework.

Maxthon Chan
fonte
0

Há vários aplicativos Linux especializados para os quais isso seria uma grande ajuda. No lado do FPGA, o Quartus e o Vivado são bons exemplos de programas executados no Linux e é improvável que haja código-fonte disponível para eles ou programas similares direcionados aos FPGAs mais recentes.

Penso que a resposta simples para sua pergunta é: recompile no MacOS onde você tem a fonte e forme um grupo para fornecer a capacidade se você tiver tempo - e isso será uma tarefa demorada.

Daniel Wisehart
fonte