linux可执行文件格式解析,Linux下可执行文件格式详解

Entry point address 指的是程序入口地址,如果是可执行文件,这个字段会有值;

他之前的字段是一些说明字段;

Start of program headers 指的是 程序头表 的起始位置。程序头表 是从装载视图的角度对elf的各个段进行的分类信息;结构和段表相似;

Start of section headers 指出了elf除文件头以外的最重要的信息:段表 的起始位置。段表包含了各个段的名称、属性、大小、位置等重要信息。操作系统首先找到段表,然后根据段表的信息去找到各个段。段表是一个类似数组的结构,一个段的信息是这个数组的一个元素。

Size of this header 指的是头文件大小,32位都是 52 个字节,0x34个字节。

Size of program headers 指的是每个 程序头表 的大小。

Number of program headers 指的是 程序头表 的数目。

Size of sections headers 指的是每个 段表 的大小;

Number of section headers 指的是 段表的数量;

Section header string table index 指出了段表当中用到的字符串表在段表中的下标。

文件头之后,紧跟着的是 程序头,因为目标文件没有链接,所以没有装载信息。我们这里可以先不理会这个东西,以后专门再说他。

程序头之后就是各个段的数据,我们用工具查看一下:

[root@www.linuxidc.com-CentOS Program]# readelf -S SimpleSection.o

There are 11 section headers, starting at offset 0xe0:

Section Headers:

[Nr] Name              Type            Addr    Off    Size  ES Flg Lk Inf Al

[ 0]                  NULL            00000000 000000 000000 00      0  0  0

[ 1] .text            PROGBITS        00000000 000034 000020 00  AX  0  0  4

[ 2] .rel.text        REL            00000000 0003f4 000010 08      9  1  4

[ 3] .data            PROGBITS        00000000 000054 000008 00  WA  0  0  4

[ 4] .bss              NOBITS          00000000 00005c 000004 00  WA  0  0  4

[ 5] .rodata          PROGBITS        00000000 00005c 000004 00  A  0  0  1

[ 6] .comment          PROGBITS        00000000 000060 00002d 01  MS  0  0  1

[ 7] .note.GNU-stack  PROGBITS        00000000 00008d 000000 00      0  0  1

[ 8] .shstrtab        STRTAB          00000000 00008d 000051 00      0  0  1

[ 9] .symtab          SYMTAB          00000000 000298 0000f0 10    10  10  4

[10] .strtab          STRTAB          00000000 000388 00006b 00      0  0  1

Key to Flags:

W (write), A (alloc), X (execute), M (merge), S (strings)

I (info), L (link order), G (group), x (unknown)

O (extra OS processing required) o (OS specific), p (processor specific)

各个字段意思依次是:段序号、段名称、段类型、段虚拟地址、偏移量、大小、ES、标志、Lk、Inf、对齐。

没有解释的列可以先不考虑,我们先关注其他几个列。

第0个段是为了读取的时候下标不用减1。

紧跟着的就是代码段,偏移量为0x34,就是说在文件头结尾之后马上就是代码段;

代码段之后,偏移量 0x54 的地方就是 数据段,占8个字节,就是程序中已经被赋值的一个全局变量和一个静态变量;

紧接着是.bss段,这里只存储了一个static变量,因为 未初始化的那个全局变量被一种优化机制存储到了 .common 段,这里可以不做理会;

然后是只读数据段.rodata,这里存储的是 printf 里面的 %d\n 这三个字符,外加结束符\0,总共4个字节的空间

我们根据Size这一列来算一下这些段总共占据的空间,(.bss由于不占空间,不用算进来):

.text 0x20

.data 0x8

.rodata 0x4

.comment 0x2d

.shstrtab 0x51

.rel.text 0x10

.symtab 0xf0

.strtab 0x6b

这里的每一个段都有一个段表元素来描述,总共11个。从头文件得知,每个元素的大小为40字节。也就是说段表总共占了 0x1b8 个字节的空间。而且段表的开始地址由于内存对齐需要,中间空了2个字节。因为段表的开始地址是第224个字节;

.rel.text 的开始地址也由于内存对齐的要求,补了一个空字节。

在加上头文件的 0x34 个字节,总共加起来是  1028 字节。

[root@xuxingwang-centos Program]# ls -al SimpleSection.o

-rw-r--r-- 1 root root 1028 Aug 21 16:09 SimpleSection.o

这个目标文件的大小恰好是1028个字节。

0b1331709591d260c1c78e86d0c51c18.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值