链接(GNU ld)重定位过程中R_386_PC32和R_X86_64_PC32之间的区别是什么 [英] What's the difference between R_386_PC32 and R_X86_64_PC32 in link(GNU ld) relocation process
问题描述
阅读书籍时计算机系统:程序员的观点第7.7.1节重定位条目:本节的简要内容是链接器如何在不同的目标文件中重新定位引用。
When reading the book Computer System: A Programmer's Perspective Section 7.7.1 Relocation Entries: the brief content of this section is how a linker relocate reference in a different object file.
编译和objdump时的示例源代码:
When compile and objdump the example source code:
void swap();
int buf[2] = {1, 2};
int main()
{
swap();
return 0;
}
然后是gcc -Wall -c -o main.o main.c,和objdump -S -r main.o> main.asm;并将看到交换的重定位条目:
Then gcc -Wall -c -o main.o main.c, and objdump -S -r main.o > main.asm; and will see the relocation entry for swap:
6: e8 fc ff ff ff call 7 <main+0x7> swap();
7: R_386_PC32 swap relocation entry
所以当ld链接main.o并交换。 o,ld将使用swap的重定位条目r(offset = 7,type = R_386_PC32)来确定链接地址:
So when ld link the main.o and swap.o, the ld will use the relocation entry r of swap(offset=7, type=R_386_PC32) to determine the link address:
refaddr = ADDR(section .text) + r.offset
*refptr = (unsigned)(ADDR(r.symbol + *refptr - refptr)
调用指令的操作数(fc ff ff ff)-4非常适合386指令集。
And the operand of call instruction (fc ff ff ff) -4 is perfectly suiting for 386 instruction set.
但是当我在X86_64 Linux中重复这个时,我发现呼叫的代码是:
But when I repeat this in a X86_64 Linux, I found the code for the call is:
9: e8 00 00 00 00 callq e <main+0xe>
a: R_X86_64_PC32 swap relocation entry
然后我的问题这就是为什么386中的调用(e8)的操作数是-4((fc ff ff ff),但是X86_64 main.o中的操作数是00 00 00 00?是不是因为指令集不同(call与callq)或者只是GNU ld使用不同的算法进行relo阳离子R_X86_64_PC32?
Then My question is why the operand of call(e8) in 386 is -4((fc ff ff ff), but the operand in X86_64 main.o is 00 00 00 00? Is it because of the different instruction set(call vs. callq), or just the GNU ld use different algorithm to relocation R_X86_64_PC32?
希望你回答,非常感谢。
Hope for you answer, Many thanks.
推荐答案
值无关紧要,在重定位过程中会被覆盖。显然,对于i386,编译器默认指向重定位条目本身,而对于x86-64,它指向下一条指令。无论如何,它只是一个虚拟值。
The value doesn't matter, it will be overwritten during the relocation process. Apparently, for i386 the compiler defaults to pointing to the relocation entry itself, while for x86-64 it points to the next instruction. It's just a dummy value anyway.
这篇关于链接(GNU ld)重定位过程中R_386_PC32和R_X86_64_PC32之间的区别是什么的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!