重定位算法
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