嵌入式与Linux那些事

电子技术应用专栏作家——嵌入式与Linux那些事。关注嵌入式与Linux的校招社招,本人整理了《嵌入式软件工程师笔试面试指南》PDF,平时发布嵌入式与Linux相关的实用技术文章

剖析一下ELF文件

0
阅读(1764)

关于计算机的文件有很多种,今天分享一种用于二进制文件、可执行文件、目标代码、共享库和核心转储格式文件。

一、ELF文件简介

ELF:Executable and Linkable Format,可执行与可链接格式。

首先,你需要知道的是所谓对象文件(Object files)有三个种类:

1)可重定向文件:文件保存着代码和适当的数据,用来和其他的目标文件一起来创建一个可执行文件或者是一个共享目标文件。(目标文件或者静态库文件,即通常后缀为.a和.o的文件)

2)可执行文件:文件保存着一个用来执行的程序。(例如bash,gcc等)

3)共享目标文件:共享库。文件保存着代码和合适的数据,用来被下连接编辑器和动态链接器链接。

二、ELF文件格式

首先,ELF文件格式提供了两种视图,分别是链接视图和执行视图。

  image.png

 链接视图是以节(section)为单位,执行视图是以段(segment)为单位。链接视图就是在链接时用到的视图,而执行视图则是在执行时用到的视图。上图左侧的视角是从链接来看的,右侧的视角是执行来看的。总个文件可以分为四个部分:

ELF header:描述整个文件的组织。

Program Header Table: 描述文件中的各种segments,用来告诉系统如何创建进程映像的。

sections 或者 segments:segments是从运行的角度来描述elf文件,sections是从链接的角度来描述elf文件,也就是说,在链接阶段,我们可以忽略program header table来处理此文件,在运行阶段可以忽略section header table来处理此程序(所以很多加固手段删除了section header table)。从图中我们也可以看出,segments与sections是包含的关系,一个segment包含若干个section。

  Section Header Table: 包含了文件各个segction的属性信息,我们都将结合例子来解释。

  image.png

程序头部表(Program Header Table),如果存在的话,告诉系统如何创建进程映像。

节区头部表(Section Header Table)包含了描述文件节区的信息,比如大小、偏移等。

如下图,可以通过执行命令”readelf -S android_server”来查看该可执行文件中有哪些section。

image.png

通过执行命令readelf –segments android_server,可以查看该文件的执行视图。

image.png


这验证了第一张图中所述,segment是section的一个集合,sections按照一定规则映射到segment。那么为什么需要区分两种不同视图?

当ELF文件被加载到内存中后,系统会将多个具有相同权限(flg值)section合并一个segment。操作系统往往以页为基本单位来管理内存分配,一般页的大小为4096B,即4KB的大小。同时,内存的权限管理的粒度也是以页为单位,页内的内存是具有同样的权限等属性,并且操作系统对内存的管理往往追求高效和高利用率这样的目标。ELF文件在被映射时,是以系统的页长度为单位的,那么每个section在映射时的长度都是系统页长度的整数倍,如果section的长度不是其整数倍,则导致多余部分也将占用一个页。而我们从上面的例子中知道,一个ELF文件具有很多的section,那么会导致内存浪费严重。这样可以减少页面内部的碎片,节省了空间,显著提高内存利用率。

需要注意地是:尽管图中显示的各个组成部分是有顺序的,实际上除了 ELF 头部表以外,其他节区和段都没有规定的顺序。


image.png

image.png

image.png

image.png

image.png

sh_type的取值如下:

image.png

image.png

image.png

image.png

image.png

image.png


原文链接:https://mp.weixin.qq.com/s/ziQKsK--YeRye2KwolSE8w

微信图片_20220708145705.jpg

电子技术应用专栏作家 嵌入式与Linux那些事