重定位算法
foreach section s {
foreach relocation entry r {
refptr = s + r.offset;
if (r.type == R_386_PC32) {
refaddr = ADDR(s) + r.offset;
*refptr = (unsigned) (ADDR(r.symbol) + *refptr - refaddr);
}
if (r.type == R_386_32) {
*refptr = (unsigned) (ADDR(r.symbol) + *refptr);
}
}
}
理解
重定位PC相對引用
*refptr
是要重定位的內容(即要重定位的引用的地址),ADDR(r.symbol) - refaddr
是運行時引用的地址到符號的偏址。運行到該指令時PC爲push PC onto stack PC <- PC + *refptr
那麼運行時實際的偏址就應該是
*refptr + 引用的地址到符號的偏址
即*refptr + ADDR(r.symbol) - refaddr
重定位絕對引用
對於絕對引用,就只需要將運行時地址加上引用地址即可,即
ADDR(r.symbol) + *refptr