28|程序可以在运行时进行链接吗?
该思维导图由 AI 生成,仅供参考
为什么要使用动态链接?
- 深入了解
- 翻译
- 解释
- 总结
本文深入介绍了动态链接技术的原理和应用。首先解释了动态链接的出现目的,以及动态链接相对于静态链接的优势。文章详细讲解了动态链接的基本原理,包括使用共享库的方法、位置无关代码(PIC)和全局偏移表(GOT)的重要作用。接着,文章通过实例分析了动态链接的执行过程,以及初次执行和再次访问时的流程。此外,文章还介绍了加载时链接和运行时链接的区别,以及运行时链接的实现方式和API。总的来说,本文通过深入的技术讲解,帮助读者全面了解了动态链接的原理和应用,以及相关的技术细节。
《深入 C 语言和程序运行原理》,新⼈⾸单¥59
全部留言(6)
- 最新
- 精选
- liu_liu老师,有几个问题想了解下: 1. 假设共享库 M,引用由应用程序定义的某个全局变量 g。而 A、B 程序都链接了 M,那么 M 中的 .got 是不是需要复制一份?因为 A、B 中 g 变量的虚拟地址不一样。 2. 关于 _dl_runtime_resolve 做符号重定位,是会遍历到所有依赖的动态库吗?如果两个动态库中都有这个符号,那么会定位到顺序靠前的动态库中的符号? 3. 如果第 2 点成立,那遍历动态库的顺序是根据链接时参数的顺序来的吗?
作者回复: 这几个问题很棒!下面是回答: 1. 是这样的,每个进程的 VAS 中共享库 M 的内存映像内都有自己的 GOT Section,里面保存了不同的地址信息。在物理内存上看,Text Segment 中的数据是可以共享的,而 Data Segment 则是进程独立的。 2. 是的,通常动态链接器会默认使用第一个被 resolve 的符号,这个过程也被称为 “Symbol Interposition”。 3. 动态链接器通常会采用广度优先(breadth-first)的方式,按照可执行文件中 .dynamic Section 里 DT_NEEDED 条目内的记录顺序进行解析。
2022-02-286 - 纳兰容若老师您好 有个问题请教一下 在图中的地址是不是画错了,一个是601008一个是6001008,还是地址之间有换算
作者回复: 感谢指正!这边应该是图里的地址写错了,我来更新一下。这边这两个地址应该是完全相同的。
2022-05-072 - 福利社现在程序的链接库越来越多,请问老师,有没有办法找出程序所有存在symbol interposition的函数及所在的动态库。
作者回复: Runtime Interposition 实际上是动态链接器做出的一种选择。对于自己可以控制的代码部分,通常可以选择性地添加 static 关键字,来限制各个符号的作用域,使它们仅维持在当前编译单元。我查了一下,貌似没有发现比较好的方式可以直接暴露出链接过程中发生的 Symbol Interposition。有一种方式是自己写一个简单的脚本,通过使用 “nm” 命令遍历程序以及它的所有依赖动态库,以此来查看是否有重名的符号存在。符号类型可以通过输出内容的 Symbol Type 字段区分,具体可以参考这里:https://www.ibm.com/docs/en/zos/2.1.0?topic=scd-nm-display-symbol-table-object-library-executable-files。
2022-03-032 - 谦谦老师你好,请问下,为什么编译应用程序的时候,共享库和应用程序要放在一起。假如我只知道共享库的名字,和运行时所在的路径。这种情况可以编译应用程序吗?
作者回复: 可以的,比如对于 Clang 你可以通过 LD_LIBRARY_PATH 环境变量来设置共享库的查找路径。
2022-08-26归属地:上海 - 神佑小鹿假设共享库 M,引用由应用程序定义的某个全局变量 g。而 A、B 程序都链接了 M。。 这个关系很奇怪,这个应用程序是指的 A 和 B 么?? 如果是 A 和 B,这个依赖关系不是很怪么?
作者回复: “这个应用程序是指的 A 和 B 么?” - 是的。 这里的例子只是为了帮助理解课程内容,不谈软件设计上的合理性,至少这种使用方式本身是合法的,因此现实情况中类似的场景也还是有的。
2022-05-153 - 连瑞龙在Linux系统中,共享库(shared library)使用 soname(共享库的名字)机制来管理共享库的版本。soname是"Shared Object NAME"的缩写,它是在共享库中嵌入的标识符,用于指定库的版本信息。 soname机制的主要目的是在不同版本的共享库之间提供兼容性,以允许多个版本的共享库在系统上共存,而不会相互干扰。soname由以下两个部分组成: 1. **实际文件名(Real name):** 共享库的实际文件名,通常以`.so`为后缀。 2. **soname:** 共享库的名字,包含主版本号。soname一般形式为`lib<name>.so.<major>`,其中`<name>`是库的基本名字,`<major>`是主版本号。例如,`libexample.so.1`。 在共享库的构建和安装过程中,开发者通常会使用`-soname`选项来指定soname。例如: ```bash gcc -shared -o libexample.so.1.0 -Wl,-soname,libexample.so.1 example.o ``` 这个命令将生成一个名为`libexample.so.1.0`的共享库文件,并且指定其soname为`libexample.so.1`。这样,当程序链接到共享库时,会使用soname来查找和链接共享库,而不是直接使用实际文件名。 使用soname的主要优势包括: - **版本管理:** soname允许系统上存在多个版本的同一个共享库,每个版本都可以独立安装和管理。 - **向后兼容性:** 当共享库的API发生变化时,通过更新soname,可以确保新版本与旧版本兼容,从而防止因为API的变化而导致的程序崩溃。 - **符号冲突的解决:** 当多个共享库的实际文件名相同,但soname不同时,可以避免符号冲突,确保程序能正确链接到所需版本的库。 总之,soname机制在Linux系统中用于管理共享库的版本,提供了一种有效的方式来确保共享库的向后兼容性和版本管理。2024-01-09归属地:北京