Linux 系统上的动态链接器是内核或 GCC 库的一部分吗?

Is Dynamic Linker part of Kernel or GCC Library on Linux Systems?

动态 Linker(又名程序解释器,Link 加载器)是内核或 GCC 库的一部分吗?

更新 (28-08-16) :

我发现 dynamic linker 的默认路径,每个二进制文件(即 linked 针对共享库)使用 /lib64/ld-linux-x86-64.so.2 是共享库 /lib/x86_64-linux-gnu/ld-2.23.so 的 link,它是实际的动态 linker.

并且它是 libc6 (2.23-0ubuntu3) 包的一部分,即。 GNU C Library: Shared libraries 在 ubuntu 中用于 AMD64 架构。

我的实际问题是

如果这个辅助程序 (ld-2.23.so) 不存在?

对此的回答是“没有应用程序 运行,甚至 shell 程序也不行”。我已经在虚拟机上试过了。

在 ELF 可执行文件中,这称为 "ELF interpreter"。在 linux 上(例如)这是 /lib64/ld-linux-x86-64.so.2

这是不是内核的一部分,并且[通常]与glibc等一起使用。其他

当内核执行ELF可执行文件时,它必须将可执行文件映射到用户space内存中。然后它会在内部查找称为 INTERP 的特殊子部分 [其中包含一个作为完整路径的字符串]。

然后内核将解释器映射到用户space内存并将控制转移给它。然后,解释器执行必要的 linking/loading 并启动程序。

因为 ELF 代表 "extensible linker format",这允许 ELF 文件有许多不同的子部分。

与文件配对的 ELF 解释器知道所有无数的扩展,而不是给内核增加负担。

虽然在一个给定的系统上通常只使用一种格式,但在一个系统上可以有几种不同的 ELF 文件变体,每一种都有自己的 ELF 解释器。

这将允许[说] BSD ELF 文件在linux 系统[与其他adjustments/support] 上运行,因为ELF 文件将指向BSD ELF 解释器而不是 linux 一个。


更新:

every process(vlc player, chrome) had the shared library ld.so as part of their address space.

是的。我假设您正在查看 /proc/<pid>/maps。这些是文件的映射(例如使用mmap)。这与 "loading" 有点不同,它可以暗示 [symbol] linking.

So primarily loader after loading the executable(code & data) onto memory , It loads& maps dynamic linker (.so) to its address space

理解这一点的最好方法是重新表述你刚才所说的话:

所以主要是内核映射可执行文件(代码和数据)到内存之后,内核将动态linker (.so)映射到程序地址space

基本上是正确的。内核还映射了其他东西,例如 bss 段和堆栈。然后 "pushes" argcargvenvp [环境变量的 space] 入栈。

然后,[通过读取文件的一个特殊部分]确定了 ld.so 的起始地址,它将其设置为恢复地址并启动线程。

到目前为止,都是内核在做事。内核几乎不做符号 linking.

现在,ld.so 接管...

which further Loads shared Libraries , map & resolve references to libraries. It then calls entry function (_start)

因为原始可执行文件(例如 vlc)已映射到内存中,ld.so 可以检查它以获取所需的共享库列表。它 将这些 映射到内存中,但 而不是 必须立即 link 符号。

映射简单快捷 -- 只需一个 mmap 调用。

可执行文件的起始地址[不要ld.so]的起始地址混淆,取自ELF可执行文件的一个特殊部分。尽管与此起始地址关联的符号传统上称为 _start,但它实际上可以命名为任何名称(例如 __my_start),因为它是确定起始地址的节数据中的内容,并且 不是符号的地址_start

将符号引用链接到符号定义是一个耗时的过程。因此,这被推迟到实际使用该符号为止。也就是说,如果一个程序引用了 printf,那么 linker 实际上不会尝试 printf 中的 link,直到程序第一次实际 通话printf

这有时称为 "link-on-demand" 或 "on-demand-linking"。请在此处查看我的回答: 以获得更详细的解释以及将可执行文件映射到用户 space.

时实际发生的情况

如果您有兴趣,可以 ldd /usr/bin/vlc 获取它使用的共享库的列表。如果您查看 readelf -a /usr/bin/vlc 的输出,您会看到这些相同的共享库。此外,您将获得 ELF 解释器的完整路径,并且可以执行 readelf -a <full_path_to_interpreter> 并注意一些差异。您可以对 vlc 想要的任何 .so 个文件重复该过程。

将所有这些与 /proc/<pid>maps 等结合起来。阿尔。可能有助于您的理解。