zoukankan      html  css  js  c++  java
  • ELF头文件

    4种ELF文件类型

     

    ELF文件类型说明实例
    Relocatable File 包含例代码和数据,可以被链接成可执行文件或共享目标文件 Linux下的.o文件
    Executable File 包含可以直接执行的程序,ELF可执行文件,一般没有扩展名 /bin/bash文件
    Shared Object File 包含代码和数据,和其他目标文件链接成新的目标文件,和可执行文件链接作为进程映像的一部分来允许 Linux下的.so文件
    Core Dump File 进程意外终止时可以产生的文件,存储着该进程的内存空间中的内容等信息 Linux下的core dump

     

     

    ELF文件构成

     两种视图

     section和segment的区别:

    • section称为节,是指在汇编源码中经由关键字section或segment修饰、逻辑划分的指令或数据区域。
    • segment称为段,是根据目标文件中属性相同的多个section合并后的section集合,这个集合称为segment。我们平时所说的可执行程序内存空间中的代码段和数据段就是指的segment。
    • section主要提供给Linker使用, 而segment提供给Loader用。Linker需要关心.text、.rel.text、.data、.rodata等,因为Linker需要做relocation,而Loader只需要知道Read/Write/Execute的属性
    • executable的ELF文件可以没有section,但必须有segment。ELF文件中间部分是共用的(也就是代码段、数据段等),如shared objects就可以同时拥有Program header table和Section Header Table,这样load完后还可以relocate。
    • 这样设定之后,使得Loader需要做的工作大大减少了,一定程度上提高了程序加载的效率。

     

    结构图

     

    注意点

    1. 除了 ELF 头部表以外,其他节区和段都没有规定的顺序
    2. 目标文件中的每个节区都有对应的节区头部描述它,反过来,有节区头部不意味着有节区
    3. 每个节区占用文件中一个连续字节区域(这个区域可能长度为 0)。
    4. 文件中的节区不能重叠,不允许一个字节存在于两个节区中的情况发生。
    5. 目标文件中可能包含非活动空间(INACTIVE SPACE)。这些区域不属于任何头部和节区,其内容未指定。
    6. 以“.”开头的节区名称是系统保留的。应用程序可以使用没有前缀的节区名称,以避免与系统节区冲突。
    7. 目标文件中也可以包含多个名字相同的节区。
    8. Section和Segment的区别和联系
      可执行文件中,一个program header描述的内容称为一个段(segment)。Segment包含一个或者多个section
    9. 可执行程序中的几个段:
    名称内容
    代码段 可执行代码、字符串常量
    数据段 已初始化全局变量、已初始化全局静态变量、局部静态变量、常量数据
    BSS段 未初始化全局变量,未初始化全局静态变量
    局部变量、函数参数
    动态内存分配

     

    section类型

    名称 类型 属性 含义
    .bss SHT_NOBITS SHF_ALLOC SHF_WRITE 包含将出现在程序的内存映像中的为初始化数据。根据定义,当程序开始执行,系统将把这些数据初始化为 0。此节区不占用文件空间。
    .data SHT_PROGBITS (无) 包含版本控制信息。
    .data1 SHT_PROGBITS SHF_ALLOC SHF_WRITE 这些节区包含初始化了的数据,将出现在程序的内存映像中。
    .debug SHT_PROGBITS (无) 此节区包含用于符号调试的信息。
    .dynamic SHT_DYNAMIC   此节区包含动态链接信息。节区的属性将包含 SHF_ALLOC 位。是否 SHF_WRITE 位被设置取决于处理器。
    .dynstr SHT_STRTAB SHF_ALLOC 此节区包含用于动态链接的字符串,大多数情况下这些字符串代表了与符号表项相关的名称。
    .dynsym SHT_DYNSYM SHF_ALLOC 此节区包含了动态链接符号表。
    .fini SHT_PROGBITS SHF_ALLOCSHF_EXECINSTR 此节区包含了可执行的指令,是进程终止代码的一部分。程序正常退出时,系统将安排执行这里的代码。
    .got SHT_PROGBITS   此节区包含全局变量偏移表。存放着调用外部函数的实际地址(第一次存放的是PLT中的指令,PLT执行完之后会把计算得到的实际值再存到GOT中)。
    .got.plt     ELF将GOT拆分成两个表 .got和.got.plt,前者用来保存全局变量引用的地址,后者用来保存函数引用的地址。
    .hash SHT_HASH SHF_ALLOC 此节区包含了一个符号哈希表.
    .init SHT_PROGBITS SHF_ALLOCSHF_EXECINSTR 此节区包含了可执行指令,是进程初始化代码的一部分。当程序开始执行时,系统要在SHF_EXECINSTR 开始调用主程序入口之前(通常指 C 语言的 main 函数)执行这些代码。
    .interp SHT_PROGBITS   此节区包含程序解释器的路径名。如果程序包含一个可加载的段,段中包含此节区,那么节区的属性将包含 SHF_ALLOC 位,否则该位为 0。
    .line SHT_PROGBITS   此节区包含符号调试的行号信息,其中描述了源程序与机器指令之间的对应关系。其内容是未定义的。
    .note SHT_NOTE   此节区中包含注释信息,有独立的格式。
    .plt SHT_PROGBITS   此节区包含过程链接表(procedure linkage table)。所有对外部函数的调用都经过PLT再到GOT的一个调用过程。
    .relname SHT_REL   这些节区中包含了重定位信息。如果文件中包含可加载的段,段中有重定位内容,节区的属性将包含 SHF_ALLOC 位,否则该位 置 0。传统上 name 根据重定位所适用的节区给定。例如 .text 节区的重定位节区名字将是:.rel.text 或者 .rela.text。
    .rel.dyn     重定位的地方在.got段内,主要是针对外部数据变量符号。不支持延迟重定位(Lazy),通常是在so文件执行时就在.init段中进行重定位操作。
    .rel.plt
        重定位的地方在.got.plt段内, 主要是针对外部函数符号。一般是函数首次被调用时候重定位。
    .rela name SHT_RELA    
    .rodata SHT_PROGBITS SHF_ALLOC 这些节区包含只读数据,这些数据通常参与进程映像的不可写段。
    .rodata1 SHT_PROGBITS SHF_ALLOC  
    .shstrtab SHT_STRTAB   此节区包含节区名称。
    .strtab SHT_STRTAB   此节区包含字符串,通常是代表与符号表项相关的名称。如果文件拥有一个可加载的段,段中包含符号串表,节区的属性将包含 SHF_ALLOC 位,否则该位为 0。
    .symtab SHT_SYMTAB   此节区包含一个符号表。如果文件中包含一个可加载的段,并且该段中包含符号表,那么节区的属性中包含SHF_ALLOC 位,否则该位置为 0。
    .text SHT_PROGBITS   此节区包含程序的可执行指令。

     

    segment类型

    程序段类型 取值 说明
    PT_NULL 0 此数组元素未用。结构中其他成员都是未定义的。
    PT_LOAD 1 此数组元素给出一个可加载的段,段的大小由 p_filesz 和 p_memsz描述。文件中的字节被映射到内存段开始处。如果 p_memsz 大于p_filesz,“剩余”的字节要清零。p_filesz 不能大于 p_memsz。可加载的段在程序头部表格中根据 p_vaddr 成员按升序排列。
    PT_DYNAMIC 2 数组元素给出动态链接信息。Dynamic Segment 是很重要的一个程序头,里面存储着函数名、使用过的动态库名、重定位表、函数代码偏移等重要信息,不过不是直接记录,而是通过一定的方法查询得到,这个查询过程是elf设计中巧妙且关键的核心所在。
    PT_INTERP 3 该记录的是链接器linker的路径.数组元素给出一个 NULL 结尾的字符串的位置和长度,该字符串将被当作解释器调用。这种段类型仅对与可执行文件有意义(尽管也可能在共享目标文件上发生)。在一个文件中不能出现一次以上。如果存在这种类型的段,它必须在所有可加载段项目的前面。
    PT_NOTE 4 此数组元素给出附加信息的位置和大小。
    PT_SHLIB 5 此段类型被保留,不过语义未指定。包含这种类型的段的程序与 ABI 不符。
    PT_PHDR 6 此类型的数组元素如果存在,则给出了程序头部表自身的大小和位置,既包括在文件中也包括在内存中的信息。此类型的段在文件中不能出现一次以上。并且只有程序头部表是程序的内存映像的一部分时才起作用。如果存在此类型段,则必须在所有可加载段项目的前面。
    PT_LOPROC 0x70000000 此范围的类型保留给处理器专用语义。
    PT_HIPROC 0x7ffffffff

     

  • 相关阅读:
    HDU 6071
    HDU 6073
    HDU 2124 Repair the Wall(贪心)
    HDU 2037 今年暑假不AC(贪心)
    HDU 1257 最少拦截系统(贪心)
    HDU 1789 Doing Homework again(贪心)
    HDU 1009 FatMouse' Trade(贪心)
    HDU 2216 Game III(BFS)
    HDU 1509 Windows Message Queue(队列)
    HDU 1081 To The Max(动态规划)
  • 原文地址:https://www.cnblogs.com/0xHack/p/11575444.html
Copyright © 2011-2022 走看看