J'apprends le C #, alors j'ai créé un petit programme C # qui dit Hello, World!
, puis je l'ai compilé mono-csc
et exécuté avec mono
:
$ mono-csc Hello.cs
$ mono Hello.exe
Hello, World!
J'ai remarqué que quand je frappe TAB
dans bash
, Hello.exe
a été marqué exécutable. En effet, il ne fonctionne que par un shell chargeant le nom du fichier!
Hello.exe
n'est pas un fichier ELF avec une extension de fichier amusante:
$ readelf -a Hello.exe
readelf: Error: Not an ELF file - it has the wrong magic bytes at the start
$ xxd Hello.exe | head -n1
00000000: 4d5a 9000 0300 0000 0400 0000 ffff 0000 MZ..............
MZ
signifie que c'est un exécutable lié statiquement à Microsoft Windows. Déposez-le sur une fenêtre Windows, et il sera (devrait) s'exécuter.
J'ai wine
installé, mais wine
, étant une couche de compatibilité pour les applications Windows, il faut environ 5 fois plus de temps pour s'exécuter en Hello.exe
tant qu'exécutant mono
directement. Par conséquent, ce n'est pas lui wine
qui l'exécute.
Je suppose qu'un mono
module de noyau installé mono
intercepte le exec
/ les appels système, ou capture les fichiers binaires commençant par 4D 5A
, mais lsmod | grep mono
que les amis retournent une erreur.
Que se passe-t-il ici et comment le noyau sait-il que cet exécutable est spécial?
Juste pour prouver que ce n’est pas ma magie qui fonctionne, j’ai utilisé le Crap Shell (alias sh
) pour l’exécuter et il fonctionne toujours en mode natif.
Voici le programme complet, puisqu'un commentateur était curieux:
using System;
class Hello {
/// <summary>
/// The main entry point for the application
/// </summary>
[STAThread]
public static void Main(string[] args) {
System.Console.Write("Hello, World!\n");
}
}
php hello.php
oupython hello.py
ouperl hello.pl
ou dans le cas d’un langage compilé tel que java,java hello
elles s’exécuteraient également car elles ne sont exécutables, mais un programme lit et exécute un fichier. Cependant, si vous courez à la./hello.exe
place demono hello.exe
la, j'ai trouvé votre question et votre réponse plus raisonnables (ce qui, dans le cas contraire, utilise définitivement binfmt-support.program codefile
. Dans votre cas, le programme est mono, alors que mes exemples incluent php, python, perl et java. Je soupçonne que si mono autoriser l'extension à un fichier autre que .exe toujours exécuté via le code. Cela ne devrait pas dépendre du tout de Windows, car il s'agit finalement d'exécuter un code compilé. Cependant, si votre fichier source a un code dépendant, tel que des API Windows uniquement, il est évident que vous devez avoir besoin de wine pour exécuter ce fichier exe./etc/magic
ou/usr/share/file/magic
(ou un endroit magique similaire) est le fichier qui contient les informations nécessaires pour pouvoir le faire.$ foo.jar
plutôt que$ java -jar foo.jar
- similaire à ce qui est fait pour le mono.Réponses:
C'est binfmt_misc en action: cela permet au noyau de savoir comment exécuter des fichiers binaires qu'il ne connaît pas. Regardez le contenu de
/proc/sys/fs/binfmt_misc
; parmi les fichiers que vous voyez ici, il faut expliquer comment exécuter les fichiers binaires Mono:(sur un système Debian). Cela indique au noyau que les fichiers binaires commençant par
MZ
(4d5a
) doivent être donnés àrun-detectors
. Ce dernier détermine s'il faut utiliser Mono ou Wine pour exécuter le binaire.Les types binaires peuvent être ajoutés, supprimés, activés et désactivés à tout moment. voir la documentation ci-dessus pour plus de détails (la sémantique est surprenante, le système de fichiers virtuel utilisé ici ne se comporte pas entièrement comme un système de fichiers standard).
/proc/sys/fs/binfmt_misc/status
donne le statut global et chaque "descripteur" binaire montre son statut individuel. Une autre façon de désactiverbinfmt_misc
consiste à décharger son module de noyau, s'il est construit en tant que module; cela signifie également qu'il est possible de le mettre sur une liste noire pour l'éviter complètement.Cette fonctionnalité permet de prendre en charge de nouveaux types binaires, tels que les exécutables MZ (qui incluent les binaires Windows PE et PE +, mais aussi les binaires DOS et OS / 2!), Les fichiers JAR Java ... Elle permet également la prise en charge des types binaires connus nouvelles architectures, utilisant généralement Qemu; ainsi, avec les bibliothèques appropriées, vous pouvez exécuter de manière transparente des fichiers binaires ARM Linux sur un processeur Intel!
Votre question découle de la compilation croisée, bien qu'au sens .NET, ce qui soulève un avertissement
binfmt_misc
: certains scripts de configuration se comportent mal lorsque vous essayez de compiler sur un système capable d'exécuter les fichiers binaires compilés. En règle générale, la détection de la compilation croisée implique la création d'un fichier binaire et sa tentative d'exécution. si ça marche, vous n'êtes pas cross-compilation, sinon, vous êtes (ou votre compilateur est en panne).autoconf
les scripts peuvent généralement être corrigés dans ce cas en spécifiant explicitement les architectures de construction et d'hôte, mais vous devrez parfois désactiverbinfmt_misc
temporairement ...la source