【问题标题】:At dynamic linking, does the dynamic loader look at all object files for definitions, or only at those specified by the executable?在动态链接中,动态加载器是查看所有目标文件的定义,还是只查看可执行文件指定的目标文件?
【发布时间】:2019-05-09 19:39:17
【问题描述】:

所以我正试图围绕静态和动态链接。 SO和网络上有很多资源。我想我几乎明白了,但仍有一件事让我感到困扰。另外,如果我的整体理解有误,请纠正我。

我想我理解静态链接: 链接器解压缩链接的库,实际上将库的目标文件包含在生成的可执行文件中。然后,应用程序对象文件中的未解析存根被实际的函数调用代码替换,该代码调用构建时已知地址中的函数。

另一方面,动态链接更让我困惑:我知道在动态链接中,对象代码中引用尚未解析的名称的存根将一直作为存根直到运行时。

然后在运行时,操作系统的动态加载器将查看存储在标准文件系统位置的预编译库。它会在库的目标文件中查找它们的符号表 (?),并尝试为每个未解析的存根找到匹配的函数定义。然后它将匹配的目标文件加载到内存中,并替换存根以指向函数定义。

所以我缺少的部分是:操作系统动态加载程序在哪里查找 - 它是否在系统库目录中所有目标文件的符号表中查找?还是它只查看应用程序可执行文件中某处指定的目标文件?这就是为什么在编译时我们必须指定程序的所有动态依赖项的原因吗?另外,动态库是否也暴露了符号表?

【问题讨论】:

    标签: c build linker operating-system


    【解决方案1】:

    所以我缺少的部分是:操作系统动态加载器在哪里看 - 它是否在系统库目录中所有目标文件的符号表中查找?

    据我所知,没有动态链接器可以做到这一点。

    还是只在目标文件中查找 在应用程序可执行文件的某处指定?

    也不完全是这样。

    细节有所不同,但一般来说,动态链接器在各种目录中按名称查找特定的共享库。搜索的目录可以内置在链接器中,由操作系统指定,在被链接的对象中指定,或组合。链接器(通常)不会检查库的符号表,直到之后它通过名称找到它们并选择它们进行链接。

    这是 为什么在编译时我们必须指定所有动态依赖项 我们的计划?

    是的,尽管在某些情况下我们不需要需要在编译时指定所有动态依赖项。一些动态链接器支持程序本身指示的按需动态加载。这可用于实现插件系统,以及其他用途。

    另外,真正的动态库是否公开了符号表 也是?

    是的。动态库有自己的符号表,因为

    1. 动态链接器使用它们来完成工作,并且
    2. 动态库可以有自己的动态链接要求,不一定反映在主程序中。

    【讨论】:

      【解决方案2】:

      在正常使用中,“动态链接”是由加载器执行的。 “静态链接”由链接器执行。

      通常,链接器可以创建可执行文件或共享库。两者的链接器输出都是一个指令流,它告诉加载器如何将可执行文件或库放置在内存中。

      另一方面,动态链接更让我感到困惑:我知道在动态链接中,对象代码中引用尚未解析的名称的存根将一直作为存根直到运行时

      这[通常]是不正确的。链接器将定位符号所在的共享库。可执行文件将具有在该共享库中查找符号的指令。如果链接器找不到所有需要解析的符号,它们通常会呕吐。

      所以我缺少的部分是:操作系统动态加载程序在哪里查找 - 它是否在系统库目录中所有目标文件的符号表中查找?

      这是一个系统特定的问题。在设计良好的操作系统中,共享库由系统管理员指定。加载器使用系统指定的库。设计不佳的系统经常使用某种搜索路径来查找共享库(这会造成巨大的安全漏洞)。

      【讨论】:

        猜你喜欢
        • 2018-04-13
        • 1970-01-01
        • 1970-01-01
        • 2013-06-16
        • 2014-10-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-24
        相关资源
        最近更新 更多