【问题标题】:Why does libc depend on ld.so?为什么 libc 依赖 ld.so?
【发布时间】:2021-01-05 15:17:20
【问题描述】:

我一直认为libc应该是一个独立的动态库,直到我发现这个:

$ ldd /lib/x86_64-linux-gnu/libc.so.6
        /lib64/ld-linux-x86-64.so.2 (0x00007fd743c00000)
        linux-vdso.so.1 (0x00007fffc75f4000)

谁能告诉我为什么 libc 需要 ld.so 以及它使用什么函数?

【问题讨论】:

    标签: c linux glibc dynamic-linking


    【解决方案1】:

    任何与共享库链接的应用程序或共享库都需要ld.so

    程序ld.sold-linux.so* 查找并加载共享 程序所需的对象(共享库),准备 程序运行,然后运行它。

    应用程序通常不会从ld-linux-x86-64.so 调用任何函数,而是加载可执行和共享库并将控制流传递给应用程序,这通常是 C 和 C++ 库运行时初始化代码。这种对ld-linux.so* 的依赖是通过ELF 文件的.interp 部分建立的(请参阅readelf -l /lib/x86_64-linux-gnu/libc.so.6 输出),这不是ldd 所显示的。

    ldd,然而,(递归地)在动态部分显示标记为NEEDED 的库(参见readelf -d /lib/x86_64-linux-gnu/libc.so.6 输出)。在 Linux 上,共享库的线程本地存储支持由/lib64/ld-linux-x86-64.so.2 实现。这是一个实现细节,但也是 glibc 依赖 ld-linux-x86-64.so 的原因。

    【讨论】:

    • 添加共享二进制文件通常引用/lib64/ld-linux-x86-64.so.2 作为它们的解释器很有用。内核将通过从 ELF 二进制文件中读取入口点和解释器来执行二进制文件,然后决定如何调用它。解释器被调用并提供原始二进制文件的名称和文件权限。库加载器 /lib64/ld-linux-x86-64.so.2 然后加载所有依赖项并跳转到动态二进制文件的入口点。
    • 所以不使用线程本地存储的共享库不会使用ld-linux.so作为DT_NEED吧?
    • @yhdang 正如我所提到的,glibc 链接 ld-linux-x86-64.so 因为后者解析 glibc 中未解析的符号,其中 一些 处理 TLS。不使用 TLS 不会改变这一点。
    猜你喜欢
    • 1970-01-01
    • 2020-01-01
    • 2010-12-15
    • 2016-06-29
    • 1970-01-01
    • 2018-04-10
    • 2016-05-05
    • 1970-01-01
    • 2015-11-15
    相关资源
    最近更新 更多