1

我已经用 编译了一个简单的hello worldc 代码gcc -fpie test.c,现在使用以下方法查看二进制文件objdump

Disassembly of section __TEXT,__text:
__text:
100000f40:  55  pushq   %rbp
100000f41:  48 89 e5    movq    %rsp, %rbp
100000f44:  48 83 ec 10     subq    $16, %rsp
100000f48:  89 7d fc    movl    %edi, -4(%rbp)
100000f4b:  8b 75 fc    movl    -4(%rbp), %esi
100000f4e:  48 8d 3d 5d 00 00 00    leaq    93(%rip), %rdi
100000f55:  b0 00   movb    $0, %al

...

我们可以清楚地看到内存地址仍然是由左侧的链接器计算的。文件不pie应该没有静态关联的内存地址吗?

我的第二个问题是,pic文件(如共享库)是如何加载到内存中的?他们有自己的虚拟地址空间吗?如果是这样,为什么他们需要独立于位置?还是将它们加载到进程地址空间中?

4

1 回答 1

1

这些不是地址。您应该查看的是 PC 相对偏移量:

leaq    93(%rip), %rdi

这些表示代码是 PIC/PIE。

共享库被映射到使用它们的每个正在运行的进程中。
然而,这些库需要重新定位(以适应程序的地址空间限制),因此使用 PIC(与位置无关的代码,也就是通常使用 PC 相对偏移量)编译。

于 2019-08-28T01:13:23.573 回答