Chapter 0304
第三第四章主要讲一下 静态链接,最直观就是通过例子讲解。
P98 给出的 a.c 和 b.c 两个文件就非常好。
1. 首先通过编译汇编之后,我们有 a.o 和 b.o 两个目标文件,这两个文件肯定是有不确定的地方,非常推荐看一下 P104 的输出结果。所以开始把这两个文件静态链接让它最后合起来的目标文件是 OK 的。
2. 合并第一步要做的就是相似段合并,代码段合在一起,数据段合在一起。然后就开始对之前不确定的符号进行重定位。(如例子中 a.c 用到了 shared 和 swap 这两个变量, P98/P104)
3. 问题就是怎么知道哪些地方要去改?答案是【重定位表】,每个目标文件都有重定位表,找到这个表在文件的偏移位置很简单:首先有【ELF头部】记录了【段表】这个数据结构,然后【段表】没干其他事,专门记录了各个其他表的属性,比如可读可写、偏移位置等,所以可以通过【段表】来找到【重定位表】。
4. 找到【重定位表】后干什么?表里面的结构可以看 P107 的输出结果和讲解。主要两点:它记录了符号的偏移值;然后 P107 最后的那个表里面还提到【重定位表】也记录符号在【符号表】中的下标。
5. 我们知道了要修改符号的位置,那要改成什么?因为知道【符号表】中下标,所以同样,通过【ELF头】找【段表】再找【符号表】。【符号表】的讲解在 P81-P83。具体逻辑过程是下面这样:P108 给出了 a.o 的【符号表】,有 shared 符号,但是 UND(undefined);但是 b.o 的【符号表】也有 shared 符号,而且是有具体值的,所以合并的时候我们就可以知道 shared 这个符号它的值是多少了。
6. 如此,最终结果搞定了目标文件的重定位。
涉及的文件格式:libc.a (见 P119)