ELF文件的结构如下图所示:

ELF文件由4部分组成,分别是ELF头(ELF header)、程序头表(Program header table)、节(Sections)和节头表(Section header table)。

实际上,一个文件中不一定包含全部这些内容,而且它们的位置也未必如上图所示这样安排,只有ELF头的位置是固定的,其余各部分的位置、大小等信息由ELF头中的各项值来决定。

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_Haif e_ehsize;
Elf32_Haif e_phentsize;
Elf32_Haif e_phnum;
Elf32_Haif e_shentsize;
Elf32_Haif e_shnum;
Elf32_Haif e_shstrndx;
}Elf32_Ehdr;

其中各类型的说明见下表,由于ELF文件力求支持从8位到32位不同架构的处理器,所以才定义了下表中这些数据类型,从而让文件格式与机器无关。

下面看一下ELF header中各项的意义。foobar文件:

最开头是16字节的e_ident,其中包含用以表示ELF文件的字符,以及其他一些与机器无关的信息。

开头的4字节是固定不变的,第1个字节值为0x7F,紧跟着就是ELF三个字符,这4字节表明这个文件是个ELF文件。

1.e_type——标识的是该文件的类型,取值就不一一列出了。文件foobar的e_type是2,表明它是一个可执行文件。

2.e_machine——foobar中此项的值为3,表明运行该程序需要的体系结构为Intel 80386.

3.e_version——文件的版本。

4.e_entry——程序的入口地址。文件foobar的入口地址为0x80480A0.

5.e_phoff——Program header table在文件中的偏移量(以字节计数),这里的值是0x34.

6.e_shoff——Section header table在文件中的偏移量(以字节计数),这里的值是0x1C0.

7.e_flags——对IA32而言,此项为0.

8.e_ehsize——ELF header大小(以字节计数),这里值为0x34.

9.e_phentsize——Program header table中每一个条目(一个Program header)的大小。这里值为0x20.

10.e_phnum——Program header table中有多少个条目,这里有3个。

11.e_shentsize——Section header table中每一个条目(一个Section header)的大小,这里值为0x28.

12.e_shnum——Section header table中有多少个条目,这里有6个。

13.e_shstrndx——包含节名称的字符串表是第几个节(从零开始数)。这里值为5,表示第5个节包含节名称。

我们看到,Program header table在文件中的偏移量(e_phoff)为0x34,而ELF header大小(e_ehsize)也是0x34,可见ELF header后面紧接着就是Program header table。Program header数据结构如下:

typedef struct{
Elf32_Word p_type;
Elf32_Off p_offset;
Elf32_Addr p_vaddr;
Elf32_Addr p_paddr;
Elf32_Word p_filesz;
Elf32_Word p_memsz;
Elf32_Word p_flags;
Elf32_Word p_align;
}Elf32_Phdr;

实际上Program header描述的是系统准备程序运行所需的一个段或其他信息。程序头表中共有三项(e_phnum=3),偏移分别是0x34~0x53、0x54~0x73和0x74~0x93.

1.p_type——当前Program header所描述的段的类型。

2.p_offset——段的第一个字节在文件中的偏移。

3.p_vaddr——段的第一个字节在内存中的虚拟地址。

4.p_paddr——在物理地址定位相关的系统中,此项是为物理地址保留。

5.p_filesz——段在文件中的长度。

6.p_memsz——段在内存中的长度。

7.p_flags——与段相关的标志。

8.p_align——根据此项值来确定段在文件以及内存中如何对齐。

Program header描述的是一个段在文件中的位置、大小以及它被放进内存后所在的位置和大小。如果我们想把一个文件加载进内存的话,需要的正是这些信息。

在foobar中共有三个Program header,其取值如下表所示:

根据这些信息,我们很容易知道foobar在加载进内存之后的情形,如下图:

最新文章

  1. PHP是怎么运行的
  2. Windows on Device 项目实践 4 - 智能风扇制作
  3. 顺序表java实现
  4. 安全测试及B/S C/S安全性比较
  5. 基于华清远见STM32f051的 IIC从模式实现方法
  6. JSCapture – 基于 HTML5 实现的屏幕捕捉库
  7. [20160701]DevideByZeroWithoutNoException——from 《Java How To Program (Early Objects), 10th》
  8. 使用Jquery解析Json基础知识
  9. postfix反垃圾邮件说明
  10. Node.js模块os
  11. iTOP-4418开发板所用核心板研发7寸/10.1寸安卓触控一体机
  12. 【Java并发.5】基础构建模块
  13. 安卓开发helloworld
  14. [PyData] 01 - Web Crawler
  15. 一道很好的mysql面试练习题,having综合应用
  16. DOM增删改操作
  17. js innerHTML 改变div内容的方法
  18. 连接oracle服务器超慢--原因分析
  19. python教程(三)·自定义函数
  20. sqlserver索引维护(重新组织生成索引)

热门文章

  1. 高性能ORM 框架之 MySqlSugar
  2. noip模拟赛 好元素 哈希表的第一题
  3. MYSQL 函数 字符串到整数
  4. max server memory
  5. 前端代码标准最佳实践:CSS
  6. 使用VS Code开发ASP.NET Core 应用程序
  7. C# 委托和事件(一):最简单的委托和事件
  8. 【阿炬Android笔记】01、调用VitamioBundle播放窗口
  9. jquery基本选择器id
  10. Struts 2.3.24源码解析+Struts2拦截参数,处理请求,返回到前台过程详析