Linux系统下的ELF文件格式

上传人:jiups****uk12 文档编号:38440270 上传时间:2018-05-02 格式:DOCX 页数:6 大小:45.53KB
返回 下载 相关 举报
Linux系统下的ELF文件格式_第1页
第1页 / 共6页
Linux系统下的ELF文件格式_第2页
第2页 / 共6页
Linux系统下的ELF文件格式_第3页
第3页 / 共6页
Linux系统下的ELF文件格式_第4页
第4页 / 共6页
Linux系统下的ELF文件格式_第5页
第5页 / 共6页
点击查看更多>>
资源描述

《Linux系统下的ELF文件格式》由会员分享,可在线阅读,更多相关《Linux系统下的ELF文件格式(6页珍藏版)》请在金锄头文库上搜索。

1、1 1 引言引言ELF(Executable and Linkable Format)即可执行连接文件格式,是 Linux,SVR4 和 Solaris2.0 默认的目标文件格式,目前标准接口委员会 TIS 已将 ELF 标准化为一种可移植的目标文件格式,运行于 32-bit Intel 体系微机上,可与多种操作系统兼容。分析 elf 文件有助于理解一些重要的系统概念,例如程序的编译和链接,程序的加载和运行等2 2 ELFELF 文件格式文件格式2.1 ELF 文件的类型ELF 文件主要有三种类型:(1)可重定位文件包含了代码和数据可与其它 ELF 文件建立一个可执行或共享的文件:(2)可执行

2、文件时可直接执行的程序:(3)共享目标文件包括代码和数据,可以在两个地方链接。第一,连接器可以把它和其它可重定位文件和共享文件一起处理以建立另一个 ELF 文件;第二,动态链接器把它和一个可执行文件和其它共享文件结合在一起建立一个进程映像。2.2 ELF 文件的组织ELF 文件参与程序的连接(建立一个程序)和程序的执行(运行一个程序),编译器和链接器将其视为节头表(section header table)描述的一些节(section)的集合,而加载器则将其视为程序头表(program header table)描述的段(segment)的集合,通常一个段可以包含多个节。可重定位文件都包含一个

3、节头表,可执行文件都包含一个程序头表。共享文件两者都包含有。为此,ELF 文件格式同时提供了两种看待文件内容的方式,反映了不同行为的不同要求。下图显示了 ELF 文件的组织。2.3 文件头(Elf header)Elf 头在程序的开始部位,作为引路表描述整个 ELF 的文件结构,其信息大致分为四部分:一是系统相关信息,二是目标文件类型,三是加载相关信息,四是链接相关信息 其中系统相关信息包括 elf 文件魔数(标识 elf 文件),平台位数,数据编码方式,elf 头部版本,硬件平台 e_machine,目标文件版本 e_version,处理器特定标志 e_ftags:这些信息的引入极大增强了

4、elf 文件的可移植性,使交叉编译成为可能。目标文件类型用 e_type 的值表示,可重定位文件为 1,可执行文件为 2,共享文件为 3;加载相关信息有:程序进入点 e_entry程序头表偏移量 e_phoff,elf 头部长度 e_ehsize,程序头表中一个条目的长度 e_phentsize,程序头表条目数目 e_phnum;链接相关信息有:节头表偏移量 e_shoff,节头表中一个条目的长度 e_shentsize,节头表条目个数 e_shnum ,节头表字符索引 e shstmdx。可使用 readelf -h filename 来察看文件头的内容。文件头的数据结构如下:typedef

5、 struct elf32_hdrunsigned char e_identEI_NIDENT;Elf32_Half e_type;/目标文件类型Elf32_Half e_machine;/硬件平台Elf32_Word e_version;/elf 头部版本Elf32_Addr e_entry;/程序进入点Elf32_Off e_phoff;/程序头表偏移量Elf32_Off e_shoff;/节头表偏移量Elf32_Word e_flags;/处理器特定标志Elf32_Half e_ehsize;/elf 头部长度Elf32_Half e_phentsize;/程序头表中一个条目的长度Elf

6、32_Half e_phnum;/程序头表条目数目Elf32_Half e_shentsize;/节头表中一个条目的长度Elf32_Half e_shnum;/节头表条目个数Elf32_Half e_shstrmdx;/节头表字符索引Elf32_Ehdr;2.4 程序头表(program header table)程序头表告诉系统如何建立一个进程映像它是从加载执行的角度来看待 elf 文件从它的角度看elf 文件被分成许多段,elf 文件中的代码、链接信息和注释都以段的形式存放。每个段都在程序头表中有一个表项描述,包含以下属性:段的类型,段的驻留位置相对于文件开始处的偏移,段在内存中的首字节地

7、址,段的物理地址,段在文件映像中的字节数段在内存映像中的字节数,段在内存和文件中的对齐标记。可用 readelf -l filename 察看程序头表中的内容。程序头表的结构如下:typedef struct elf32_phdrElf32_Word p_type; /段的类型Elf32_Off p_offset; /段的位置相对于文件开始处的偏移Elf32_Addr p_vaddr; /段在内存中的首字节地址Elf32_Addr p_paddr;/段的物理地址Elf32_Word p_filesz;/段在文件映像中的字节数Elf32_Word p_memsz;/段在内存映像中的字节数Elf3

8、2_Word p_flags;/段的标记Elf32_Word p_align;,/段在内存中的对齐标记)Elf32_Phdr;2.5 节头表(section header table)节头表描述程序节,为编译器和链接器服务。它把 elf 文件分成了许多节每个节保存着用于不同目的的数据这些数据可能被前面的程序头重复使用,完成一次任务所需的信息往往被分散到不同的节里。由于节中数据的用途不同,节被分成不同的类型,每种类型的节都有自己组织数据的方式。每一个节在节头表中都有一个表项描述该节的属性,节的属性包括小节名在字符表中的索引,类型,属性,运行时的虚拟地址,文件偏移,以字节为单位的大小,小节的对齐等

9、信息,可使用 readelf -S filename 来察看节头表的内容。节头表的结构如下:typedef structElf32_Word sh_name;/小节名在字符表中的索引E1t32_Word sh_type;/小节的类型Elf32_Word sh_flags;/小节属性Elf32_Addr sh_addr; /小节在运行时的虚拟地址Elf32_Off sh_offset;/小节的文件偏移Elf32_Word sh_size;/小节的大小以字节为单位Elf32_Word sh_link;/链接的另外一小节的索引Elf32 Word sh_info;/附加的小节信息Elf32 Word

10、 sh_addralign;/小节的对齐Elf32 Word sh_entsize; /一些 sections 保存着一张固定大小入口的表。就像符号表Elf32_Shdr;3 3 ELFELF 的特性的特性3.1 平台相关在 ELF 文件头中包含了足够的平台相关信息,如数据编码方式,平台位数,硬件平台 e_machine 等,这些平台相关信息可在编译由编译器决定。例如,与平台位数的相关的数据结构的定义在 elf.h 的头文件中在编译预处理时确定:#if ELF CLASS=ELFCLASS32extern Elf32_Dyn_DYNAMIC;#define elfhdr elf32_hdr;#

11、define elf_phdr elf32_phdr;#define elf_note elf32_note;#elseextern Elf64_Dyn_DYNAMIC;#define elfhdr elf64_hdr;#define elf_phdr elf64_phdr;#define elf_note elf64_note;#endiflinux 系统加载 ELF 可执行文件时,必须首先做一些简单的一致性检查其代码如下if(memcmp(elf_ex.e_ident,ELFMAG,SELFMAG)!=0)goto out; /检查文件头开始四个字符是否为 ELF 魔数0177ELFif(

12、elf_ex.e_type!=ET_EXEC/检查文件类型是否为可执行文件或共享目标文件if(!elf_check_arch(/检查硬件平台是否一致其中的 elf_check_arch(x)在不同的硬件平台上有不同的定义,其由系统的硬件平台决定。这样,在硬件平台相同的系统上,ELF 可以不作修改的执行。因此,它可以支持不同平台上的交叉编译(cross_compilation)和交叉链接(cross_linking)。3.2 PICELF 可以生成一种特殊的代码与位置无关的代码(position-independent code,PIC)。用户对 gcc 使用-fPIC 指示 GNU 编译系统生

13、成 PIC 代码。它是实现共享库或共享可执行代码的基础这种代码的特殊性在于它可以加载到内存地址空间的任何地址执行这也是加载器可以很方便的在进程中动态链接共享库。PIC 的实现运用了一个事实,就是代码段中任何指令和数据段中的任何变量之间的距离都是一个与代码段和数据段的绝对存储器位置无关的常量。因此,编译器在数据段开始的地方创建了一个表叫做全局偏移量表(global offset tableGOT)。GOT 包含每个被这个目标模块引用的全局数据目标的表目。编译器还为 GOT 中每个表目生成一个重定位记录。在加载时,动态链接器会重定位 GOT 中的每个表目,使得它包含正确的绝对地址。PIC 代码在代

14、码中实现通过 GOT 间接的引用每个全局变量,这样,代码中本来简单的数据引用就变得复杂,必须加入得到 GOT 适当表目内容的指令。对只读数据的引用也根据同样的道理,所以,加上 IC 编译成的代码比一般的代码开销大。如果一个 elf 可执行文件需要调用定义在共享库中的任何函数,那么它就有自己的 GOT 和PLT(procedure linkage table,过程链接表)这两个节之间的交互可以实现延迟绑定(lazy binging),这种方法将过程地址的绑定推迟到第一次调用该函数。为了实现延迟绑定,GOT 的头三条表目是特殊的:GOT0包含.dynamic 段的地址,.dynamic 段包含了动

15、态链接器用来绑定过程地址的信息,比如符号的位置和重定位信息;GOT1包含动态链接器的标识;GOT2包含动态链接器的延迟绑定代码的入口点。GOT 的其他表目为本模块要引用的一个全局变量或函数的地址。PLT 是一个以 16 字节(32 位平台中)表目的数组形式出现的代码序列。其中 PLT0是一个特殊的表目,它跳转到动态链接器中执行;每个定义在共享库中并被本模块调用的函数在 PLT 中都有一个表目,从 PLT1开始模块对函数的调用会转到相应 PLT 表目中执行,这些表目由三条指令构成。第一条指令是跳转到相应的 GOT 存储的地址值中第二条指令把函数相应的 ID 压入栈中,第三条指令跳转到 PLTO中

16、调用动态链接器解析函数地址,并把函数真正地址存入相应的 GOT 表目中。被调用函数 GOT 相应表目中存储的最初地址为相应 PLT 表目中第二条指令的地址值,函数第一次被调用后GOT 表目中的值就为函数的真正地址。因此,第一次调用函数时开销比较大但是其后的每次调用都只会花费一条指令和一个间接的存储器引用。3.3 强大的工具支持由于 gnu 由大量的工具支持 elf 文件个时 随着 gnu 工具的功能的扩展程序员对 ELF 文件的运用也越来越灵活。例如,在 C+中全局的构造函数和析构函数必须非常小心的处理碰到的语言规范问题。构造函数必须在 main 函数之前被调用。析构函数必须在 main 函数返回之后被调用。ELF 文件格式中,定义了两个特殊的节(section),.init 和.fini,.init 保存着可执行指令,它构成了进程的初始化代码。当一个程序开始运行时,在 main 函数被调用之前(c 语言称为 mai

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 行业资料 > 其它行业文档

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号