ELF基本结构

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/kidthephantomthiefI/article/details/79926800

《程序员的自我修养——链接、装载与库》读书笔记

        编译器编译源代码后产生的文件叫做目标文件。它们经过链接后可以形成库文件或者可执行文件。主流平台的可执行文件格式主要有Windows下的PE(Portable Executable)和Linux下的ELF(Executable Linkable Format),他们都是COFF(Common File Format)的变种。ELF文件标准里面把系统采用ELF格式的文件归为四类:可重定位文件(Relocatable File),可执行文件(Executable File),共享目标文件(Shared Object File)和核心转储文件(Core Dump File)。

1. 总体结构

        可重定位文件(如静态链接库,Linux的.o,Windows的.obj)包含了代码和数据,可以被用来链接生成可执行文件或共享目标文件。可执行文件(如Linux的/bin/bash,Windows的.exe)包含了可以直接执行的程序。共享目标文件(如Linux的.so,Windows的.dll)包含了代码和数据,链接器可以使用这种文件跟其他的可重定位文件和共享目标文件链接,产生新的目标文件;也可以将几个这种共享目标文件与可执行文件结合,作为进程映像的一部分来运行。当进程意外终止时,系统可以将该进程的地址空间的内容及终止时的一些其它信息转储到核心转储文件(Linux下的core dump)。

        目标文件中的信息按照属性的不同,以节(Section)的形式存储。一般一个ELF文件中包含了代码节(.code或.text)、数据节(.data)、只读数据节(.rodata)、未初始化数据节(.bss)、注释信息节(.comment)和堆栈提示节(.note.GNU-stack)等。一个ELF文件的基本结构如下图所示:


ELF结构
图1 ELF结构

        位于文件最前部的是ELF文件头(ELF Header),他描述了整个文件的基本属性,包括节表(Section Table)在文件中的偏移。而节表中包含了所有节的信息,比如每个节的节名、节的长度、在文件中的偏移、读写权限及节的其它属性。

2. .bss节

        对于程序中的数据来说,.rodata节中存放着只读数据,如程序中的只读变量和字符串常量,.data节中存储着已初始化的全局变量和局部静态变量,.bss节中存储着未初始化的全局变量和局部静态变量。由于未初始化的全局变量和局部静态变量的默认值为0,为它们在.data节中分配空间并且存放数据0是没有意义的,而在程序运行中它们的确要占内存空间,所以可执行文件只是在节表中记录了它们的大小,为它们预留了位置,记为.bss节。它并没有内容,在文件中也不占据空间。(BSS原是汇编器FAP的伪指令,用于定义符号并且为该符号预留给定数量的未初始化空间。)值得注意的是,有些编译器会将未初始化全局变量存放在目标文件的.bss节,有些则不存放,只是预留一个未定义的全局符号,等到最终链接成可执行文件时再在.bss节分配空间,这又和程序的链接过程有关。

3. 字符串表

        ELF文件中用到了许多字符串,比如段名、变量名。由于它们的长度不定,难以用固定的结构表示,常见做法是把它们集中起来存放到一个表,然后用它们在表中的偏移来引用它们。如,.strtab节为字符串表(String Table),用来保存普通的字符串,.shstrtab节为节表字符串表(Section Header String Table),用来保存节表中用到的字符串,比如节名。

4. 符号表

        在链接中,函数和变量被统称为符号(Symbol),函数名或变量名就是符号名(Symbol Name)。每个目标文件都会有一个符号表(Symbol Table),这个表里面记录了目标文件中所用到的所有符号。每个定义的符号有一个对应的值,叫符号值(Symbol Value),对于函数和变量来说,符号值就是它们的地址。符号表中的符号可以分为一下几类:

  • 定义在本目标文件中的全局符号
  • 本目标文件中引用的,没有定义在本目标文件中全局符号,这一般叫做外部符号(External Symbol)
  • 节名,它的值就是该节的起始地址
  • 局部符号,这类符号只在编译单元内部可见,这些符号对于链接过程没有作用
  • 行号信息,即目标文件指令与源代码中代码行的对应关系

5. 重定位表

        链接器在处理目标文件时,需要对目标文件中代码节和数据节中,那些对绝对位置的引用的位置进行重定位。这些重定位信息都记录在ELF文件的重定位表(Relocation Table)中,对于每一个需要重定位的代码节或者数据节,都有一个相应的重定位表。

6. 总结

        这里描述的只是ELF文件的基本结构,当考虑到静态链接,动态链接和装载的过程时,还需要涉及到很多内容,暂且不表。

猜你喜欢

转载自blog.csdn.net/kidthephantomthiefI/article/details/79926800
今日推荐