ELF文件格式

ELF文件格式

  • ELF文件简介
  • 文件结构
  • 文件头

ELF文件简介

ELF(Executable and Linkable Format)是一种常见的二进制文件格式,用于可执行文件、共享库、目标文件等。
ELF 文件格式是一种灵活、可扩展的文件格式,被广泛用于 UNIX 和类 UNIX 操作系统。

一个 ELF 文件通常由以下几个主要部分组成:

  • 文件头(ELF Header): 文件头包含了关于 ELF 文件本身的信息,如文件类型、目标体系结构、入口点地址等。文件头是 ELF 文件的第一个部分,其长度是固定的。
  • 程序头表(Program Header Table): 程序头表描述了程序在内存中的布局。对于可执行文件,程序头表指定了如何将文件内容映射到内存;对于目标文件,它描述了程序在内存中的段的布局。
  • 段头表(Section Header Table): 段头表包含了一系列段头条目,每个条目描述了一个段的信息,如段的类型、大小、偏移等。段通常包含代码、数据、符号表等信息。
  • 数据段: 包含实际的程序数据,如代码段、数据段等。
  • 符号表: 符号表包含了程序中使用的符号的信息,如函数、变量等。符号表与调试信息相关联,用于调试和符号解析。
  • 重定位信息: 重定位信息包含了需要在链接时或加载时进行地址调整的信息,确保程序正确地连接和执行。
  • 动态链接信息: 如果 ELF 文件支持动态链接,那么它包含了动态链接器所需的信息,如共享库的位置、动态符号表等。

ELF 文件格式的灵活性使其成为多种体系结构和操作系统上的标准格式。
不同的体系结构可能会有一些特定的字段,但整体结构基本保持一致。
ELF 文件通常以 .elf、.o(目标文件)、.so(共享库)等扩展名结尾。

文件结构

常见的ELF格式如上图所示,左边为链接视图,右边为执行视图。

链接视图:
静态链接器(即编译后参与生成最终ELF过程的链接器,如ld )会以链接视图解析ELF。
编译时生成的 .o(目标文件)以及链接后的 .so (共享库)均可通过链接视图解析,链接视图可以没有段表(如目标文件不会有段表)。

执行视图:
动态链接器(即加载器,如x86架构 linux下的 /lib/ld-linux.so.2或者安卓系统下的 /system/linker均为动态链接器)会以执行视图解析ELF并动态链接。
执行视图可以没有节表。

文件头

ELF的结构声明位于系统头文件 elf.h 中,ELF格式分为32位与64位两种,除了重定位类型稍有区别,其它大致相同,为了简化描述,后续说明将省略32/64字样。

ELF Header的声明如下 :

#define EI_NIDENT (16)
typedef struct
{
    unsigned char	e_ident[EI_NIDENT];	/* Magic number and other info */
    Elf_Half		e_type;			/* Object file type */
    Elf_Half		e_machine;		/* Architecture */
    Elf_Word	        e_version;		/* Object file version */
    Elf_Addr		e_entry;		/* Entry point virtual address */
    Elf_Off		e_phoff;		/* Program header table file offset */
    Elf_Off		e_shoff;		/* Section header table file offset */
    Elf_Word	        e_flags;		/* Processor-specific flags */
    Elf_Half		e_ehsize;		/* ELF header size in bytes */
    Elf_Half		e_phentsize;		/* Program header table entry size */
    Elf_Half		e_phnum;		/* Program header table entry count */
    Elf_Half		e_shentsize;		/* Section header table entry size */
    Elf_Half		e_shnum;		/* Section header table entry count */
    Elf_Half		e_shstrndx;		/* Section header string table index */
} Elf_Ehdr;

e_ident

包含了Maigc Number和其它信息,共16字节。	
0~3:前4字节为Magic Number,固定为ELFMAG。
4(EI_CLASS):ELFCLASS32代表是32位ELF,ELFCLASS64 代表64位ELF。
5(EI_DATA):ELFDATA2LSB代表小端,ELFDATA2MSB代表大端。
6(EI_VERSION):固定为EV_CURRENT(1)。
7(EI_OSABI):操作系统ABI标识(实际未使用)。
8(EI_ABIVERSION):ABI版本(实际 未使用)。
9~15:对齐填充,无实际意义。

e_type

ELF的文件类型,定义如下:
     ET_REL		可重定位文 件(如目标文件)
     ET_EXEC	        可执行文件(可直接执行的文件)
     DT_DYN	        共享目标文件(如SO库)
     DT_CORE	        Core文件(吐核文件)
注:GCC使用编译选项 -pie 编译的可执行文件实际 也是DT_DYN类型。

other

e_machine
目标体系结构,即程序要在哪种体系结构上运行,此字段定义了目标处理器的架构。
e_verison
文件版本,目前常见的ELF 文件版本均为EV_CURRENT(1)。
e_entry
入口虚拟地址。
e_phoff
段表文件偏移。
e_shoff
节表文件偏移。
e_flags
处理器特定的标志,一般为0。
e_ehsize
Elf_Header的大小(字节)
e_phentsize
段头(Program Header)的大小(字节)。
e_phnum
段的数量。
e_shentsize
节头(Section Header)的大小(字节)。
e_shnum
字的数量。
e_shstrndx
节字符串表的节索引。

你可能感兴趣的:(Linux,ELF,文件格式)