Compatibilité binaire entre Mac OS X et Linux

27

Préparez-vous, cette question semblera probablement naïve et / ou stupide, étant donné que je suis relativement nouveau dans le fonctionnement interne des systèmes de type Unix et dans la programmation en général.

Prêt? D'accord! Je vais passer par environ 3 niveaux de ridicule, augmentant au fur et à mesure.


Nous avons deux systèmes avec un matériel similaire (le principal étant le processeur, disons un duo Intel Core 2 standard).

L'un est en cours d'exécution (insérez votre distribution linux ici: Ubuntu sera désormais utilisé), et l'autre est en cours d'exécution, disons Mac OS X.

On compile un programme équivalent, Disons quelque chose comme:

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

Le code est extrêmement simple, car je ne veux pas encore considérer les implications des bibliothèques partagées.

Une fois compilé sur les systèmes respectifs. La différence principale entre la sortie n'est-elle pas une question d'ELF vs Mach-O? Si l'on supprimait chaque binaire du formatage, en laissant un binaire plat, les instructions machine démontées ne seraient-elles pas les mêmes? (avec peut-être quelques différences selon les habitudes / tendances des compilateurs).

1.) Si l'on devait développer un programme pour reconditionner le binaire plat produit à partir de notre système Ubuntu, au format Mach-O, fonctionnerait-il dans le système Mac OS X? Ensuite, si l'on ne disposait que du binaire compilé du programme supposé ci-dessus et que l'on avait cet outil mystique pour reconditionner les binaires plats, des programmes simples pourraient-ils s'exécuter sur le système Mac OS X?


Allons maintenant un peu plus loin.

Nous avons maintenant un programme avec source tel que:

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

2.) En supposant que ce programme est compilé et lié statiquement, notre programme magique serait-il toujours capable de reconditionner le binaire brut au format Mach-O et de le faire fonctionner sur mac os X? Étant donné qu'il n'aurait pas besoin de s'appuyer sur d'autres binaires (pour lesquels le système mac n'aurait pas dans ce cas)


Et maintenant pour le niveau final;

3.) Et si nous utilisions ce programme supposé pour convertir toutes les bibliothèques partagées nécessaires au format Mach-O, puis compilions le programme ci-dessus avec une liaison dynamique. Le programme réussirait-il toujours à fonctionner?

Ça devrait être ça pour l'instant, évidemment chaque étape de l'absurdité s'appuie sur la base précédente, même pour donner un sens. donc si le tout premier pilier est détruit, je doute qu'il y ait beaucoup de mérite aux niveaux restants.

Je n'irais certainement pas jusqu'à penser à cela avec des programmes avec GUI à l'esprit. Les systèmes de fenêtrage seraient probablement un tout autre casse-tête. Je ne considère que les programmes de ligne de commande à ce stade.

Maintenant, j'invite le monde à me corriger et à me dire tout ce qui ne va pas dans ma façon de penser absurde.

zec
la source
l'équivalent de binaires Wine pour OS X est Darling: darling.dolezel.info
strugee

Réponses:

25

Vous oubliez une chose cruciale, à savoir que votre programme devra interagir avec le système d'exploitation pour faire quelque chose d'intéressant.

Les conventions sont différentes entre Linux et OS X, donc le même binaire ne peut pas fonctionner tel quel sans avoir essentiellement un morceau de code dépendant du système d'exploitation pour pouvoir interagir avec lui. Beaucoup de ces choses sont cachées dans les bibliothèques, que vous devez ensuite relier, ce qui signifie que votre programme doit être lié, et la liaison est également différente entre les deux systèmes.

Et ainsi de suite. Ce qui ressemble à la surface à la même chose est très différent dans les détails réels.

Thorbjørn Ravn Andersen
la source
5
Ceci est fondamentalement correct quant au problème, mais le problème n'est pas vraiment les bibliothèques (qui pourraient être traînées) mais les appels système, qui sont des requêtes vers le noyau du système d'exploitation. Si le système d'exploitation ne fournit pas d'interface d'appel système compatible, vous n'avez pas de chance.
mattdm
1
Aah, c'est excellent. C'est exactement le genre de correction constructive que j'espérais. Merci beaucoup: D Pourriez-vous m'en dire plus sur ces appels système supposés, ou me rediriger vers un endroit où je peux en savoir plus?
zec
3
Ils ne sont pas "supposés", ils sont réels. :) Voici un bon début: ibm.com/developerworks/linux/library/l-system-calls
mattdm
7
Cela dit, votre idée "folle" n'est pas complètement impossible. Juste beaucoup de travail. Le projet Wine est essentiellement destiné à exécuter des binaires MS Windows sur Linux (ou OS X). Il fournit une couche de traduction pour les appels système. wiki.winehq.org/…
mattdm
1
Eh bien, je pensais que ce ne serait pas complètement impossible, mais je ne m'attendais pas non plus à ce que ce soit presque aussi simple que je l'ai décrit. J'ai écrit la question avec l'intention d'être corrigée. Cela semble parfois être une méthode plus efficace pour aller au cœur du problème que de poser une question directe telle que "Comment convertir un binaire linux pour qu'il s'exécute sur Mac OS". De plus, j'ai utilisé du vin de temps en temps, mais je n'avais jamais vraiment réfléchi à la façon dont il fonctionnait auparavant, je pense que je vais y aller un jour.
zec
17

C'est faisable si quelqu'un veut passer suffisamment de temps pour y arriver. Le projet Darling tente cela, bien qu'à ce jour, il est dans un état assez primitif.

Cela a déjà été fait avec succès sur d'autres plateformes:

  • Solaris et UnixWare incluent un programme d'aide appelé lxrunqui fonctionne quelque chose comme sudo: vous passez votre nom et paramètres exécutables à l'aide et il corrige les choses dynamiquement afin que l'exécutable puisse parler au système d'exploitation. Le site officiel (vers le bas, lien vers l' archive ) indique qu'il est bittrotté .

  • Le noyau de Linux avait autrefois une fonctionnalité appelée iBCS qui faisait l'inverse, sauf qu'il n'avait pas besoin d'un assistant car le noyau reconnaissait directement les binaires "étrangers". Il est tombé en ruine pendant la série de développement du noyau 2.3 , probablement parce que la petite bataille du serveur Unix était essentiellement terminée une fois la version 2.4 sortie.

  • Le noyau de FreeBSD peut être configuré pour reconnaître les binaires Linux et les exécuter comme s'ils étaient natifs. Cette fonctionnalité semble être en meilleure forme que les deux précédentes.

    OpenBSD et NetBSD ont des fonctionnalités similaires.

OS X contient beaucoup de FreeBSD , donc porter son support Linux peut être simple.

Warren Young
la source
2
L'une des raisons pour lesquelles ce n'est pas un gros problème pour les programmes Linux → d'autres plates-formes est: il n'y a pas d'applications importantes uniquement pour Linux pour lesquelles la source n'est pas disponible. Vous voulez exécuter votre programme sur OS X ou Solaris, le recompiler, et c'est parti. Il peut y avoir un peu de portage à faire là où le code a été écrit de manière spécifique à Linux, mais généralement ce n'est pas beaucoup de travail, en particulier par rapport au maintien de la couche de compatibilité. La compatibilité Linux de FreeBSD était très importante lorsque Netscape était un binaire distribué uniquement pour Linux, et est probablement toujours utilisé pour Adobe Flash Player.
mattdm
@ Jörg W Mittag - vous devez également disposer des bibliothèques système de l'autre plate-forme. Cela peut avoir été la base de leur poursuite contre AutoZone. Mais honnêtement, j'oublie les détails et je m'en soucie à peine. :)
mattdm
Donc, ce que vous dites est essentiellement que si le système d'exploitation X fournit les mêmes services que le système d'exploitation Y, un binaire peut s'exécuter sous les deux. C'est vrai, mais cela nécessite un effort délibéré pour le système X. Je ne connais aucun système d'exploitation compatible de cette façon avec OS X.
Thorbjørn Ravn Andersen
bitrotten? Je vais me montrer.
GnP
3

Je suis à peu près d'accord avec tout le monde, mais je tiens à ajouter que, même si cela prendrait beaucoup de temps et d'efforts, ce ne serait pas autant que ce qu'il a fallu pour développer Wine.

Une grande partie de ce qui est difficile dans le développement de Wine, c'est qu'ils portent un format binaire à partir d'un système d'exploitation à source fermée et de nombreux appels système ne sont pas documentés. Ils devaient essentiellement effectuer une rétro-ingénierie du système d'exploitation.

Si quelqu'un devait faire cela d'un OS ouvert à un autre OS ouvert, il pourrait probablement le faire en 1/10 du temps, car la couche de compatibilité pourrait tout à fait être copiée / collée à partir de l'autre OS si un appel système natif équivalent n'existe pas. Bien sûr, dans la plupart des cas dans le monde POSIX, un appel natif sera disponible.

Un autre projet à noter est ReactOS, où ils créent essentiellement une version compatible binaire complète de Windows ... pas besoin de Wine.

Joe
la source
1

Il est techniquement réalisable sous macOS, mais non sans effort important, bien qu'une partie de l'effort soit déjà fait pour nous.

  • MacOS et un Red Hat Enterprise Linux renommé ont tous deux été certifiés UNIX 03. Cela signifie en principe que les appels POSIX doivent avoir la même API.
  • MacOS et Linux utilisent System V ABI pour la plateforme amd64. Cela signifie que pour amd64, macOS et Linux doivent avoir une ABI et une API compatibles.
  • macOS utilise Mach-O comme format exécutable natif tandis que Linux utilise ELF. Cela facilite les choses, car le format de fichier exécutable peut être utilisé pour distinguer si la couche de compatibilité doit être appelée. Cela nécessiterait quelque chose comme ça binfmt_misc.
  • Il existe une extension de noyau macOS tierce qui fournit exactement cela. Maintenant, nous avons un moyen de charger convaincre macOS de charger ELF, nous avons besoin de notre spécial ld-linux.soqui est lui-même un exécutable Mach-O qui chargerait notre ELF et l'exécuterait.

Maintenant, ce dont nous avons besoin est au moins un spécial ld-linux.soqui peut faire ce qui suit:

  • Être un exécutable Mach-O ou dyldlui-même,
  • Peut charger des fichiers Linux ELF en mémoire à la bonne adresse,
  • Si tout va bien a la capacité de la carte Linux soname à macos ceux ( par exemple /lib/libc.so.6à /lib/libSystem.B.dylib) et la charge correspondant Mach-O lorsqu'un correspondant ELF ne se trouve pas, donc nous pouvons réutiliser les bibliothèques macos

Avec juste ce chargeur au-dessus d'ELF qui ne fait pas d'appels sys directs a de bonnes chances de fonctionner, mais ELF avec syscalls pourrait ne pas fonctionner. Un deuxième composant qui pourrait être utile serait une extension du noyau qui intercepte ces appels système Linux et les mappe avec ceux de macOS. Pour les utilisations de bureau, une implémentation spéciale de mesa est nécessaire pour mapper les appels graphiques Linux vers OpenGL.frameworket Metal.framework.

Maxthon Chan
la source
0

Il existe un certain nombre d'applications Linux spécialisées pour lesquelles cela serait d'une grande aide. Du côté FPGA, Quartus et Vivado sont de bons exemples de programmes qui s'exécutent sous Linux et il est peu probable que du code source soit disponible pour eux ou des programmes similaires qui ciblent les derniers FPGA.

Je pense que la réponse simple à votre question est: recompilez sur MacOS où vous avez la source et formez un groupe pour fournir la capacité si vous avez le temps - et ce sera une tâche longue.

Daniel Wisehart
la source