ELF⽂件格式详解ARM的可执⾏⽂件的格式是ELF格式⽂件,下⽂对ELF格式做个详细的介绍。线粒体功能
序⾔
1. OBJECT⽂件
导⾔
ELF头(ELF Header)
Sections
西红柿炒蛋String表(String Table)
Symbol表(Symbol Table)
重定位(Relocation)
2. 程序装载与动态连接
导⾔
Program头(Program Header)
Program装载(Program Loading)
Dynamic连接(Dynamic Linking)
3. C LIBRARY
C Library
________________________________________________________________
导⾔
________________________________________________________________
ELF: 可执⾏连接格式
可执⾏连接格式是UNIX系统实验室(USL)作为应⽤程序⼆进制接⼝
(Application Binary Interface(ABI)⽽开发和发布的。⼯具接⼝标准委
员会(TIS)选择了正在发展中的ELF标准作为⼯作在32位INTEL体系上不同操
作系统之间可移植的⼆进制⽂件格式。
假定开发者定义了⼀个⼆进制接⼝集合,ELF标准⽤它来⽀持流线型的软件
发展。应该减少不同执⾏接⼝的数量。因此可以减少重新编程重新编译的
代码。
关于这⽚⽂档
这篇⽂档是为那些想创建⽬标⽂件或者在不同的操作系统上执⾏⽂件的开发
着准备的。它分以下三个部分:
* 第⼀部分, “⽬标⽂件Object Files”描述了ELF⽬标⽂件格式三种主要
的类型。
* 第⼆部分, “程序转载和动态连接”描述了⽬标⽂件的信息和系统在创建
运⾏时程序的⾏为。
* 第三部分, “C 语⾔库”列出了所有包含在libsys中的符号,标准的ANSI C
和libc的运⾏程序,还有libc运⾏程序所需的全局的数据符号。
注意: 参考的X86体系已经被改成了Intel体系。
________________________________________________________________
1. ⽬标⽂件(Object file)
________________________________________________________________ ========================= 序⾔ =========================
第⼀部分描述了iABI的object⽂件的格式, 被称为ELF(Executable
and Linking Format). 在object⽂件中有三种主要的类型。
* ⼀个可重定位(relocatable)⽂件保存着代码和适当的数据,⽤来和其他的
object⽂件⼀起来创建⼀个可执⾏⽂件或者是⼀个共享⽂件。
* ⼀个可执⾏(executable)⽂件保存着⼀个⽤来执⾏的程序;该⽂件指出了
exec(BA_OS)如何来创建程序进程映象。
* ⼀个共享object⽂件保存着代码和合适的数据,⽤来被下⾯的两个链接器
链接。第⼀个是连接编辑器[请参看ld(SD_CMD)],可以和其他的可重定位和
共享object⽂件来创建其他的object。第⼆个是动态链接器,联合⼀个
可执⾏⽂件和其他的共享object⽂件来创建⼀个进程映象。
⼀个object⽂件被汇编器和联接器创建, 想要在处理机上直接运⾏的object
⽂件都是以⼆进制来存放的。那些需要抽象机制的程序,⽐如象shell脚本,
是不被接受的。
在介绍性的材料过后,第⼀部分主要围绕着⽂件的格式和关于如何建⽴程序。
第⼆部分也描述了object⽂件的⼏个组成部分,集中在执⾏程序所必须的信息上。
哈密瓜怎么保存
⽂件格式
Object⽂件参与程序的联接(创建⼀个程序)和程序的执⾏(运⾏⼀个程序)。
object ⽂件格式提供了⼀个⽅便有效的⽅法并⾏的视⾓看待⽂件的内容,
在他们的活动中,反映出不同的需要。例 1-1图显⽰了⼀个object⽂件的
组织图。
+ 图1-1: Object⽂件格式
Linking 视⾓ Execution 视⾓
============ ==============
ELF header ELF header
Program header table (optional) Program header table
Section 1 Segment 1
.
.. Segment 2
Section n ...
Section header table Section header table (optional)
⼀个ELF头在⽂件的开始,保存了路线图(road map),描述了该⽂件的组织情况。ctions保存着object ⽂件的信息,从连接⾓度看:包括指令,数据,
符号表,重定位信息等等。特别ctions的描述会出项在以后的第⼀部分。
第⼆部分讨论了段和从程序的执⾏⾓度看⽂件。
假如⼀个程序头表(program header table)存在,那么它告诉系统如何来创建⼀
个进程的内存映象。被⽤来建⽴进程映象(执⾏⼀个程序)的⽂件必须要有⼀个程
序头表(program header table);可重定位⽂件不需要这个头表。⼀个
ction头表(ction header table)包含了描述⽂件ctions的信息。每个ction在这个表中有⼀个⼊⼝;每个⼊⼝给出了该ction的名字,⼤⼩,
等等信息。在联接过程中的⽂件必须有⼀个ction头表;其他object⽂件可要
可不要这个ction头表。
注意: 虽然图显⽰出程序头表⽴刻出现在⼀个ELF头后,ction头表跟着其他ction部分出现,事实是的⽂件是可以不同的。此外,ctions和段(gments)没有特别的顺序。只有ELF头(elf header)是在⽂件的固定位置。
数据表⽰
object⽂件格式⽀持8位、32位不同的处理器。不过,它试图努⼒的在更⼤
或更⼩的体系上运⾏。因此,object⽂件描绘⼀些控制数据需要⽤与机器
⽆关的格式,使它尽可能的⽤⼀般的⽅法甄别object⽂件和描述他们的内容。
在object⽂件中剩余的数据使⽤⽬标处理器的编码⽅式,不管⽂件是在哪台
机⼦上创建的。
+ 图 1-2: 32-Bit Data Types
Name Size Alignment Purpo
兰花园==== ==== ========= =======
Elf32_Addr 4 4 Unsigned program address
Elf32_Half 2 2 Unsigned medium integer
Elf32_Off 4 4 Unsigned file offt
Elf32_Sword 4 4 Signed large integer
Elf32_Word 4 4 Unsigned large integer
unsigned char 1 1 Unsigned small integer
所有的object⽂件格式定义的数据结构是⾃然⼤⼩(natural size),为相关
的类型调整指针。如果需要,数据结构中明确的包含了确保4字节对齐的填
充字段。来使结构⼤⼩是4的倍数。数据从⽂件的开始也有适当的对齐。
例如,⼀个包含了Elf32_Addr成员的结构将会在⽂件内对齐到4字节的边界上。
因为移植性的原因,ELF不使⽤位字段。
========================== 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
该成员保持着ction头表(ction header table)在⽂件中的偏移量(以字节
计数)。假如该⽂件没有ction头表的的话,该成员就保持为0。
* e_flags
该成员保存着相关⽂件的特定处理器标志。
flag的名字来⾃于EF_<machine>_<flag>。看下机器信息“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
该成员保存着ction头的⼤⼩(以字节计数)。⼀个ction头是在ction
头表(ction header table)的⼀个⼊⼝;所有的⼊⼝都是同样的⼤⼩。
* e_shnum
该成员保存着在ction header table中的⼊⼝数⽬。因此,e_shentsize和
e_shnum的乘积就是ction头表的⼤⼩(以字节计数)。
假如⽂件没有ction头表,e_shnum值为0。