程序解释器在可执行文件中的作用是什么



我正在对elf可执行文件进行反汇编,并了解elf格式。在那里,我看到lib64/ld-linux-x86-64.so.2在生成的可执行文件中用作程序解释器。

我的猜测是:我在源代码中使用了printf,它必须动态链接。当我查看动态部分时,我能够找到对libc.so.6共享库(标记:DT_NEEDED(的引用。在我的系统中,我在不同的目录中发现了多个同名文件:

sourav@ubuntu-VirtualBox:/$ sudo find / -name libc.so.6
/usr/lib/x86_64-linux-gnu/libc.so.6
find: ‘/run/user/1000/doc’: Permission denied
find: ‘/run/user/1000/gvfs’: Permission denied
/snap/snapd/13170/lib/x86_64-linux-gnu/libc.so.6
/snap/snapd/11107/lib/x86_64-linux-gnu/libc.so.6
/snap/core18/1988/lib/i386-linux-gnu/libc.so.6
/snap/core18/1988/lib/x86_64-linux-gnu/libc.so.6
/snap/core18/2128/lib/i386-linux-gnu/libc.so.6
/snap/core18/2128/lib/x86_64-linux-gnu/libc.so.6

所以,我想程序解释器的目的是将这些名称解析到适当的库中,并在执行过程中加载它们。这是正确的吗?

看起来,我们也可以有不带程序解释器的可执行文件(程序解释器本身就是这样(。在这种情况下,system/os本身是否加载共享库?如果是,它如何解析库的路径?

是否可以使用gcc在没有程序解释器的情况下生成可执行文件?我的gcc版本是"gcc版本9.3.0(Ubuntu 9.3.0-17ubuntu1~20.04("。

所以,我想程序解释器的目的是将这些名称解析到适当的库中,并在执行过程中加载它们。这是正确的吗?

是的,但这有点极简主义。加载动态库包括定位它们,在必要时将它们加载或映射到内存中,以及在内部解析动态符号(可能是惰性的(以进行多种重新定位。它涉及递归地加载库自己需要的库。此外,在动态链接的可执行文件中,程序解释器提供程序入口点(从内核的角度来看(,因此它还负责设置和输入程序特定的入口点(例如,C或C++程序中的main()(。

似乎,我们也可以有没有程序解释器的可执行文件(程序解释器本身就是这样(。在这种情况下,system/os本身是否加载共享库?如果是,它如何解析库的路径?

您可以在没有程序解释器的情况下拥有ELF可执行文件,但它们不是动态链接的,至少在ELF意义上不是这样。没有要加载的共享库,当然系统也不会加载任何库。

是否可以使用gcc在没有程序解释器的情况下生成可执行文件?我的gcc版本是"gcc版本9.3.0(Ubuntu 9.3.0-17ubuntu1~20.04("。

如果您有所有所需库的静态版本可用,那么您应该能够通过在链接程序时在命令行上包含-static选项来实现这一点。然而,您完全有可能没有所需的静态库,即使libc是您唯一需要的库。

最新更新