为何.o文件Objdump反汇编看不到函数名,二进制反汇编能看到?

reteitre 2016-10-04 11:45:25
我的预想是:
(1) 在编译阶段,gcc -c使得函数调用被一个名称占位符写入,也就是call strlen, call write这种,而真正的strlen,write的地址要在链接的阶段,被真正的地址取代。

(2) 在链接的阶段,因为strlen和write函数的真正地址被gcc知道了,所以用真实的地址去取代call strlen当中
的strlen,变成一个数字。

首先我有两个.c文件,一个有main函数,一个定义了a函数,如下:

$ cat m.c
void a(char*);
int main(int argc,char*argv[])
{
char s[]="hello\n";
a(s);
return 0;
}

$ cat a.c
#include<unistd.h>
#include<string.h>
void a(char*s)
{
write(1,s,strlen(s));
}

复制代码
我用gcc -c 编译它们,然后用objdump -d看它们的反汇编结果:

$ objdump -d a.o
a.o: 文件格式 elf64-x86-64
Disassembly of section .text:

0000000000000000 <a>:
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: 48 83 ec 10 sub $0x10,%rsp
8: 48 89 7d f8 mov %rdi,-0x8(%rbp)
c: 48 8b 45 f8 mov -0x8(%rbp),%rax
10: 48 89 c7 mov %rax,%rdi
13: e8 00 00 00 00 callq 18 <a+0x18>
18: 48 89 c2 mov %rax,%rdx
1b: 48 8b 45 f8 mov -0x8(%rbp),%rax
1f: 48 89 c6 mov %rax,%rsi
22: bf 01 00 00 00 mov $0x1,%edi
27: e8 00 00 00 00 callq 2c <a+0x2c>
2c: 90 nop
2d: c9 leaveq
2e: c3 retq

看起来在a.o文件里面,两个call指令并没有对应的函数名,而是变成了地址callq 18和callq 2c,然后

$ gcc m.o a.o -o m
$ objdump -d m

复制代码
可看到a函数的反汇编代码:

000000000040062c <a>:
40062c: 55 push %rbp
40062d: 48 89 e5 mov %rsp,%rbp
400630: 48 83 ec 10 sub $0x10,%rsp
400634: 48 89 7d f8 mov %rdi,-0x8(%rbp)
400638: 48 8b 45 f8 mov -0x8(%rbp),%rax
40063c: 48 89 c7 mov %rax,%rdi
40063f: e8 5c fe ff ff callq 4004a0 <strlen@plt>
400644: 48 89 c2 mov %rax,%rdx
400647: 48 8b 45 f8 mov -0x8(%rbp),%rax
40064b: 48 89 c6 mov %rax,%rsi
40064e: bf 01 00 00 00 mov $0x1,%edi
400653: e8 38 fe ff ff callq 400490 <write@plt>
400658: 90 nop
400659: c9 leaveq
40065a: c3 retq
40065b: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)

复制代码
这个是有函数名的。

看到的结果,和我预想的相反。我的理解错在哪里,为什么编译阶段生成的.o只有地址,没有名称,链接之后反而变成了名称,而不是地址?
...全文
2138 2 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2016-10-05
  • 打赏
  • 举报
回复
gcc是开源的。
fefe82 2016-10-05
  • 打赏
  • 举报
回复
实际不是 callq 18 和 callq 2c ,是 callq +0 。 callq 指令里放的相对的偏移,填的都是零。在最后链接的时候才填上的具体内容。所以在 .o 里也就看不到实际被调用的函数。 .o 会有一个地方,记录着所有需要重新填写地址的函数列表,以及这些函数在程序中哪里被调用了。 链接只有 ,callq 后面被填入了真正的偏移。于是反汇编器可以根据这个偏移找到函数的真正的地址,然后根据地址在符号表或者调试信息找到这个函数的名字。函数名是不会即在指令里的。
标题SpringBoot构建的人工智能时代个人计算机安全防护科普系统研究AI更换标题第1章引言阐述研究背景、意义,分析国内外在个人计算机安全防护科普方面的现状,并介绍论文研究方法和创新点。1.1研究背景与意义说明人工智能时代个人计算机安全防护的重要性。1.2国内外研究现状概述国内外在个人计算机安全防护科普系统的研究进展。1.3研究方法与创新点介绍本文采用的研究方法以及创新之处。第2章相关理论概述SpringBoot框架、人工智能技术及计算机安全防护的理论基础。2.1SpringBoot框架简介介绍SpringBoot框架的特点及其在科普系统中的应用。2.2人工智能技术概述阐述人工智能技术的基本原理及其在安全防护中的应用。2.3计算机安全防护理论分析个人计算机安全防护的基本原理和方法。第3章科普系统设计详细介绍基于SpringBoot的人工智能时代个人计算机安全防护科普系统的设计思路和实现过程。3.1系统架构设计阐述科普系统的整体架构设计及各模块功能。3.2科普内容策划与设计分析科普内容的选择、编排和设计原则。3.3交互功能设计介绍科普系统的交互功能,提升用户体验。第4章系统实现与测试详述科普系统的实现过程,包括前端开发、后端实现和系统测试等环节。4.1前端开发实现介绍前端界面的设计、开发和实现过程。4.2后端功能实现详述后端功能的实现,包括数据处理、安全防护策略等。4.3系统测试与优化阐述系统测试的方法、过程和结果,以及针对测试结果的优化措施。第5章应用效果评估通过实际应用案例,评估科普系统在提升个人计算机安全防护意识方面的效果。5.1应用案例选取选择具有代表性的应用案例进行分析。5.2效果评估方法介绍评估科普系统效果的方法和指标。5.3评估结果分析对评估结果进行详细分析,验证科普系统的有效性。第6章结论与展望总结研究成果,指出研究的不足之处,并展望未来的研究方向。6.1研

65,194

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧