内部资料
技术笔记
PKU/SSDB-03-TN-005
JBEOS-TN-03-005
2003 年 5 月
ELF 文件格式分析
滕启明
北京大学信息科学技术学院操作系统实验室
2003 年 5 月
声 明
本研究工作是在国家 863 计划软件重大专项《构件化嵌入式操作系统及开发环境》资助下开展的。
本报告中涉及的技术观点主要参考相关研究项目公开发表的成果,不提供任何形式、任何意义保证。
本报告仅作为内部技术交流材料使用。任何外部使用须经北京大学软件研究所授权。
摘要 嵌入式操作系统应用领域广,硬件环境复杂多样,降低开发成本、缩短开发周
期、提高产品质量是工业界和学术界共同关注的问题。借鉴软件复用的思想,
采用基于构件的软件开发思路来开发嵌入式操作系统是一条可行的途径。本文
是作者在探索系统软件构件的复用技术的过程中生成的技术笔记,重点分析了
UNIX 类操作系统中普遍采用的目标文件格式 ELF(Executable and Linkable
Format),目的是研究操作系统中二进制级软件构件的静态、动态组装技术。
本文首先介绍 ELF 文件格式规范,然后结合一个简单的 C 语言程序,分析编
译、链接后生成的可重定位、可执行格式实例。
关键词 操作系统 编译 链接 目标文件 软件构件
目 录
2.1
2.2
1 简介..................................................................................................................................... 1
2 相关标准............................................................................................................................. 1
SYSTEM V ABI........................................................................................................................................ 1
LSB ........................................................................................................................................................ 2
3 ELF文件格式 ..................................................................................................................... 2
3.1 简介........................................................................................................................................................ 2
3.1.1 目标文件中的数据表示................................................................................................................ 2
3.2 目标文件格式........................................................................................................................................ 3
3.3
ELF HEADER部分 .................................................................................................................................. 3
3.4 节区(SECTIONS) ................................................................................................................................ 6
3.4.1 节区头部表格................................................................................................................................ 6
3.4.2 节区头部 ....................................................................................................................................... 7
3.4.3 特殊节区 ..................................................................................................................................... 10
3.5 字符串表(STRING TABLE)............................................................................................................... 12
3.6 符号表(SYMBOL TABLE) ................................................................................................................. 13
3.6.1 关于st_info的说明....................................................................................................................... 13
3.6.2 符号类型 ..................................................................................................................................... 14
3.6.3 特殊的节区索引.......................................................................................................................... 15
3.6.4
STN_UNDEF符号....................................................................................................................... 15
3.6.5 符号取值 ..................................................................................................................................... 15
3.7 重定位信息.......................................................................................................................................... 16
3.7.1 重定位表项.................................................................................................................................. 16
3.7.2 重定位类型.................................................................................................................................. 17
3.8 程序加载和动态链接.......................................................................................................................... 19
3.8.1 程序头部(Program Header) ................................................................................................... 19
3.8.2 程序加载 ..................................................................................................................................... 21
3.8.3 动态链接 ..................................................................................................................................... 23
3.8.4 全局偏移表(GOT) ................................................................................................................. 27
3.8.5 过程链接表(PLT)................................................................................................................... 28
3.8.6 哈希表(Hash Table)................................................................................................................ 30
3.8.7 初始化和终止函数...................................................................................................................... 31
C库 ....................................................................................................................................................... 31
3.9.1 关于C库函数............................................................................................................................... 31
3.9.2 全局数据符号.............................................................................................................................. 33
3.9
图形目录
图 1 目标文件格式................................................................................................................................3
图 2 ELF Header数据结构 .................................................................................................................3
图 3 节区头部数据结构.......................................................................................................................7
图 4 符号表项格式定义.....................................................................................................................13
图 5 符号表项的st_info字段合成......................................................................................................13
图 6 重定位表项的格式.....................................................................................................................16
图 7 程序头部数据结构.....................................................................................................................19
图 8 注释节区示例.............................................................................................................................21
图 9 可执行文件布局示例.................................................................................................................22
图 10 动态节区符号结构...................................................................................................................24
图 11 绝对过程链接表 ........................................................................................................................28
图 12 位置独立的过程链接表...........................................................................................................29
图 13 符号哈希表的组织...................................................................................................................30
2003 年 5 月
1 简介
PKU/SSDB-03-TR-005
可执行链接格式(Executable and Linking Format)最初是由 UNIX 系统实验室(UNIX
System Laboratories,USL)开发并发布的,作为应用程序二进制接口(Application Binary
Interface,ABI)的一部分。工具接口标准(Tool Interface Standards,TIS)委员会将还
在发展的 ELF 标准选作为一种可移植的目标文件格式,可以在 32 位 Intel 体系结构上的
很多操作系统中使用[1, 2]。
ELF 标准的目的是为软件开发人员提供一组二进制接口定义,这些接口可以延伸到
多种操作环境,从而减少重新编码、重新编译程序的需要。接口的内容包括目标模块格
式、可执行文件格式以及调试记录信息与格式等。
TIS 给出的 Portable Formats Specification 1.1 版本中主要针对三种不同类型的目标
文件作了规定,并规定了程序加载与动态链接相关过程细节,给出了标准 ANSI C 和 libc
例程必须提供的符号[1]。在该组织随后发布的 Executable and Linking Format(ELF)
Specification 1.2 版本中则分如下三个部分,主要的不同点是对与操作系统相关的部分进
行了重新组织:
Book I: Executable and Linking Format,描述 ELF 目标文件格式;
Book II: Processor Specific(Intel Architecture),描述 ELF 中与硬件相关的信息;
Book III: Operating System Specific,描述 ELF 中与操作系统相关的部分,例如
System V Release 4 信息等。
2 相关标准
2.1 System V ABI
System V Application Binary Interface(ABI)为已编译的应用程序定义了系统接口,同
时也为安装脚本支持提供了一个最小环境。其目的是为应用程序提供一个标准的二进制
接 口 , 使 得 这 些 程 序 能 够 运 行 在 符 合 X/Open Commen Application Environment
Specification, Issue 4.2 和 System V Interface Definition, Fourth Edition 的操作系统上。二
进制要包含与不同处理器体系结构相关的信息,所以 ABI 并不是只有一个规范,而是
一个规范体系。System V ABI 由两个部分组成:一个通用的部分,描述 System V 在所
有硬件平台上都一致的接口[3];一个处理器相关的部分,描述特定于某个处理器体系
结构的具体实现[4]。
System V ABI 的主要参考标准包括:
目标系统处理器的体系结构手册
System V Interface Definition(接口定义), 第 4 版
X/Open Common Application Environment Specification(CAE), Issue 4.2
IEEE POSIX 1003.1-1990 标准操作系统规范
International Standard, ISO/IEC 9899:1990(E), Programming Languages – C,
12/15/90.
X Window System™, X Version 11, Release 5, 图形用户界面规范
© 北京大学信息科学技术学院操作系统实验室
第 1 页 共 38 页
2003 年 5 月
2.2 LSB
PKU/SSDB-03-TR-005
由于我们所关心的主要是 Linux 平台上目标文件的格式,所以 Linux 标准 LSB
(Linux Standard Base)也是重要的参考资料。LSB 的目标是增强不同的 Linux 发布版本之
间的兼容性,与 ABI 类似,也由两个部分组成:
gLSB(Generic LSB) 适用于所有体系结构
archLSB(Architecture Specific LSB) 特定某种体系结构的 LSB
目前,LSB 由 SourceForge 开放源码项目社区提供支持。
3 ELF 文件格式
3.1 简介
目标文件有三种类型:
可重定位文件(Relocatable File) 包含适合于与其他目标文件链接来创建可
执行文件或者共享目标文件的代码和数据。
可执行文件(Executable File) 包含适合于执行的一个程序,此文件规定了
exec() 如何创建一个程序的进程映像。
共享目标文件(Shared Object File) 包含可在两种上下文中链接的代码和数
据。首先链接编辑器可以将它和其它可重定位文件和共享目标文件一起处理,
生成另外一个目标文件。其次,动态链接器(Dynamic Linker)可能将它与某
个可执行文件以及其它共享目标一起组合,创建进程映像。
目标文件全部是程序的二进制表示,目的是直接在某种处理器上直接执行。
3.1.1 目标文件中的数据表示
目标文件格式支持 8 位字节/32 位体系结构。不过这种格式是可以扩展的,目标文
件因此以某些机器独立的格式表达某些控制数据,使得能够以一种公共的方式来识别和
解释其内容。目标文件中的其它数据使用目标处理器的编码结构,而不管文件在何种机
器上创建。
名称
Elf32_Addr
Elf32_Half
Elf32_Off
Elf32_SWord
Elf32_Word
unsigned char
表 1 ELF 中常用数据格式
大小 对齐
目的
4
2
4
4
4
1
4 无符号程序地址
2 无符号中等整数
4 无符号文件偏移
4 有符号大整数
4 无符号大整数
1 无符号小整数
目标文件中的所有数据结构都遵从“自然”大小和对齐规则。如果必要,数据结构可
以包含显式的补齐,例如为了确保 4 字节对象按 4 字节边界对齐。数据对齐同样适用于
© 北京大学信息科学技术学院操作系统实验室
第 2 页 共 38 页
PKU/SSDB-03-TR-005
2003 年 5 月
文件内部。
3.2 目标文件格式
目标文件既要参与程序链接又要参与程序执行。出于方便性和效率考虑,目标文件
格式提供了两种并行视图,分别反映了这些活动的不同需求。
图 1 目标文件格式
链接视图
ELF 头部
程序头部表(可选)
执行视图
ELF 头部
程序头部表
节区 1
...
节区 n
...
...
段 1
段 2
...
节区头部表
节区头部表(可选)
文件开始处是一个 ELF 头部(ELF Header),用来描述整个文件的组织。节区部
分包含链接视图的大量信息:指令、数据、符号表、重定位信息等等。
程序头部表(Program Header Table),如果存在的话,告诉系统如何创建进程映像。
用来构造进程映像的目标文件必须具有程序头部表,可重定位文件不需要这个表。
节区头部表(Section Heade Table)包含了描述文件节区的信息,每个节区在表中
都有一项,每一项给出诸如节区名称、节区大小这类信息。用于链接的目标文件必须包
含节区头部表,其他目标文件可以有,也可以没有这个表。
注意:尽管图中显示的各个组成部分是有顺序的,实际上除了 ELF 头部表以外,
其他节区和段都没有规定的顺序
3.3 ELF Header 部分
文件的最开始几个字节给出如何解释文件的提示信息。这些信息独立于处理器,也
独立于文件中的其余内容。ELF Header 部分可以用下图中的数据结构表示:
图 2 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;
e_phoff;
Elf32_Off
Elf32_Off
e_shoff;
© 北京大学信息科学技术学院操作系统实验室
第 3 页 共 38 页