GNU/Linux >> Tutoriales Linux >  >> Linux

Linux:¿cómo es mono mágico?

Estoy aprendiendo C#, así que hice un pequeño programa en C# que dice Hello, World! , luego lo compiló con mono-csc y lo ejecuté con mono :

$ mono-csc Hello.cs
$ mono Hello.exe
Hello, World!

Noté que cuando presioné TAB en bash , Hello.exe fue marcado como ejecutable. De hecho, ¡se ejecuta con solo un shell cargando el nombre del archivo!

Hello.exe es no un archivo ELF con una extensión de archivo divertida:

$ 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 significa que es un ejecutable vinculado estáticamente de Microsoft Windows. Colóquelo en un cuadro de Windows y (debería) ejecutarse.

Tengo wine instalado, pero wine , al ser una capa de compatibilidad para las aplicaciones de Windows, tarda aproximadamente 5 veces más en ejecutar Hello.exe como mono y ejecutarlo directamente do, por lo que no es wine que lo ejecuta.

Supongo que hay algo de mono módulo kernel instalado con mono que intercepta el exec syscall/s, o captura binarios que comienzan con 4D 5A , pero lsmod | grep mono y amigos devuelven un error.

¿Qué está pasando aquí y cómo sabe el kernel que esto ejecutable es especial?

Solo como prueba de que no es mi shell trabajando magia, usé Crap Shell (también conocido como sh ) para ejecutarlo y aún se ejecuta de forma nativa.

Aquí está el programa completo, ya que un comentarista tenía curiosidad:

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");
  }
}

Respuesta aceptada:

Esto es binfmt_misc en acción:le permite al núcleo saber cómo ejecutar binarios que no conoce. Mire el contenido de /proc/sys/fs/binfmt_misc; entre los archivos que ve allí, uno debería explicar cómo ejecutar los binarios Mono:

enabled
interpreter /usr/lib/binfmt-support/run-detectors
flags:
offset 0
magic 4d5a

(en un sistema Debian). Esto le dice al kernel que los binarios que comienzan con MZ (4d5a ) debe darse a run-detectors . Este último decide si usar Mono o Wine para ejecutar el binario.

Los tipos binarios se pueden agregar, eliminar, habilitar y deshabilitar en cualquier momento; consulte la documentación anterior para obtener más detalles (la semántica es sorprendente, el sistema de archivos virtual que se usa aquí no se comporta del todo como un sistema de archivos estándar). /proc/sys/fs/binfmt_misc/status da el estado global, y cada "descriptor" binario muestra su estado individual. Otra forma de deshabilitar binfmt_misc es descargar su módulo kernel, si está construido como un módulo; esto también significa que es posible incluirlo en la lista negra para evitarlo por completo.

Esta función permite admitir nuevos tipos binarios, como ejecutables MZ (que incluyen binarios de Windows PE y PE+, ¡pero también binarios de DOS y OS/2!), archivos JAR de Java... También permite admitir tipos binarios conocidos en nuevas arquitecturas. , típicamente usando Qemu; por lo tanto, con las bibliotecas apropiadas, puede ejecutar de forma transparente binarios ARM Linux en un procesador Intel.

Relacionado:Cosas de Linux que olvidé Hoja de referencia

Su pregunta surgió de la compilación cruzada, aunque en el sentido de .NET, y eso plantea una advertencia con binfmt_misc :algunos scripts de configuración se comportan mal cuando intenta realizar una compilación cruzada en un sistema que puede ejecutar los archivos binarios compilados de forma cruzada. Por lo general, detectar la compilación cruzada implica construir un binario e intentar ejecutarlo; si se ejecuta, no está compilando de forma cruzada, si no lo hace, lo está (o su compilador está roto). autoconf los scripts generalmente se pueden corregir en este caso especificando explícitamente las arquitecturas de compilación y host, pero a veces tendrá que deshabilitar binfmt_misc temporalmente…


Linux
  1. Cómo usar BusyBox en Linux

  2. Cómo instalar Python en Linux

  3. Cómo uso cron en Linux

  4. Cómo instalar Java en Linux

  5. Cómo particionar un disco en Linux

Cómo instalar Mono en Ubuntu 20.04

Cómo instalar Mono en CentOS 8

Cómo instalar Mono en Debian 10

Cómo instalar FFmpeg en Linux

Cómo instalar Mono o dotNET45 en Linux - Tutorial

Cómo instalar Mono en Linux Mint 20