chapter_07
复制本地路径 | 在线编辑
第七章讲的就是动态链接了,这里比较复杂,但是书上讲的特别好。
-
首先是一个问题:为什么要使用动态链接?两点:节省空间、便于链接库的更新 (P180)
-
然后就是 P191 开始讲的例子,将地址无关代码分为四种类型进行说明。
- 前两种比较简单,看书上例子。
- 第三种主要是一个关键问题:GOT 表中存储的是物理地址还是虚拟地址?
GOT 表中存储的是物理地址还是虚拟地址
GOT 表中存储的还是虚拟地址。现在有两个程序 a.out 和 b.out,假设都需要动态加载 test.so,其装载后的物理地址是 0xDEAD0000,我们访问的数据在 test.so 偏移位置是0x100。
现在首先是 a.out 要使用 test.so,test.so 加载到内存 0xDEAD0000 中。但同时对于 a.out 来说,它会认为 test.so 加载到了它的虚拟地址中,如下面所示。
0x08048000 0x08049000 0x00000000 r-x a.out 0x08049000 0x0804a000 0x00000000 r-- a.out 0x0804a000 0x0804b000 0x00001000 rw- a.out 0xf7d5a000 0xf7d77000 0x00000000 r-- test.so 0xf7d77000 0xf7ed4000 0x0001d000 r-x test.so 0xffeb6000 0xffed7000 0x00000000 rw- [stack]但是对于 A 的 MMU 来说,它会存储(0xf7d5a000, 0xDEAD0000) 这一对。
同样的,当 b.out 需要使用 test.so 时,它的虚拟地址假设如下。
0x08048000 0x08049000 0x00000000 r-x b.out 0x08049000 0x0804a000 0x00000000 r-- b.out 0x0804a000 0x0804b000 0x00001000 rw- b.out 0xf7d95000 0xf7db2000 0x00000000 r-- test.so 0xf7db2000 0xf7f0f000 0x0001d000 r-x test.so 0xffd84000 0xffda5000 0x00000000 rw- [stack]
对于 B 的 MMU 来说,他会存储(0xf7d95000, 0xDEAD0000) 这一对。 -
PLT 那里讲的很好,P200-202,直接看就行,很容易理解。
-
几个比较容易混淆的 Section:
.got&&.got.plt&&.plt.rel.text&&.rel.data&&.rel.dyn&&.rel.plt
-
一个问题:为什么使用 fPIC 还需要动态重定向??
-
一个很重要的问题:如果 A 和 B 同时使用 test.so 的某个全局变量,会相互影响吗?
如果 A 和 B 同时使用 test.so 的某个全局变量,会相互影响吗?
P198,不会!!!对于数据而言,每个进程都会创立副本,所以对于刚才所说的 2.2,如果 A 和 B 访问函数,那么 MMU 都是映射到 0xDEAD0000,如果访问数据,那么 MMU 映射到各自创立的副本。