符号解析和重定位
在上一篇博客空间的地址与分配介绍过,链接器链接目标文件分为两个步骤。这一篇博客就是介绍第二步符号解析和重定位的。这也是静态静态链接中的核心内容。符号详解
重定位
看下边一个例子:
#include "func.c"
int main()
{
func();
}
在这段代码中的函数func(),因为其定义在其他文件中,所以在编译器就暂时把地址0看做是“func()”
的地址。等到链接器在完成地址和空间分配之后就可以确定所有符号的虚拟地址(包括func),那么链接器就可以根据重定位表对每个需要重定位的符号进行地址修正。
符号解析
在我们的观念中,之所以要链接就是因为我们在目标文件中用到的符号被定义在其他目标文件。这也是我们在编译过程中出现“undefined symbol”这类编译错误的原因。
其实重定位的过程往往也伴随着符号的解析过程,每个重定位的入口都是对一个符号的引用,那么当链接器需要对某个符号的引用进行重定位时,它就要确定这个符号的目标地址,这时候链接器就回去查找由所输入目标文件的符号表组成的全局符号表,找到相应的符号进行重定位。
参考文献
[1] 俞甲子 石凡 潘爱明.程序员的自我修养.电子工业出版社,2009.4.