链接(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

查看:1622
本文介绍了链接(GNU ld)重定位过程中R_386_PC32和R_X86_64_PC32之间的区别是什么的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

阅读书籍时计算机系统:程序员的观点第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屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆