C++学习(三九五)ELF类型文件

Posted hankern

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++学习(三九五)ELF类型文件相关的知识,希望对你有一定的参考价值。

ELF 是Executable and Linking Format的缩写,即可执行和可链接的格式。

.o文件、可执行文件、核心转储文件(core dump)、.so文件(动态链链接库)

在计算机科学中,是一种用于二进制文件、可执行文件、目标代码、共享库和核心转储格式文件。
是UNIX系统实验室(USL)作为应用程序二进制接口(Application Binary Interface,ABI)而开发和发布的,也是Linux的主要可执行文件格式。
1999年,被86open项目选为x86架构上的类Unix操作系统的二进制文件标准格式,用来取代COFF。因其可扩展性与灵活性,也可应用在其它处理器、计算机系统架构的操作系统上。

ELF文件由4部分组成,分别是ELF头(ELF header)、程序头表(Program header table)、节(Section)和节头表(Section header table)。实际上,一个文件中不一定包含全部内容,而且它们的位置也未必如同所示这样安排,只有ELF头的位置是固定的,其余各部分的位置、大小等信息由ELF头中的各项值来决定。

 左边是从汇编器和链接器的视角来看这个文件,开头的ELF Header描述了体系结构和操作系统等基本信息,并指出Section Header Table和Program Header Table在文件中的什么位置,Program Header Table在汇编和链接过程中没有用到,所以是可有可无的,Section Header Table中保存了所有Section的描述信息。右边是从加载器的视角来看这个文件,开头是ELF Header,Program Header Table中保存了所有Segment的描述信息,Section Header Table在加载过程中没有用到,所以是可有可无的。注意Section Header Table和Program Header Table并不是一定要位于文件开头和结尾的,其位置由ELF Header指出,上图这么画只是为了清晰。

我们在汇编程序中用.section声明的Section会成为目标文件中的Section,此外汇编器还会自动添加一些Section(比如符号表)。Segment是指在程序运行时加载到内存的具有相同属性的区域,由一个或多个Section组成,比如有两个Section都要求加载到内存后可读可写,就属于同一个Segment。有些Section只对汇编器和链接器有意义,在运行时用不到,也不需要加载到内存,那么就不属于任何Segment。

目标文件需要链接器做进一步处理,所以一定有Section Header Table;可执行文件需要加载运行,所以一定有Program Header Table;而共享库既要加载运行,又要在加载时做动态链接,所以既有Section Header Table又有Program Header Table。

要注意区分段(segment)和节(section)的概念,这两个概念在后面会经常提到。
我们写汇编程序时,用.text,.bss,.data这些指示,都指的是section,比如.text,告诉汇编器后面的代码放入.text section中。
目标代码文件中的section和section header table中的条目是一一对应的。section的信息用于链接器对代码重定位。

而文件载入内存执行时,是以segment组织的,每个segment对应ELF文件中program header table中的一个条目,用来建立可执行文件的进程映像。
比如我们通常说的,代码段、数据段是segment,目标代码中的section会被链接器组织到可执行文件的各个segment中。
.text section的内容会组装到代码段中,.data, .bss等节的内容会包含在数据段中。

以上是关于C++学习(三九五)ELF类型文件的主要内容,如果未能解决你的问题,请参考以下文章

C++学习(四九五)一个最简单的cmake工程文件(动态链接库)

C++学习(三九六)如何查看.o文件

C++学习(三九八)grep命令

C++学习(二九五)Android的URI使用总结

C++学习(三九七)Android Stdudio(AS)提高构建速度的方法

C++学习(三九三)__cxx_global_var_init