ELF可重定位目标文件的格式

一个典型的ELF可重定位目标文件的格式如图1:

ELF可重定位目标文件的格式_第1张图片

图1 典型的ELF可重定位目标文件


ELF可重定位目标文件的格式_第2张图片

图2 可执行文件的存储器映像


ELF头以一个16字节的序列开始,描述了生成该文件的系统的字的大小和字节顺序。ELF头剩下的部分包含帮助连接器语法分析和解释目标文件的信息。其中包括ELF头的大小、目标文件的类型(如可重定位、可执行、共享的)、机器类型(如x86-64)、节头部表的文件偏移,以及节头部表中条目的大小和数量。

.text

已编译程序的机器代码

.rodata

只读数据

.data

已初始化的全局和静态C变量。局部C变量在运行时被保存在栈中,既不出现在.data节中,也不出现在.bss节中。

.bss

未初始化的全局和静态C变量,以及所有被初始化为0的全局或静态变量。在目标文件中这个节不占据实际的空间,它仅仅是一个占位符。目标文件格式区分已初始化和未初始化变量是为了空间效率:在目标文件中,未初始化变量不需要占据任何实际的磁盘空间。运行时,在内存中分配这些变量,初始值为0.


$ readelf -h HelloWorld
ELF Header:
  Magic:   7f 45 4c 46 02 01 01 03 00 00 00 00 00 00 00 00               魔数
  Class:                           ELF64			         分类
  Data:                            2's complement, little endian	 数据表示:补码、小端
  Version:                         1 (current)		                 版本号
  OS/ABI:                          UNIX – Linux		                 Linux的ABI
  ABI Version:                     0			                 ABI版本
  Type:                            EXEC (Executable file)	         类型:可执行文件
  Machine:                         Advanced Micro Devices X86-64         硬件平台:AMD x86-64
  Version:                         0x1			                 版本号
  Entry point address:             0x4003e0	                         程序入口地址
  Start of program headers:        64 (bytes into file)	                 程序头表的位置
  Start of section headers: 	   2472 (bytes into file)	         节头表的位置
  Flags:                           0x0			                 标志
  Size of this header:             64 (bytes)	                         文件头的大小:64字节
  Size of program headers:         56 (bytes)		                 程序头表项的大小:56字节
  Number of program headers:       8		                         程序头表项的数目:8项
  Size of section headers:         64 (bytes)		
  Number of section headers:         	 30		                 节头表项的大小30字节
  Section header string table index: 	 27		                 节头表的项数目:27项
ELF可重定位目标文件的格式_第3张图片
图3

.symtab 节
符号表
过程和静态变量名

节名和位置

.rel.text 节
文本部分的重新定位信息
在可执行文件中需要修改的指令的地址

修改指令

.rel.data 节
数据段的重新定位信息

在合并的可执行文件中需要修改的指针数据的地址

.debug 节

符号调试信息(gcc -g)

.line

初始C源程序中的行号和.text节中机器指令之间的映射。只有以-g选项调用编译器驱动程序时,才会得到这张表。

.srttab

一个字符串表

以null结尾的字符串序列

节头表
每节的偏移和大小

PS:为什么未初始化的数据称为.bss ?

用术语.bss来表示未初始化的数据是很普遍的,它起始于IBM704汇编语言中“块存储开始(Block Storage Start)”指令的首字母缩写,并沿用至今。一种记住.bata和.bss节之间区别的简单方法是吧“bss”看成是"更好的节省空间(Better Save Space)"的缩写。


本篇内容出自《深入理解计算机系统》第三版的第七章 链接7.4可重定位目标文件

原著《Computer Systems A Programmer's Perspective Third Edition》【美】Randal E.Bryant 【美】David R.O'Hallaron

你可能感兴趣的:(#,Linux)