04可重定位⽬标⽂件ELF⽂件解析
⽬录
⼀:可重定位⽬标⽂件的特点
·可被链接(合并)⽣成可执⾏⽂件或共享⽬标⽂件
·静态链接库⽂件由若⼲个可重定位⽬标⽂件组成世界大学排名2012
·包含代码、数据(已初始化全局变量和局部静态变量.data和未初始化的全局变量和局部静态变量.bss)
·包含重定位信息(指出哪些符号引⽤处需要重定位)
·⽂件扩展名为.o(相当于Windows中的.obj⽂件)
我们都知道可重定位⽬标⽂件都是⽤来进⾏链接⽣成可执⾏⽬标⽂件的,那么下⾯我们来看下相应的链接试图,看看可重定位⽬标⽂件中都包含什么信息,下图是⼀个简单的举例,⼀起来看下吧。
洋气是什么意思
通过上⾯的图⽚我们可以看出ELF⽂件主要包含了text,data,bss节,之前的⽂章对这些节的内容也做了简单的介绍,具体可以翻看之前的内容。要想进⾏连接,除了这⼏个节之前还需要其他的信息,⽐如符号表,重定位信息等等,这些后⾯会⼀⼀介绍。这⾥我们先介绍下为什么会有BSS节。
·C语⾔规定:
– 未初始化的全局变量和局部静态变量的默认初始值为0
· 将未初始化变量(.bss节)与已初始化变量(.data节)分开的好处
– .data节中存放具体的初始值,需要占磁盘空间
– .bss节中⽆需存放初始值,只要说明.bss中的每个变量将来在执⾏时占⽤⼏个字节即可,
因此,.bss节实际上不占⽤磁盘空间,提⾼了磁盘空间利⽤率
awv· BSS 中所⽤的⼀个 (Block Started by Symbol)最初是UA-SAP汇编程序伪指令,⽤于为符号预留⼀块内存空间
· 所有 通过专门的 未初始化的全局变量和局部静态变量 “节头表(Section header table)”
都被汇总到.bss节中,来说明应该为.bss节预留多⼤的空间
⼆:可重定位⽬标⽂件的格式
prize是什么意思上⾯讲了可重定位⽬标⽂件有text,data,bss节,除了这些内容还有其他的重要信息,下⾯我们⼀起来探讨⼀下吧。
从上⾯的图中我们可以看到可执⾏⽬标⽂件包含的内容有很多,下⾯我们⼀⼀进⾏分析
1:ELF头
ELF头位于ELF⽂件开始,包含⽂件结构说明信息。分32位系统对应结构和64位系统对应结构(32位版本、64位版本)。包括16字节标识信息、⽂件类型 (.o,exec, .so)、机器类型(如 IA-32)、节头表的偏移、节头表的表项⼤⼩以及表项个数。
我们以32为操作系统做举例,其对应的数据结构如下所⽰:
#define EI_NIDENT 16
typedef struct { unsigned char e_ident[EI_NIDENT];cured
Elf32_Half e_type;
Elf32_Half e_machine;
Elf32_Word e_version;
aqfElf32_Addr e_entry;
Elf32_Off e_phoff;
Elf32_Off e_shoff;
Elf32_Word e_flags;
Elf32_Half e_ehsize;
Elf32_Half e_phentsize;
moneytalks
Elf32_Half e_phnum;
少儿英语学习网站
Elf32_Half e_shentsize;
Elf32_Half e_shnum;
Elf32_Half e_shstrndx;
机械设备管理制度
} Elf32_Ehdr;
定义了ELF魔数、版本、⼩端/⼤端、操作系统平台、⽬标⽂件的类型、机器结构类型、程序执⾏的⼊⼝地址、程序头表(段头表)的起始位置和长度、节头表的起始位置和长度等
其中魔数在⽂件开头的⼏个字节中,通常是⽤来确定 ⽂件的类型和格式的,加载或读取⽂件的时候可以⽤魔数来确定⽂件的类型是否正确。
a.out的魔数:01H 07H
PE格式魔数:4DH 5AH
2:.text 节
编译后的代码部分
3:.rodata 节
只读数据,如 printf 格式串、switch跳转表等
4:.data 节
已初始化的全局变量
5:.bss 节
未初始化全局变量,仅是占位符,不占据任何实际磁盘空间。区分初始化和⾮初始化是为了空间效率
6:.symtab 节
存放函数和全局变量 (符号表)信息 ,它不包括局部变量
7:. 节
.text节的重定位信息,⽤于重新修改代码段的指令中的地址信息
caucus
8:.rel.data 节
.data节的重定位信息,⽤于对被模块使⽤或定义的全局变量进⾏重定位的信息
9:.debug 节
调试⽤符号表 (gcc -g)
10:strtab 节
包含symtab和debug节中符号及节名Section header table(节头表)每个节的节名、偏移和⼤⼩
11:Section header table(节头表)
每个节的节名、偏移和⼤⼩
上⾯这些就是可重定位⽬标⽂件包含的信息了,其中Section header table(节头表)表述就是每个节所占据的地址空间⼤⼩了。
上图中就是节头表的信息举例,使⽤readelf -S test.o命令可以查看,其中Addr例表述的是每个节映射到虚拟地址的位置,因为可重定位⽬标⽂件还没有经过链接过程,所以该例都是0,经过链接过程之后才会将各个节映射到虚拟地址上去。
上述各个节中有4个节会被分配存储空间,其他的节在系统真正运⾏的时候是不会分配存储空间的。
.text:可执⾏
.data和.bss:可读可写.rodata:可读