linux目标文件,Linux下目标文件分析

作者:冯老师,

1. 程序源码如下:

feb01abb59d53881647667ddaeb22218.png

2.命令

gcc –E simple_section.c –o simple_section.i

gcc –S simple_section.i –o simple_section.s

gcc –c simple_section.s –o simple_section.o

gcc simple_section.o –o a.out

3. Elf文件头

ELF目标文件格式的最前部是ELF文件头,它包含了描述整个文件的基本属性,包括ELF魔数、文件机器字节长度、数据存储方式、版本、运行平台、ABI版本、ELF重定位类型、硬件平台、硬件平台版本、入口地址、程序头入口和长度、段表的位置和长度及段的数量等。

文件头的结构体定义如下:

3314fc38a63e95f41c80a147e2169a25.png

使用”readelf –h”命令可以查看目标文件头文件的内容:

95efb84099c945e2d338bce42f46e402.png

magic是结构体的第一个成员e_indent,16个字节:

最开始的4个字节是所有的ELF文件都必须相同的标识码,分别为0x7f, 0x45, 0x4c,0x 46。第一个字节对应ASCII字符里的DEL控制符,后面3个字节刚好是ELF这三个字母的ASCII值。

4. 段表

ELF文件中有很多段,段表就是保存这些段的基本属性的结构。包括每个段的段名、段的长度、在文件中的偏移、读写权限及段的其他属性。也就是说ELF文件段的结构式由段表决定的,编译器、连接器和装载器都是依靠段表来定位和访问各个段的属性的。

段表的定义如下:

6f688905315909bfea50d033d15bf7dc.png

“objdump –h”命令只是显示关键段,省略了辅助性的段。”readelf -S”命令显示的更完整。

68e5df80a5e1c3a07cc9d0a9521867c4.png

已初始化的全局变量和局部静态变量,都保存在.data段。未初始化的全局变量和局部静态变量一般放在.bss段。

但是,这个例子里,bss段只占4个字节。

通过下面的符号表,可以看出只有static_var2变量放在了bss段中,global_uninit_var并没有放在任何的,只是一个未定义的“COMMON符号”,这和编译器有关,全局的未初始化变量,有的放在bss 段,有的则不放,只是预留一个未定义的全局变量符号,等到最终链接成可执行文件的时候,再在bss段分配空间。

5c98eeb3ed39a7c8ee2da8c40311520b.png

0d7b7a4a71824bad5a9d0e8d76e28edf.png

备注:

1) .bss段在”objdump -h”的输出结果中,没有“CONTENTS”,因此不存在。

2) .comment段:存放的是编译器版本信息,比如字符串“GCC:(GNU)4.2.0”

3) .shstrtab : Section String Table.段名表

4) .strtab:string table字符串表

5) .symtab: Symbol Table符号表

6) .rel.text: 告诉链接器指令中的哪些地方需要做重定位

7) .objdump –s simple_section.o命令可以显示所有段的内容。

8) .hexdump –C simple_section.o 命令,可以把目标文件中的所有字节都打印出来。

5679e1852fe1e4d742008d934e65c211.png

start of section headers是372字节,十六进制后是0x00000174。和下图中section table的起始地址是一致的。

再结合”readelf –S simple_section”的结果,注意Al属性,会有对齐,可以画出下面的图:

234e55399b5e5d8f66e154751dd40ccb.png

最后的0x51c刚好是1308字节,是simple_section.o的大小。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值