Linux是如何加载这个用C#编译的exe的呢?

Linux是如何加载这个用C#编译的exe的呢?

我刚刚发现了一些非常令人惊讶的事情。

csc我可以使用(来自 Visual Studio)在 Windows 计算机上编译一个简单的 C# hello world ,将生成的exe文件复制到我的 Linux 计算机,然后使用mono helloworld.exe.到目前为止,一切对我来说都是有意义的:根据这个帖子在 Windows 上,helloworld.exe基本上只是一个最终启动 C# 运行时的技巧,并且 CIL 字节码只是从文件中稍后的某些数据部分中读取exe。同样,我想,在 Linux 上,mono helloworld.exe只需启动 C# 运行时并直接读取字节码,而无需担心 exe 欺骗。

对于后代,这是我从以下来源获得的来源Charles Petzold 的优秀免费 C# 书籍:

//---------------------------------------------
// FirstProgram.cs (c) 2006 by Charles Petzold
//---------------------------------------------
class FirstProgram
{
    public static void Main()
    {
        System.Console.WriteLine("Hello, Microsoft .NET Framework!");
    }
}

但这就是事情变得有趣的地方:在 Linux 上(uname -r在我的机器上4.14.188-1-MANJARO)我可以简单地执行./helloworld.exe并且它可以工作!

我开始做一些调查,以下是运行的前几行strace ./helloworld.exe

execve("./hw.exe", ["./hw.exe"], 0x7fffae8e6070 /* 61 vars */) = 0
[ Process PID=3381 runs in 32 bit mode. ]
brk(NULL)                               = 0x7eedb000
arch_prctl(0x3001 /* ARCH_??? */, 0xffb19948) = -1 EINVAL (Invalid argument)
readlink("/proc/self/exe", "/usr/bin/wine", 4096) = 13
mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xf7faa000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/bin/../lib32/tls/i686/sse2/libwine.so.1", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat64("/usr/bin/../lib32/tls/i686/sse2", 0xffb18e00) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/bin/../lib32/tls/i686/libwine.so.1", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat64("/usr/bin/../lib32/tls/i686", 0xffb18e00) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/bin/../lib32/tls/sse2/libwine.so.1", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat64("/usr/bin/../lib32/tls/sse2", 0xffb18e00) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/bin/../lib32/tls/libwine.so.1", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat64("/usr/bin/../lib32/tls", 0xffb18e00) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/bin/../lib32/i686/sse2/libwine.so.1", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat64("/usr/bin/../lib32/i686/sse2", 0xffb18e00) = -1 ENOENT (No such file or directory)

我预计会出现一些错误,指出“此文件不是有效的可执行文件”,因为我只希望 Linux 程序加载器能够理解 ELF 文件而不是 Windows 的 PE 格式。相反,似乎系统足够聪明,可以开始寻找 wine (在输出中strace,您可以看到它开始寻找 wine 库,并且因为我已经在我的 Linux 机器上安装了 wine,所以它最终确实找到了它们)在)。

发生什么了?execve如果检测到 PE 文件,调用是否足够智能,可以尝试使用 wine,或者这是正在bash执行的操作?或者是完全不同的其他东西?

答案1

您肯定已经通过包管理器安装了 Wine 或/和 Mono,并附带了一个特殊的配置文件,该文件告诉内核在用户启动 exe 文件后要做什么。

更多信息请点击这里:https://en.wikipedia.org/wiki/Binfmt_misc

相关内容