ELF文件格式及程序加载执行过程总汇(2)ELF Header


========================== ELF Header ========================== 


一些object文件的控制结构能够增长的,所以ELF头包含了他们目前的大小。 
假如object文件格式改变,程序可能会碰到或大或小他们不希望的控制结构。 
程序也有可能忽略额外(extra)的信息。 
对待来历不明(missing)的信息依靠上下文来解释,假如扩展被定义,它们 
将会被指定。 

+ 图 1-3: ELF Header 

#define EI_NIDENT 16 

typedef struct { 
unsigned char e_ident[EI_NIDENT]; 
Elf32_Half e_type; 
Elf32_Half e_machine; 
Elf32_Word e_version; 
Elf32_Addr e_entry; 
Elf32_Off e_phoff; 
Elf32_Off e_shoff; 
Elf32_Word e_flags; 
Elf32_Half e_ehsize; 
Elf32_Half e_phentsize; 
Elf32_Half e_phnum; 
Elf32_Half e_shentsize; 
Elf32_Half e_shnum; 
Elf32_Half e_shstrndx; 
} Elf32_Ehdr; 

* e_ident 

这个最初的字段标示了该文件为一个object文件,提供了一个机器无关 
的数据,解释文件的内容。在下面的ELF的鉴别(ELF Identification) 
部分有更详细的信息。 

* e_type 

该成员确定该object的类型。 

Name Value Meaning 
==== ===== ======= 
ET_NONE 0 No file type 
ET_REL 1 Relocatable file 
ET_EXEC 2 Executable file 
ET_DYN 3 Shared object file 
ET_CORE 4 Core file 
ET_LOPROC 0xff00 Processor-specific 
ET_HIPROC 0xffff Processor-specific 

虽然CORE的文件内容未被指明,类型ET_CORE是保留的。 
值从 ET_LOPROC 到 ET_HIPROC(包括ET_HIPROC)是为特殊的处理器保留的。 
如有需要,其他保留的变量将用在新的object文件类型上。 

* e_machine 

该成员变量指出了运行该程序需要的体系结构。 

Name Value Meaning 
==== ===== ======= 
EM_NONE 0 No machine 
EM_M32 1 AT&T WE 32100 
EM_SPARC 2 SPARC 
EM_386 3 Intel 80386 
EM_68K 4 Motorola 68000 
EM_88K 5 Motorola 88000 
EM_860 7 Intel 80860 
EM_MIPS 8 MIPS RS3000 

如有需要,其他保留的值将用到新的机器类型上。特殊处理器名使用机器名来 
区别他们。例如,下面将要被提到的成员flags使用前缀EF_;在一台EM_XYZ机器 
上,flag称为WIDGET,那么就称为EF_XYZ_WIDGET。 

* e_version 

这个成员确定object文件的版本。 

Name Value Meaning 
==== ===== ======= 
EV_NONE 0 Invalid version 
EV_CURRENT 1 Current version 

值1表示原来的文件格式;创建新版本就用>1的数。EV_CURRENT值(上面给 
出为1)如果需要将指向当前的版本号。 

* e_entry 

该成员是系统第一个传输控制的虚拟地址,在那启动进程。假如文件没有 
如何关联的入口点,该成员就保持为0。 

* e_phoff 

该成员保持着程序头表(program header table)在文件中的偏移量(以字节计数)。 
假如该文件没有程序头表的的话,该成员就保持为0。 

* e_shoff 

该成员保持着section头表(section header table)在文件中的偏移量(以字节 
计数)。假如该文件没有section头表的的话,该成员就保持为0。 

* e_flags 

该成员保存着相关文件的特定处理器标志。 
flag的名字来自于EF__。看下机器信息“Machine Information” 
部分的flag的定义。 

* e_ehsize 

该成员保存着ELF头大小(以字节计数)。 

* e_phentsize 

该成员保存着在文件的程序头表(program header table)中一个入口的大小 
(以字节计数)。所有的入口都是同样的大小。 

* e_phnum 

该成员保存着在程序头表中入口的个数。因此,e_phentsize和e_phnum 
的乘机就是表的大小(以字节计数).假如没有程序头表(program header table), 
e_phnum变量为0。 

* e_shentsize 

该成员保存着section头的大小(以字节计数)。一个section头是在section 
头表(section header table)的一个入口;所有的入口都是同样的大小。 

* e_shnum 

该成员保存着在section header table中的入口数目。因此,e_shentsize和 
e_shnum的乘积就是section头表的大小(以字节计数)。 
假如文件没有section头表,e_shnum值为0。 

* e_shstrndx 

该成员保存着跟section名字字符表相关入口的section头表(section header 
table)索引。假如文件中没有section名字字符表,该变量值为SHN_UNDEF。 
更详细的信息 看下面“Sections”和字符串表(“String Table”) 。 


ELF 鉴别(Identification) 

在上面提到的,ELF提供了一个object文件的框架结构来支持多种处理机,多 
样的数据编码方式,多种机器类型。为了支持这个object文件家族,最初的几 
个字节指定用来说明如何解释该文件,独立于处理器,与文件剩下的内容无关。 

ELF头(也就是object文件)最初的几个字节与成员e_ident相一致。 

+ 图 1-4: e_ident[] Identification Indexes 

Name Value Purpose 
==== ===== ======= 
EI_MAG0 0 File identification 
EI_MAG1 1 File identification 
EI_MAG2 2 File identification 
EI_MAG3 3 File identification 
EI_CLASS 4 File class 
EI_DATA 5 Data encoding 
EI_VERSION 6 File version 
EI_PAD 7 Start of padding bytes 
EI_NIDENT 16 Size of e_ident[] 

通过索引访问字节,以下的变量被定义。 

* EI_MAG0 to EI_MAG3 

文件的前4个字符保存着一个魔术数(magic number),用来确定该文件是否 
为ELF的目标文件。 

Name Value Position 
==== ===== ======== 
ELFMAG0 0x7f e_ident[EI_MAG0] 
ELFMAG1 ‘E‘ e_ident[EI_MAG1] 
ELFMAG2 ‘L‘ e_ident[EI_MAG2] 
ELFMAG3 ‘F‘ e_ident[EI_MAG3] 

* EI_CLASS 

接下来的字节是e_ident[EI_CLASS],用来确定文件的类型或者说是能力。 

Name Value Meaning 
==== ===== ======= 
ELFCLASSNONE 0 Invalid class 
ELFCLASS32 1 32-bit objects 
ELFCLASS64 2 64-bit objects 

文件格式被设计成在不同大小机器中可移植的,在小型机上的不用大型机上 
的尺寸。类型ELFCLASS32支持虚拟地址空间最大可达4GB的机器;使用上面 
定义过的基本类型。 

类型ELFCLASS64为64位体系的机器保留。它的出现表明了object文件可能 
改变,但是64位的格式还没有被定义。如果需要,其他类型将被定义,会 
有不同的类型和不同大小的数据尺寸。 

* EI_DATA 

字节e_ident[EI_DATA]指定了在object文件中特定处理器数据的编码 
方式。当前定义了以下编码方式。 

Name Value Meaning 
==== ===== ======= 
ELFDATANONE 0 Invalid data encoding 
ELFDATA2LSB 1 See below 
ELFDATA2MSB 2 See below 

更多的关于编码的信息出现在下面。其他值保留,将被分配一个新的编码 
方式,当然如果必要的话。 

* EI_VERSION 

字节e_ident[EI_VERSION]表明了ELF头的版本号。 
现在这个变量的是一定要设为EV_CURRENT,作为上面e_version的解释。 

* EI_PAD 

该变量标识了在e_ident中开始的未使用的字节。那些字节保留并被设置为 
0;程序把它们从object 文件中读出但应该忽略。假如当前未被使用的字节 
有了新的定义,EI_PAD变量将来会被改变。 

一个文件的数据编码指出了如何来解释一个基本的object文件。在上述的 
描述中,类型ELFCLAS32文件使用占用1,2和4字节的目标文件。下面定义的 
编码方式,用下面的图来描绘。数据出现在左上角。 


ELFDATA2LSB编码指定了2的补数值。 
最小有意义的字节占有最低的地址。 

+ 图1-5: Data Encoding ELFDATA2LSB 

0------+ 
0x0102 | 01 | 
+------+ 
0------1------+ 
0x010204 | 02 | 01 | 
+------+------+ 
0------1------2------3------+ 
0x01020304 | 04 | 03 | 02 | 01 | 
+------+------+------+------+ 

ELFDATA2LSB编码指定了2的补数值。 
最大有意义的字节占有最低的地址。 

+ 图1-6: Data Encoding ELFDATA2MSB 

0------+ 
0x0102 | 01 | 
+------+ 
0------1------+ 
0x010204 | 01 | 02 | 
+------+------+ 
0------1------2------3------+ 
0x01020304 | 01 | 02 | 03 | 04 | 
+------+------+------+------+ 


机器信息 

为了确定文件,32位Intel体系结构的需要以下的变量。 

+ 图1-7: 32-bit Intel Architecture Identification, e_ident 

Position Value 
======== ===== 
e_ident[EI_CLASS] ELFCLASS32 
e_ident[EI_DATA] ELFDATA2LSB 

处理器确认ELF头里的e_machine成员,该成员必须为EM_386。 

ELF报头里的e_flags成员保存了和文件相关的位标记。32位Intel体系上未 
定义该标记;所以这个成员应该为0; 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值