本机可执行文件的哪一部分(具体而言)使其不可移植?

发布于 2024-07-22 07:41:23 字数 293 浏览 3 评论 0原文

乍一听这似乎是个愚蠢的问题,但请耐心听我说。

众所周知,一种 CPU 架构的二进制文件不能在其他架构上运行。 例如,在 sparc64 芯片上运行 x86 二进制文件是不可能的(没有某种兼容层)。 指令集不同,很明显这是行不通的。

但是,当二进制文件针对相同的 CPU 但针对不同的操作系统时,代码的哪一部分会阻止执行。 例如,在 x86 Linux 机器上运行 x86 Solaris 二进制文件。 我假设存在某种与运行时链接器或进程调度程序相关的特定于平台的存根?

我有兴趣知道。 谢谢。

This sounds like a daft question at first, but bear with me.

It is common knowledge that binaries for one CPU architecture do not run on others. So for example it is impossible to run (without a compatibility layer of some kind), an x86 binary on a sparc64 chip. The instruction sets are different, so clearly that will not work.

But when the binary is for the same CPU, but for a different operating system, which part of the code prevents execution from being possible. For example, running an x86 Solaris binary on an x86 Linux box. I am assuming that there is some kind of platform specific stub which relates to the run-time linker or process scheduler?

I would be interested to know. Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

蝶…霜飞 2024-07-29 07:41:23

原因有很多。 主要的,按“与金属的距离”排序是:

  1. 操作系统可能有不同的可执行文件二进制格式。 在这种情况下,您将无法首先加载二进制文件。
  2. 程序可以使用另一种方法来指示它们希望进行系统调用(例如,INT21 与 INT80)。
  3. 该程序可能依赖于其他操作系统中不存在的系统调用(例如 dlopen())。
  4. 该程序可能依赖于其他操作系统中不存在的标准库。
  5. 该程序可能依赖于其他操作系统上不可用的其他库。

当然,在意外环境中运行的程序可能会以多种方式严重失败。

There are a number of reasons. The main ones, ordered in "distance from the metal" are:

  1. The operating systems may have different binary formats for executable files. In this case you will not be able to load the binary in the first place.
  2. The program may use another method to indicate they wish to place a system call (e.g. INT21 vs INT80).
  3. The program may rely on system calls that are not present in the other OS (e.g. dlopen())
  4. The program may rely on the standard library not present on the other OS.
  5. The program may rely on other libraries that are not available on the other OS.

Of course there are many more ways a program running in an unexpected environment can fail spectacularly.

兮颜 2024-07-29 07:41:23

有四个问题:

  1. 不同的操作系统以不同的方式打包其二进制可执行文件(例如 Linux ELF 与 Windows 格式);
  2. 不同CPU架构上的指令集不同;
  3. 不同的操作系统有不同的系统调用(例如Win32中的CreateProcess()与Linux/Unix中的fork());
  4. 路径、合法字符、目录分隔符等差异。

假设两者都存在非系统库,否则这是另一个区别。

There are four problems:

  1. Different operating systems package their binary executables differently (eg Linux ELF vs Windows format);
  2. Different instruction sets on different CPU architectures;
  3. Different operating systems have different system calls (eg CreateProcess() in Win32 vs fork() in Linux/Unix);
  4. Differences such as paths, legal characters, directory separators and so on.

Non-system libraries are assumed to be present on both, otherwise that's another difference.

强辩 2024-07-29 07:41:23

主要是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 可执行文件),因为根本就没有需求。

It's mainly the APIs. For example Win32 APIs are not really available on Linux. It is possible to get around this though, see Wine. The executable format may also be different (ELF/PE), but that could be fixed fairly easily (Wine does this; it allows PE executables to be executed on Linux).

Also, your example of Solaris and Linux executables mixing would be fairly easy to implement, since the OSs are so similar (ELF for executable format, POSIX APIs, X window system, etc.). FreeBSD can already run Linux executables. The reason this is not so common is simply that there is not much of a demand for it. There are a whole lot more Windows programs than *NIX programs, so Wine was created. There are a whole lot more Linux programs than FreeBSD programs, so FreeBSD implemented the Linux compatibility layer. Solaris might eventually implement something similar too. However, don't expect the reverse (Solaris/BSD executables on Linux), since there is just no demand for it.

魂ガ小子 2024-07-29 07:41:23

除了二进制格式和其他“打包”功能(这可能也不是那么简单)之外,您几乎在每个代码片段中都会发现一些后果。 像 PIC 这样的东西

  1. 可能会导致每个全局访问都依赖于重新加载 GOT 指针的系统特定假设以及附加偏移量的假设。
  2. 许多系统都有特定的 ABI,在寄存器中传递小结构,为了对齐目的而跳过寄存器,为特殊目的保留寄存器。有些系统有几个(如 ARM EABI 和 OABI)
  3. 线程本地存储相关问题,每个线程实例化的变量与操作系统指定的设施。 寄存器选择、偏移量等。
  4. 一些操作系统(尤其是)窗口支持某种格式的异常处理,以允许跨语言甚至跨机器(通过 DCOM)异常处理。
  5. 更高级别的跨程序系统(例如 COM,但也包括 Mac 上的 Objective C 互操作性,或与特定 KDE-gcc 版本组合的兼容性)也可能对 VMT 布局有某些要求。
  6. 有些链接器和格式支持节的负偏移量,有些则不支持。

请注意,这只是一个值得研究的有趣内容的大脑转储。 它可能并不完整,并且并非全部适用。 上述一些要点可能会重叠(例如,为 TLS 或 PIC 保留寄存器也是 ABI 更改)

Besides binary format and other "packaging" features (which might not be exactly trivial either) There are also consequences that you find in nearly every code fragments. Stuff like

  1. PIC might cause every global access to rely on system specific assumptions on reloading the GOT pointer, and assumptions on additional offsets.
  2. Many systems have a specific ABI, passing small structs in registers, skipping registers for alignment purposes, reserving registers for special purposes Some have several (like ARM EABI and OABI)
  3. thread local storage related issues, variables that are instantiated per thread are tightly coupled to the facilities the OS specifies. Register choice, offsets etc.
  4. Some OSes (most notably) windows have support for a certain format of exception handling to allow cross-language and even cross-machine(via DCOM) exception handling.
  5. Higher level cross-program systems (like COM, but also e.g. Objective C interoperability on Mac, or compability with a certain KDE-gcc versioncombination) might also have certain requirements on VMT layout.
  6. Some linkers and formats support offsets negative to a section, some not.

Note that this is just a braindump of stuff that could be interesting to look into. It is probably not complete, and not all might apply. Some of the points above might overlap (e.g. reserving a register for TLS or PIC is also an ABI change)

无力看清 2024-07-29 07:41:23

它是系统特定的库,并不总是可移植的。 例如,您不能在 vanilla linux 上使用 win32 窗口 api(是的,我意识到有一些解决办法,例如 wine,它不是最好的例子)。

It is system specific libraries that are not always portable. For example, you cannot use the win32 window api on vanilla linux (and yes i realize there are work arrounds for this such as wine, its not the best example).

一袭水袖舞倾城 2024-07-29 07:41:23

除了其他人所说的之外,可执行文件的实际格式可能有所不同。 因此,当操作系统加载它时,它无法在文件中的正确位置找到代码、数据段等所需的值。

In addition to what others have said, the actual format of the executable may be different. So when the OS comes to load it, it doesn't find the values it is expecting for code, data segments etc. in the right places in the file.

青衫负雪 2024-07-29 07:41:23

系统库和 API。 实际的简单代码应该可以工作。 这就是为什么像 Wine 这样的层不进行任何 CPU 模拟,它们只是重新实现 Windows API。

System libraries and APIs. Actual simple code should work. This is why layers like Wine don't do any CPU emulation, they just re-implement the Windows API.

凉栀 2024-07-29 07:41:23

正如已经指出的那样,不兼容性与可执行文件格式本身的关系较小,而与可执行文件引用的库关系不大。

我相信 Linux 实际上与许多不同的可执行格式兼容,尽管我在这里可能是错的

As has been already pointed out the incompatibility has less to do with the executable formats themselves then the libraries referenced by an executable.

I believe linux is actually compatible with a number of different executable formats although I could be wrong here

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文