微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

objdump 显示的地址是最终地址还是只是偏移量?

如何解决objdump 显示的地址是最终地址还是只是偏移量?

假设此 C 代码使用 gcc file.c 编译:

int main(){
 return 0;
}

使用 objdump 生成输出

0000000000000660 <main>:
660:    55                      push   %rbp
661:    48 89 e5                mov    %rsp,%rbp
664:    b8 00 00 00 00          mov    $0x0,%eax
669:    5d                      pop    %rbp
66a:    c3                      retq   
66b:    0f 1f 44 00 00          nopl   0x0(%rax,%rax,1)

注意第一个地址是 660

以下是 GDB 的相同输出

0x555555554660 <main>                   push   %rbp
0x555555554661 <main+1>                 mov    %rsp,%rbp
0x555555554664 <main+4>                 mov    $0x0,%eax
0x555555554669 <main+9>                 pop    %rbp
0x55555555466a <main+10>                retq

注意每个地址左侧添加5s

这是我的问题:

1- 左边的 5s 是什么?为什么 objdump 没有它们?

2- 这些只是抵消吗?或以二进制硬编码的最终地址,这些地址将加载到虚拟内存中。

3- 如果这些是偏移量,那么常规可执行文件PIE 之间有什么区别?我认为只有 PIE 代码是位置无关的,并且在加载时分配了随机地址,我没有使用 -fpie 选项进行编译。我也用过 -fno-pie 并没有什么区别。

解决方法

1- 左边的 5 是多少?为什么 objdump 没有它们?

555…55516 是 1000…00016 的三分之一。你看到多个 5 只是因为有人将某个特定的记忆区域分成了三个部分。 objdump 没有它们,因为它只是显示偏移量。

2- 这些只是抵消吗?或以二进制硬编码的最终地址,这些地址将加载到虚拟内存中。

它们是相对于它们所在程序部分开头的偏移量。

3- 如果这些是偏移量,那么常规可执行文件和 PIE 之间有什么区别?我认为只有 PIE 代码是位置无关的,并且在加载时分配了随机地址,我没有使用 -fpie 选项进行编译。我也用过 -fno-pie 并没有什么区别。

位置无关的可执行文件在程序执行期间计算其地址。它使用基址寄存器或提供给它的其他信息来定位事物,或者使用相对于程序计数器的地址,或其他与程序位置无关的寻址形式。

相反,不是位置无关的程序可以使用绝对寻址形式。然而,绝对地址不一定内置在目标模块中。目标模块中的地址可能仍然是相对于程序段或其他参考点的偏移量。当程序被加载时,加载器选择放置程序段的位置,并调整所有内置于指令中的地址,将它们从偏移地址更改为绝对地址。目标模块和最终的可执行文件包含描述需要这些“修复”的所有位置的数据结构。

位置无关代码可以同时用于两个不同进程中的两个不同虚拟内存地址。因为它使用相对寻址形式来构造其所有地址,所以代码的位置是无关紧要的。使用加载器固定地址的代码与特定地址相关联;加载程序完成后,代码在其指令中嵌入了特定地址,因此无法将其移动到其他位置。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。