Compatibilidad binaria entre Mac OS X y Linux

27

Prepárense, esta pregunta probablemente parecerá ingenua y / o tonta, ya que soy relativamente nuevo en el funcionamiento interno de los sistemas tipo UNIX y en la programación en general.

Listo? ¡Okay! Voy a pasar por unos 3 niveles de ludicrosidad, aumentando a medida que avance.


Tenemos dos sistemas con hardware similar (el punto principal es el procesador, digamos un Intel Core 2 Duo estándar).

Uno se está ejecutando (inserte su distribución de Linux aquí: Ubuntu se usará en adelante), y el otro se está ejecutando, digamos Mac OS X.

Uno compila un programa equivalente. Digamos algo como:

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

El código es extremadamente simple, porque todavía no quiero considerar las implicaciones de las bibliotecas compartidas.

Cuando se compila en los sistemas respectivos. ¿No es la principal diferencia entre la salida una cuestión de ELF vs Mach-O? Si uno despojara cada binario del formato, dejando un binario plano, ¿no serían las mismas instrucciones desmontadas de la máquina? (con quizás algunas diferencias dependiendo de los hábitos / tendencias del compilador).

1.) Si uno desarrollara un programa para reempaquetar el binario plano producido desde nuestro sistema Ubuntu, en el formato Mach-O, ¿se ejecutaría en el sistema Mac OS X? Entonces, si uno solo tuviera el binario compilado del supuesto programa anterior, y uno tuviera esta herramienta mística para reempaquetar binarios planos, ¿los programas simples podrían ejecutarse en el sistema Mac OS X?


Ahora vamos a llevarlo un poco más lejos.

Ahora tenemos un programa con fuente como:

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

2.) Suponiendo que este programa se compila y está vinculado estáticamente, ¿podría nuestro programa mágico volver a empaquetar el binario sin formato en el formato Mach-O y hacerlo funcionar en Mac OS X? Como no necesitaría depender de ningún otro binario (para lo cual el sistema Mac no tendría en este caso)


Y ahora para el nivel final;

3.) ¿Qué pasa si usamos este supuesto programa para convertir todas las bibliotecas compartidas necesarias al formato Mach-O, y luego compilamos el programa anterior con enlaces dinámicos? ¿El programa todavía podría ejecutarse?

Eso debería ser todo por ahora, obviamente cada paso de lo absurdo se basa en la base anterior, incluso para tener sentido. así que si el primer pilar se destruye, dudo que haya mucho mérito para los niveles restantes.

Definitivamente, ni siquiera iría tan lejos como para pensar en esto con programas con GUI en mente. Los sistemas de ventanas probablemente serían otro dolor de cabeza. Solo estoy considerando programas de línea de comandos en esta etapa.

Ahora, invito al mundo a que me corrija y me diga todo lo que está mal en mi absurda línea de pensamiento.

zec
fuente
el equivalente de vino para OS X binarios es de Darling: darling.dolezel.info
strugee

Respuestas:

25

Olvida una cosa crucial, a saber, que su programa tendrá que interactuar con el sistema operativo para hacer algo interesante.

Las convenciones son diferentes entre Linux y OS X, por lo que el mismo binario no puede ejecutarse tal cual sin esencialmente tener una porción de código dependiente del sistema operativo para poder interactuar con él. Muchas de estas cosas están ocultas en las bibliotecas, que luego debe vincular, y eso significa que su programa debe ser vinculable, y la vinculación también es diferente entre los dos sistemas.

Y así sigue y sigue. Lo que en la superficie suena como hacer lo mismo es muy diferente en los detalles reales.

Thorbjørn Ravn Andersen
fuente
55
Esto es básicamente correcto en cuanto a cuál es el problema, pero el problema no es realmente bibliotecas (que podrían arrastrarse) sino llamadas al sistema, que son solicitudes al núcleo del sistema operativo. Si el sistema operativo no proporciona una interfaz de llamada del sistema compatible, no tiene suerte.
mattdm
1
Aah, esto es excelente. Este es exactamente el tipo de corrección constructiva que esperaba. Muchas gracias: D ¿Podría contarme más sobre estas supuestas llamadas al sistema o redirigirme a algún lugar donde pueda obtener más información sobre ellas?
zec
3
No son "supuestos", son reales. :) Aquí hay un buen comienzo: ibm.com/developerworks/linux/library/l-system-calls
mattdm
77
Dicho esto, tu idea "loca" no es completamente imposible. Solo mucho trabajo. El proyecto Wine es esencialmente esto para ejecutar binarios de MS Windows en Linux (u OS X). Proporciona una capa de traducción para llamadas al sistema. wiki.winehq.org/…
mattdm
1
Bueno, pensé que no sería completamente imposible, pero tampoco esperaba que fuera tan simple como lo describí. Escribí la pregunta con la intención de ser corregida. Esto a veces parece ser un método más eficiente para llegar al meollo del asunto que hacer una pregunta directa como "¿Cómo convierto un binario de Linux para que se ejecute en Mac OS"? También he usado vino de vez en cuando, pero nunca antes había reflexionado sobre cómo funcionaba antes, creo que voy a investigarlo en algún momento.
zec
17

Esto es factible si alguien quiere pasar el tiempo suficiente para que esto suceda. El proyecto Darling está intentando esto, aunque al momento de escribir esto, está en un estado bastante primitivo.

Se ha realizado con éxito antes en otras plataformas:

  • Solaris y UnixWare incluyen un programa auxiliar llamado lxrunque funciona de la siguiente manera sudo: le pasa el nombre y los parámetros del ejecutable al asistente y lo arregla dinámicamente para que el ejecutable pueda comunicarse con el sistema operativo. El sitio oficial (abajo, enlace de archivo ) dice que está bitrotted .

  • El núcleo de Linux una vez tuvo una característica llamada iBCS que hizo lo contrario, excepto que no necesitaba un ayudante porque el núcleo reconocía los binarios "externos" directamente. Se cayó en desuso durante el desarrollo del núcleo de la serie 2.3 , muy probablemente debido a la pequeña batalla servidor Unix era esencialmente sobre una vez que salió de 2,4.

  • El kernel de FreeBSD se puede configurar para reconocer los binarios de Linux y ejecutarlos como si fueran nativos. Esta característica parece estar en mejor forma que las dos anteriores.

    OpenBSD y NetBSD tienen características similares.

OS X tiene una gran cantidad de FreeBSD , por lo que portar su soporte para Linux podría ser sencillo.

Warren Young
fuente
2
Una de las razones por las que esto no es un gran problema para los programas Linux → otras plataformas es: no hay aplicaciones significativas solo para Linux para las que la fuente no esté disponible. Desea ejecutar su programa en OS X o Solaris, vuelva a compilarlo y listo. Puede haber un poco de portabilidad para hacer donde el código fue escrito en formas específicas de Linux, pero en general no es mucho trabajo, especialmente en comparación con el mantenimiento de la capa de compatibilidad. La compatibilidad con Linux de FreeBSD fue un gran problema cuando Netscape era un binario distribuido solo para Linux, y probablemente todavía se usa para Adobe Flash Player.
mattdm
@ Jörg W Mittag: además, tenía que tener disponibles las bibliotecas del sistema de la otra plataforma. Esta puede haber sido la base de su demanda contra AutoZone. Pero, sinceramente, olvido los detalles y apenas me importan. :)
mattdm
Entonces, lo que usted dice es esencialmente que si el sistema operativo X proporciona los mismos servicios que el sistema operativo Y, entonces un binario puede ejecutarse en ambos. Esto es cierto, pero requiere un esfuerzo deliberado para el sistema X. No tengo conocimiento de que ningún sistema operativo sea compatible de esta manera con OS X.
Thorbjørn Ravn Andersen
bitrotten? Me mostraré afuera.
GnP
3

Estoy bastante de acuerdo con todos, pero quiero agregar que, si bien esto requeriría una gran cantidad de tiempo y esfuerzo, no sería tanto como se ha llevado a desarrollar Wine.

Gran parte de lo difícil en el desarrollo de Wine es que están portando un formato binario desde un sistema operativo de código cerrado y MUCHAS de las llamadas del sistema no están documentadas. Básicamente, tuvieron que aplicar ingeniería inversa al sistema operativo.

Si alguien hiciera esto de un sistema operativo abierto a otro sistema operativo abierto, probablemente podría hacerlo en 1/10 de las veces, ya que la capa de compatibilidad podría copiarse / pegarse desde el otro sistema operativo si una llamada de sistema nativo equivalente no existe Por supuesto, en la mayoría de los casos en todo el mundo POSIX, habrá una llamada nativa disponible.

Otro proyecto notable es ReactOS, donde esencialmente están creando una versión de Windows totalmente compatible con binarios ... sin necesidad de Wine.

joe
fuente
1

Es técnicamente factible en macOS, pero no sin un esfuerzo significativo, aunque parte del esfuerzo ya está hecho para nosotros.

  • Tanto macOS como Red Hat Enterprise Linux han sido certificados como UNIX 03. Esto significa que, en principio, las llamadas POSIX deben tener la misma API.
  • Tanto macOS como Linux usan System V ABI para la plataforma amd64. Esto significa que para amd64 macOS y Linux deberían tener ABI y API compatibles.
  • macOS usa Mach-O como su formato ejecutable nativo mientras que Linux usa ELF. Esto facilita las cosas, ya que el formato de archivo ejecutable se puede utilizar para distinguir si se debe llamar a la capa de compatibilidad. Sin embargo, esto requeriría algo así binfmt_misc.
  • Existe una extensión de kernel de macOS de terceros que proporciona exactamente eso. Ahora tenemos una forma de cargar convencer a macOS para cargar ELF, necesitamos nuestro especial, ld-linux.soque es un ejecutable de Mach-O que cargaría nuestro ELF y lo ejecutaría.

Ahora lo que necesitamos es al menos un especial ld-linux.soque pueda hacer lo siguiente:

  • Ser un ejecutable de Mach-O o en dyldsí mismo,
  • Puede cargar archivos ELF de Linux en la memoria en la dirección correcta,
  • Es de esperar que tenga la capacidad de asignar soname de Linux a macOS (ejemplo /lib/libc.so.6a /lib/libSystem.B.dylib) y cargar Mach-O correspondiente cuando no se encuentra un ELF coincidente, por lo que podemos reutilizar las bibliotecas de macOS

Con solo ese cargador por encima de ELF que no realiza llamadas de sistema directas, tiene una buena posibilidad de funcionar, pero es posible que ELF con llamadas de sistema no funcione. Un segundo componente que podría ser útil sería una extensión del kernel que capta esas llamadas al sistema de Linux y las asigna a las de macOS. A partir de los usos de escritorio, se necesita una implementación especial de mesa para asignar llamadas gráficas de Linux a OpenGL.frameworky Metal.framework.

Maxthon Chan
fuente
0

Hay una serie de aplicaciones de Linux especializadas para las que esto sería de gran ayuda. Por el lado de FPGA, Quartus y Vivado son buenos ejemplos de programas que se ejecutan en Linux y es poco probable que haya código fuente disponible para ellos o programas similares que se dirijan a los últimos FPGA.

Creo que la respuesta simple a su pregunta es: recompile en MacOS donde tiene la fuente y forme un grupo para proporcionar la capacidad si tiene tiempo, y será una tarea que requiere mucho tiempo.

Daniel Wisehart
fuente