Chinaunix首页 | 论坛 | 博客
  • 博客访问: 23081
  • 博文数量: 8
  • 博客积分: 20
  • 博客等级: 民兵
  • 技术积分: 149
  • 用 户 组: 普通用户
  • 注册时间: 2010-06-01 11:02
个人简介

no no no

文章分类

全部博文(8)

文章存档

2013年(8)

我的朋友

分类: C/C++

2013-08-09 01:53:16

objdump -h test.o
得到elf的各段信息,有大小、文件内偏移量、各段属性等。


objdump -s -d test.o(-s打印十六进制,-d将包含指令的段反汇编)
其中,代码段与数据段分开,且代码段为readonly属性,这样做三个原因:
1.代码段与数据段映射到进程中不同的地址空间;
2.cpu缓存设计成代码缓存与数据缓存分离;
3.代码段可在进程间共享,节省内存。如同个进程多次打开。




size test.o可看主要三段text data bss段的大小。


可写代码确认各段的大小,数据的存放。
常见段:
 


gcc有扩展机制指定某变量可放入某个段内:
__attribute__((section("some")) int c;


elf文件结构:
 




readelf -h test.o读ELF Header。
对应的文件头结构定义于代码:
/usr/include/elf.h内。


ELF头16字节魔数。头4为标志ID,用于操作系统加载时判断是否正确的文件类型。第5字节表示是否32字段或64字节。第6字节1小端、2大端。第7字节版本号。后9字节无用。
 
DEL+“ELF”


头中TYPE,可重定向.o;可执行;共享目标文件.so。


机器类型指出何机器运行,段表偏移指出段表所在。


readelf -S test.o读取段表,显示全的段信息。每段有类型和标志,决定本段是什么段。
重定位表.rel.test段是需要重定位的东西存的地方;
字符串表分一般的.strtab和段的.shstrtab,前者存正常,后者存段表中的,如段名,这个段在ELF文件头中有起始偏移。


符号表:.symtab
符号,是链接的关键因素。符号表中记录的值,就是代码或函数的地址。 nm test.o读取符号表。
符号类型与绑定信息说明了符号的类型。
readelf -s test.o显示符号表相关。


符号名称:
早期变量名即符号名,这样会造成符号冲突。后来C规定foo变成符号时为_foo。当前gcc默认不加_foo,只有vc加。而c++为解决重载、不同类问题引入了函数签名,使符号看上去复杂,可用c++filt还原。
因此,在c++链接c库时,符号名称不一致,所以引入extern "C"。代码中一般判断__cplusplus来处理。


强符号、弱符号:
函数、初始化的全局变量为强符号,未初始化的全局变量为弱。也可__attrbute__((weak))强行定位弱符号。
链接时强弱符号处理规则:
1. 强符号只能有一个;2. 强弱共存取强;3. 多个弱符号取大的。
可用于在库文件中定义的函数定义成弱符号时,被用户代码覆盖而不报错。


强引用、弱引用:
强引用指链接时,未找到符号定义会报错的引用。弱引用则找不到符号定义时设为特殊值,一般是0。
gcc可__attribute__((weakref))指定为弱引用。
可用于判断是否链接了外部库,如lpthread。


strip test.o用于去除目标文件中的调试信息。




阅读(990) | 评论(0) | 转发(0) |
0

上一篇:ldd 8 内存分配

下一篇:没有了

给主人留下些什么吧!~~