位置无关代码是怎么产生的?
1 编译时根据选项-fPIC,来决定是否生成位置无关代码(实际上,只是对符号的重定位方式进行不同的标记而已)
2 链接时根据不同的重定位方式,生成真正的重定位代码(例如,多了.got .plt等)
位置无关代码的基本原理
在访问变量或者函数的时候,使用相对地址来访问(即当前指令的偏移)
位置无关代码的相关数据结构
1 .got表(变量的查找)
2 .got.plt表(函数的查找)
3 .plt表(这东西是为了延迟绑定,准备的)
位置无关代码的重定位(程序启动的时候)
1 对.got表里面的每一个变量进行重定位(值为变量的具体地址)
2 对.got.plt里面的每一个函数进行重定位
1 值为对应的.plt表项的指令地址,即lazy binding)
2 值为函数的具体地址(dlopen不延迟绑定的时候)
判断一个.so文件是否是位置无关代码
readelf -d foo.so | grep TEXTREL(即判断,是否具有代码段重定位表)
位置无关代码的编译规则
1 如果是自己本地的静态变量或函数,则只需要相对rip的偏移量即可
static void func(),不走got,就是相对地址,加快函数调用速度
2 如果是全局变量,或者是外部引用,则需要got表
global void func(),走got,为了全局统一
3 如果可执行文件是动态链接的,则默认生成位置无关代码(不显示指定fPIC的时候)
4 -Bsymbolic
网友评论