c - 在动态链接时,动态加载器是查看所有目标文件的定义,还是仅查看可执行文件指定的目标文件?

标签 c build linker operating-system

所以我试图理解静态和动态链接。 SO 和网络上有很多资源。我想我差不多明白了,但还有一件事似乎困扰着我。另外,如果我的整体理解有误,请指正。

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

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

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

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

最佳答案

So the part I'm missing is this: where does the OS dynamic loader look - does it look in the symbol tables for all object-files in the system-libraries directory?

据我所知,没有动态链接器可以执行此操作。

Or does it only look in object-files specified somewhere in the application-executable file?

也不完全是这样。

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

Is this the reason why at compile time we must specify all dynamic dependencies of our program?

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

Also, is it true dynamic libraries expose a symbol-table too?

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

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

关于c - 在动态链接时,动态加载器是查看所有目标文件的定义,还是仅查看可执行文件指定的目标文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56066490/

相关文章:

gcc - 你能在 ld 脚本中添加两个 SECTION 部分吗

c - 为 linux 内核的简单 hello world 模块生成 .ko 文件时出错

在线性时间内用 crt 连接 C 字符串

linux - 使用 pkg-config 找不到错误 : dav1d >= 0. 2.1

java - 如何使用 Maven 创建具有依赖项的可执行/可运行 JAR?

linux - boost 静态链接

linux - 创建一个包含其链接时库依赖项的共享库

C 程序,具有检查整数 A 是否包含整数 B 的函数

c - 在 execl 之后处理 C 中的信号

maven - 如何为多模块项目中的特定模块激活 Maven 配置文件