为什么解释器的路径硬编码在 ELF 可执行文件中?

为什么解释器的路径硬编码在 ELF 可执行文件中?

(这是一个一般性问题,而不是抱怨——对此可能有一个很好的解释。)

对于已编译的可执行文件,为什么将解释器的路径硬编码到二进制文件中而不是让操作系统决定?即解释器不应该从可执行文件的格式(例如ELF)和体系结构(x86-64)中派生出来。

运行时可以看到解释器路径file /path/to/some-executable

some-executable: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=acd1829414c2843215bd10ed75a0fe486fce288e, not stripped

为了确保解释器路径字符串确实存在于二进制文件中,然后strings -t x /path/to/some-executable | head显示它位于字节 0x270: 270 /lib64/ld-linux-x86-64.so.2,检查文件readelf -l /path/to/some-executable显示解释器的相同偏移量。

答案1

可用的属性ELF 标头(除了指向动态链接器本身的指针)不是足以确定适当的动态链接器。动态链接器还与构建编译器所针对的 C 库相关联,因此,例如,使用 GNU C 库构建的 Linux 上的 64 位 x86 二进制文件可能会如果由 musl 动态链接器加载则失败:

二进制兼容性受到更多限制,但随着 musl 的新版本,它会稳步提高。目前,一些 glibc 链接的共享库可以使用 musl 加载,但如果将 musl 替换为/lib/ld-linux.so.2.

动态链接器的选择还控制着共享库的发现方式,因此甚至不可能仅通过名称指定动态链接器而不使用路径,并依赖链接器样式的算法来查找适当的链接器。可以使用另一种方法,但它必须在内核中实现,因此在每个二进制文件中对其进行硬编码要容易得多。

答案2

根据您希望它存在的标准路径指定解释器,或者使用 /usr/bin/env 代替它,在 'nix 系统中会有登录历史记录。只需看一下大多数脚本开头的 hash-bang 行即可。由于没有真正的操作系统文件类型概念,因此仅将预期路径或解释器或链接器放入文件中是从未被取代的旧标准解决方案。

相关内容