foreach section s { //对于每个节
foreach relocation entry r { //对于每个重定位条目,条目在节上
refptr = s + r.offset; /* ptr to reference to be relocated */
/* Relocate a PC-relative reference */
if (r.type == R_X86_64_PC32){
refaddr = ADDR(s) + r.offset; /* ref's run-time address */
*refptr = (unsigned) (ADDR(r.symbol) + r.addend - refaddr);
}
/* Relocate an absolute reference */
if (r.type ==R_X86_64_32)
*refptr = (unsigned) (ADDR(r.symbol) + r.addend);
}
}第 1 行和第 2 行在每个节 s 以及与每个节相关联的重定位条目 r 上迭代执行
假设每个节 s 是一个字节数组,每个重定位条目 r 是一个类型为 Elf64_Rela 的结构
假设当算法运行时,链接器已经为每个节(用 ADDR(s) 表示)和每个符号都选择了运行时地址(用 ADDR(r.symbol) 表示)
ADDR(s) 表示 节的地址
ADDR(r.symbol) 表示 符号的运行时地址
第 3 行计算的是需要被重定位的 4 字节引用的数组 s 中的地址,也就是这个符号在节中的相对位置
如果这个引用使用的是 PC 相对寻址,那么它就用第 5 ~ 9 行来重定位
如果该引用使用的是绝对寻址,它就通过第 11 ~ 13 行来重定位