修正项描述位置和运算

编译一个文件时,另一个文件中的函数地址或本文件最终放置的位置可能尚未确定。工具把待修正位置和所需规则记为重定位项,链接器或加载器随后根据实际布局计算值,再写入规定字段。

ELF重定位项包含修正位置r_offset,以及结合符号索引与重定位类别的r_info。类别规定应执行怎样的地址运算和编码;具体规则是机器相关的,不能把所有项目都理解成“往地址上加同一个常数”。

参考:[1]

隐含加数与显式加数

ELF的REL格式从被修正字段取得隐含加数,RELA格式则在记录的r_addend中保存显式加数。加数参与地址计算,不能因为记录里有符号索引,就忽略原位置或记录中携带的其他数值。

r_offset的解释也随文件类别改变:在可重定位目标文件中,它是相对有关节起点的字节偏移;在可执行文件或共享对象中,它可表示待修正位置的虚拟地址。同一个字段名称并不意味着在每个阶段都有相同坐标系。

参考:[1]

链接阶段与加载阶段的不同任务

静态链接可确定输入节怎样组合、哪些符号定义被采用,并处理此时能完成的引用。动态加载时,一些地址又取决于共享对象实际加载位置和运行时符号选择;这些修正不是每次调用都重新链接整个程序。

位置无关代码可以减少需要修改的指令地址,却不排除数据指针或其他项目仍需重定位。符号解析回答采用哪个定义,重定位回答怎样把该定义及布局关系编码到引用处;两者相关,但属于不同操作。

参考:[2] [3] [1]