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