对于一个包含共享对象和可执行目标文件的模块来说,共享对象在装载前往往不能确定自己在进程虚拟空间的位置,具体原因有以下两点
-
地址冲突问题
由于共享对象会被很多其他模块共同使用,如果共享对象使用一个固定的装载地址,那么这个地址就不能被其他进程所使用,会造成空间的浪费
-
共享库的更新问题
共享库如果使用规固定地址,那么对共享库升级后共享库中的全局函数和变量地址就不能够改变,否则如果有应用程序在链接时就已经绑定到了这些地址,那么升级后他们必须重新进行链接
因此,共享对象的装载时地址往往会在装载前一刻由操作系统决定,只有当装载后才能确定
装载时重定位
由于共享对象的装载时地址无法事先确定,所以在产生共享对象时,就出现了装载时重定位,即在装载时进行重定位
在Linux中,只使用-shared选项时会默认产生使用装载时重定位的共享对象
3.地址无关码
-
由于装载时重定位的方法需要对指令部分进行修改,所以没有办法做到一份指令同时被多个进程所共享
-
对于共享对象中的可修改数据部分来说使用转载时重定位则没有问题,因为这部分会被每个进程都拷贝一份副本
由于装载时重定位的指令部分无法共享的确定,由此产生了地址无关码
- 可以加载而无需重定位的代码称为地址无关码
- gcc中使用-fPIC选项可以得到使用地址无关码的共享对象
实现方法
-
基本思想
将指令中哪些需要被修改的部分