Saya sedang belajar C #, jadi saya membuat program C # kecil yang mengatakan Hello, World!
, lalu mengompilasinya mono-csc
dan menjalankannya dengan mono
:
$ mono-csc Hello.cs
$ mono Hello.exe
Hello, World!
Saya menyadari bahwa ketika saya memukul TAB
di bash
, Hello.exe
ditandai dieksekusi. Memang, ini dijalankan hanya dengan sebuah shell memuat nama file!
Hello.exe
adalah tidak file ELF dengan ekstensi file yang lucu:
$ 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
berarti itu adalah Microsoft Windows yang dapat dieksekusi yang terhubung secara statis. Jatuhkan ke kotak Windows, dan itu akan (harus) berjalan.
Saya telah wine
terinstal, tapi wine
, menjadi lapisan kompatibilitas untuk aplikasi Windows, membutuhkan waktu sekitar 5x lebih lama untuk menjalankan Hello.exe
sebagai mono
dan dijalankan langsung lakukan, sehingga tidak wine
yang berjalan itu.
Saya berasumsi ada beberapa mono
modul kernel yang diinstal dengan mono
yang mencegat exec
syscall / s, atau menangkap binari yang dimulai dengan 4D 5A
, tetapi lsmod | grep mono
dan teman-teman mengembalikan kesalahan.
Apa yang terjadi di sini, dan bagaimana kernel tahu bahwa ini executable khusus?
Hanya untuk membuktikan itu bukan sihir shell saya , saya menggunakan Crap Shell (alias sh
) untuk menjalankannya dan masih berjalan secara asli.
Inilah programnya secara penuh, karena seorang komentator ingin tahu:
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");
}
}
sumber
php hello.php
ataupython hello.py
atauperl hello.pl
jika bahasa dikompilasi seperti javajava hello
mereka juga akan berjalan karena mereka tidak dapat dieksekusi di sana tetapi sebuah program membaca dan mengeksekusi file. Namun jika Anda menjalankan./hello.exe
alih-alihmono hello.exe
, saya menemukan pertanyaan Anda dan menerima jawaban yang lebih masuk akal (yang dalam kasus pasti menggunakan dukunganprogram codefile
, dalam program kasus Anda adalah mono, sedangkan contoh saya termasuk php, python, perl dan java. Saya curiga jika mono mengizinkan ekstensi selain file .exe masih dieksekusi melalui kode. Seharusnya tidak bergantung sama sekali pada windows karena akhirnya ini menjalankan kode yang dikompilasi. Namun jika file sumber Anda memiliki beberapa kode dependen seperti windows only API maka jelas Anda harus memerlukan anggur untuk menjalankan file exe itu./etc/magic
atau/usr/share/file/magic
(atau lokasi magis serupa) adalah file yang berisi informasi yang diperlukan untuk dapat melakukan ini.$ foo.jar
daripada$ java -jar foo.jar
- mirip dengan apa yang dilakukan untuk mono.Jawaban:
Ini adalah binfmt_misc yang sedang beraksi: memungkinkan kernel untuk diberi tahu bagaimana menjalankan binari yang tidak diketahuinya. Lihatlah isi
/proc/sys/fs/binfmt_misc
; di antara file yang Anda lihat di sana, orang harus menjelaskan cara menjalankan binari Mono:(pada sistem Debian). Ini memberi tahu kernel tempat binari dimulai dengan
MZ
(4d5a
) harus diberikanrun-detectors
. Yang terakhir mengetahui apakah menggunakan Mono atau Wine untuk menjalankan biner.Jenis biner dapat ditambahkan, dihapus, diaktifkan dan dinonaktifkan kapan saja; lihat dokumentasi di atas untuk perincian (semantiknya mengejutkan, sistem file virtual yang digunakan di sini tidak berperilaku sepenuhnya seperti sistem file standar).
/proc/sys/fs/binfmt_misc/status
memberikan status global, dan masing-masing "deskriptor" biner menunjukkan status masing-masing. Cara lain untuk menonaktifkanbinfmt_misc
adalah membongkar modul kernelnya, jika itu dibangun sebagai modul; ini juga berarti memungkinkan untuk masuk daftar hitam untuk menghindarinya sepenuhnya.Fitur ini memungkinkan tipe biner baru untuk didukung, seperti executable MZ (yang termasuk Windows PE dan PE + binari, tetapi juga DOS dan OS / 2 binari!), File Java JAR ... Ini juga memungkinkan tipe biner yang dikenal untuk didukung pada arsitektur baru, biasanya menggunakan Qemu; dengan demikian, dengan perpustakaan yang sesuai, Anda dapat menjalankan binari ARM Linux secara transparan pada prosesor Intel!
Pertanyaan Anda berasal dari kompilasi silang, meskipun dalam arti .NET, dan itu menimbulkan peringatan dengan
binfmt_misc
: beberapa skrip konfigurasi keliru ketika Anda mencoba melakukan cross-compile pada sistem yang dapat menjalankan binari cross-compiled. Biasanya, mendeteksi kompilasi silang melibatkan membangun biner dan mencoba menjalankannya; jika berjalan, Anda tidak kompilasi silang, jika tidak, Anda (atau kompiler Anda rusak).autoconf
skrip biasanya dapat diperbaiki dalam hal ini dengan secara eksplisit menentukan arsitektur build dan host, tetapi kadang-kadang Anda harus menonaktifkanbinfmt_misc
sementara ...sumber