起初这听起来像是一个愚蠢的问题,但请耐心等待。
众所周知,一种 CPU 架构的二进制文件不会在其他架构上运行。例如,不可能在 sparc64 芯片上运行 x86 二进制文件(没有某种兼容层)。指令集是不同的,所以很明显这是行不通的。
但是,当二进制文件用于同一个 CPU,但用于不同的操作系统时,代码的哪一部分会阻止执行。例如,在 x86 Linux 机器上运行 x86 Solaris 二进制文件。我假设存在某种与运行时链接器或进程调度器相关的平台特定存根?
我很想知道。谢谢。
起初这听起来像是一个愚蠢的问题,但请耐心等待。
众所周知,一种 CPU 架构的二进制文件不会在其他架构上运行。例如,不可能在 sparc64 芯片上运行 x86 二进制文件(没有某种兼容层)。指令集是不同的,所以很明显这是行不通的。
但是,当二进制文件用于同一个 CPU,但用于不同的操作系统时,代码的哪一部分会阻止执行。例如,在 x86 Linux 机器上运行 x86 Solaris 二进制文件。我假设存在某种与运行时链接器或进程调度器相关的平台特定存根?
我很想知道。谢谢。
有很多原因。主要的,按“与金属的距离”排序的是:
当然,在意想不到的环境中运行的程序可能会以多种方式严重失败。
有四个问题:
假定两者都存在非系统库,否则这是另一个区别。
主要是API。例如,Win32 API 在 Linux 上并不真正可用。不过,有可能解决这个问题,请参阅Wine。可执行格式也可能不同(ELF/PE),但可以很容易地修复(Wine 可以做到这一点;它允许 PE 可执行文件在 Linux 上执行)。
此外,您的 Solaris 和 Linux 可执行文件混合示例将相当容易实现,因为操作系统非常相似(ELF 表示可执行格式、POSIX API、X 窗口系统等)。FreeBSD 已经可以运行 Linux 可执行文件。这种情况不常见的原因很简单,就是对它的需求不多。Windows 程序比 *NIX 程序多得多,因此创建了 Wine。Linux 程序比 FreeBSD 程序多得多,因此 FreeBSD 实现了 Linux 兼容层。Solaris 最终也可能实现类似的东西。但是,不要指望相反(Linux 上的 Solaris/BSD 可执行文件),因为没有需求。
除了二进制格式和其他“打包”功能(这也可能不完全是微不足道的)之外,您还可以在几乎每个代码片段中找到一些后果。像这样的东西
请注意,这只是一些有趣的东西。它可能不完整,并且并非所有内容都适用。上面的某些点可能会重叠(例如,为 TLS 或 PIC 保留寄存器也是 ABI 更改)
它是系统特定的库,并不总是可移植的。例如,您不能在 vanilla linux 上使用 win32 窗口 api(是的,我意识到有一些工作场所,例如 wine,它不是最好的例子)。
系统库和 API。实际的简单代码应该可以工作。这就是为什么像 Wine 这样的层不做任何 CPU 仿真,它们只是重新实现 Windows API。
除了其他人所说的,可执行文件的实际格式可能有所不同。因此,当操作系统开始加载它时,它不会在文件的正确位置找到它期望的代码、数据段等值。
正如已经指出的那样,不兼容与可执行文件格式本身的关系不大,与可执行文件引用的库有关。
我相信 linux 实际上与许多不同的可执行格式兼容,尽管我在这里可能是错的