找回密码
 注册
搜索
查看: 1813|回复: 1

[资料] elf文件格式解析

[复制链接]
发表于 2012-2-1 14:30:23 | 显示全部楼层 |阅读模式
  在MTK平台上实现支持全部变量的动态加载必读。

  1ExecutableandLinkableFormat(ELF)初稿,图请参考ELF_Format手册

  1.1Preface

  ELF-可执行链接格式最初是由UNIX系统实验室(USL)作为应用程序二进制接口(ABI)开发和发行。工具接口标准委员会TIS已经将ELF作为运行在Intel32位架构之上的各类型操作系统的可导出对象文件格式标准。ELF标准为开发者提供了一组横跨多运行环境的二进制接口定义来组织软件开发。

  1.2对象文件$leads…………….

  1.2.1介绍

  本部分描述了iABI对象文件格式,也称之为ELF。有三种主要类型的对象文件:

  1.可重组(relocatable)文件包含了适合用来链接其他对象文件的代码和数据,从而创建出可执行或可共享的对象文件;

  2.可执行(executable)文件包含了用于执行的程序,该文件规定了exec如何创建一个程序的进程映像;

  3.可共享对象(sharedobject)文件包含了用来在两个上下文之间链接的代码和数据。首先,链接器ld将该文件和其他的可重组文件或可共享对象文件进行处理后,创建出新对象文件,其次,动态链接器将该新对象文件与可执行文件或共享对象组合,来共同创建一个进程映像;

  经过汇编器以及链接器创建成的对象文件,其是在处理器上可直接执行的程序的二进制代表。本部分主要描述文件格式以及其如何用来构建程序。后一部分也描述了对象文件,集中在程序执行所必须的信息上。

  1.2.1.1文件格式

  在程序链接和程序执行过程都涉及到对象文件。出于方便和效率,对象文件格式图从链接和运行两个视角来展示文件的内容。

  ELFheader位于文件的开始处,其用来描述文件的组织结构。Section包含了大量的对象文件信息,从链接的视角来看就是指令、数据、符号表、重组信息等等。Segment和Program是从程序执行视角来观看的,这将在下部分讲解。

  如果存在ProgramHeadertable的话,其将告诉操作系统如何创建进程映像。用来创建进程映像(执行程序)的文件必须包含programheadertable。可重组(relocatable)文件可以没有该信息。Sectionheadertable包含了用来描述文件section的信息。每个section在该表中都有一个对应的表项,每个表项给出了诸如section名称、尺寸等等信息。用于链接的文件必须有sectionheadertable,其他的对象文件可有可无。

  这里需要注意的是,虽然图中Programheadertable紧接着ELFheader,sectionheadertable紧接着sections,实际的文件中并不一定是这样。而且,sections和segments也可以不按次序排放,只有ELFheader是固定在文件的首部。

  1.2.1.2数据的表示

  对象文件格式支持8位、32位等架构的大量处理器。然而,为了保证其容易扩展到更多的体系架构,因此对象文件提供了一些机器独立的控制数据,用来按照统一的方式标明和解释对象文件的内容。对象文件中其余的数据都是按照目标处理器硬编码的,当然不用考虑该文件是在哪个文件上创建的。

  对象文件格式中定义的所有数据结构定义都沿守自然尺寸以及对齐原则。必要时,数据结构可以包含填补内容来保证4字节对象的4字节对齐。数据也可以相对于文件起始位置对齐,例如,包含Elf32_Addr成员的数据结构在文件中将会按照4字节对齐。为了保证可移植性,EFL中不使用bit域。

  1.2.2ELFHeader

  1.2.2.1ELFHeader结构

  一些对象文件控制结构可能会增长,因为ELFheader包含了这些结构的实际尺寸。如果对象文件格式发生改变,那么程序有可能会碰到控制结构比原来大或者比原来小的情况,这样,程序有可能就会忽略一些额外的信息。至于这些丢失的信息如何处理,则依赖于上下文环境。

  e_ident这段最先开始的字节标识该文件为对象文件,并且提供了机器独立的数据,其用来解释文件内容。完整的描述见下面的ELFIdentification。

  e_type该成员指定了对象文件的类型。虽然核心文件内容没有明确的规定,但是ET_CORE类型则专门为该文件保留。

  从0xFF00到0xFFFF,为特定处理器保留。剩余所有其他的值也是保留的,用于新类型的对象文件。ET_NONE0No

  ET_REL1Relocatable

  ET_EXEC2Executable

  ET_DYN3Shared

  ET_CORE4Core

  ET_LOPROC0xff00Processor-specific

  ET_HIPROC0xffffProcessor-specific

  e_machine该成员指定了文件适用的计算机架构。除了定义的值之外,其他的值保留,在必要时用于新的计算机架构。

  EM_NONE0No

  EM_M321AT&T

  EM_SPARC2SPARC

  EM_3863Intel

  EM_68K4Motorola

  EM_88K5Motorola

  EM_8607Intel

  EM_MIPS8MIPS

  e_version该成员指定了对象文件版本,1表示该文件为最初文件格式。如果扩展了,则使用更高的编号。EV_NONE0Invalid

  EV_CURRENT1Current

  e_entry

  该成员标明了系统接管该进程控制的第一条指令的逻辑地址,从而开始了该进程。如果没有关联切入点,则默认为0。

  e_phoff该成员包含了programheadertable的文件偏移地址(按字节),如果该文件没有programheadertable,则该成员为0。

  e_shoff该成员包含了sectionheadertable的文件偏移地址(按字节),如果该文件没有sectionheadertables,则该成员为0。

  e_flags该成员包含了文件与处理器相关的标识。

  e_ehsize该成员包含了ELFheader的尺寸(按字节)。

  e_phentsize包含了programheadertable中一条表项的字节数,所有表项大小相等。

  e_phnum包含了programheadertable中表项的数目。如果该文件没有programheadertable,则该值为0。

  e_shentsize包含了sectionheadertable中一条表项的字节数,所有表项大小相等。

  e_shnum包含了sectionheadertable中表项的数目。如果该文件不含sectionheadertable,则该值为0。

  e_shstrndxsectionnamestringtable(段名称字符串表)独立构成一个section。

  e_shstrndx成员包含了该section在sectionheadertable中表项的索引号。如果该文件不含sectionnamestringtable,该成员中填充的值为SHN_UNDEF,见‘‘Sections’’和‘‘StringTable’’。

  1.2.2.2ELFHeaderELFIdentification

  像上面提及到的一样,ELF提供了对象文件框架来支持多处理器、多数据编码、多类型的机器。为了支持这些对象文件家族,文件的初始字节必须指明如何解析本文件,而且该指明过程必须和处理器(查询解析信息就是通过该处理器进行的)无关以及和该文件剩余的内容无关。

  EFLHeader的初始字节也就是e_ident成员。

  每个字节的具体值及其含义如下:

  EI_MAG0到EI_MAG3

  文件的头4个字节包含了特征码,其用来表明该文件是一个ELF对象文件

  ELFMAG00x7fe_ident[EI_MAG0]

  ELFMAG1’E’e_ident[EI_MAG1]

  ELFMAG2’L’e_ident[EI_MAG2]

  ELFMAG3’F’e_ident[EI_MAG3]

  EI_CLASS

  e_ident[EI_CLASS]指明了文件的种类或容量。

  ELF文件格式在设计时就考虑到了在不同总线宽度的机器中通用,而不用考虑到诸如把最大总线宽度的机器码强加到最小机器上去。

  类别ELFCLASS32支持高达4GB的虚拟地址空间和文件尺寸,其使用上面定义的基本类型。

  类别ELFCLASS64为64位架构保留,其也表明了对象文件可能的改变,不过64位格式还没有定义。

  其他的类别也会在需要时定义,相应的基本类型和尺寸也会发生变化。ELFCLASSNONE0Invalid

  ELFCLASS32132-bit

  ELFCLASS64264-bit

  EI_DATA

  e_ident[EI_DATA]规定了对象文件中和处理器相关的数据的如何编码。更多的下面会详解。

  ELFDATANONE0Invalid

  ELFDATA2LSB1Seebelow

  ELFDATA2MSB2Seebelow

  EI_VERSION

  e_ident[EI_DATA]指定了EFLheader版本号。当前情况下,必须是EV_CURRENT,后面会详细解释。

  EI_PAD

  该值标明了在e_ident中无用字节的开始,这些字节被设置为0,为保留;读取对象文件的进程应该忽略这些字节。如果未来某些未用字节派上用场了,该值在也许会改变。

  文件的数据解码规定了如何翻译文件中的基本对象。如上所述,类别ELFCLASS32文件使用占用1、2、4字节的对象。在编码的前提下,对象的排布如下图所示,序号在每个单元的左上角。

  ELFDATA2LSB编码规范规定了最末端字节占用最低地址:

  ELFDATA2MSB编码规范规定了最末端字节占用最高地址:

  1.2.2.3ELFHeader机器信息

  对于32位Intel体系架构而言,文件标识e_ident中相关成员的值应该如下:

  e_ident[EI_CLASS]=ELFCLASS32

  e_ident[EI_DATA]=ELFDATA2LSB

  同时在ELFheader中的e_machine成员必须为EM_286。ELFheader中的e_flags成员包含了和文件相关的比特标志位。32位Intel体系架构不需要任何标志位,因此该值为0。

  1.2.3Sectionheadertable及section特征

  1.2.3.1sectionheadertable概述

  对象文件的sectionheadertables使得可以轻而易举的定位所有的section,sectionheadertable是一个Elf32_Shdr结构的数组。sectionheadertableindex是数组中某个元素的下标。ELFheader中的e_shoff成员给出了sectionheadertable到文件头的偏移(按字节),e_shnum给出了sectionheadertable中包含多少个表项,e_shentsize给出了每个表项的字节数。

  1.2.3.2sectionheadertable特殊的sectionindex

  某些sectionheadertableindex是保留的,对象文件中的section不应该占用这些特殊index。

  SHN_UNDEF该值标明了一个没有定义的、丢失的、或者没有意义的section引用,例如,一个“已经定义了”的符号引用了SHN_UNDEFsection序号的,则该符号实际被当作为未定义符号。

  注意:虽然索引0被保留为一个未定义的值,但是sectionheadertable仍然包含了用于0索引的表项,也就是说,如果e_shnum=6,则索引为0-5。

  SHN_LORESERVE该值指定了保留索引的低端。

  SHN_LOPROC至SHN_HIPROC此范围内的索引用于特定的处理器,也是保留的。

  SHN_ABS该值指定了相应引用的绝对值。例如,引用了SHN_ABSsection序号的已定义符号,其地址将是绝对的,不会被重组所影响。

  SHN_COMMON引用该section的符号都是常用的符号,例如FORTRANCOMMON或没有分配的C外部变量。

  SHN_HIRESERVE该值指定了保留索引高端,系统保留索引在SHN_LORESERVE和SHN_HIRESERVE范围之间(包含SHN_LORESERVE和SHN_HIRESERVE)。Sectionheadtable中不会包含这些保留索引的表项。

  1.2.3.3section的特征

  除了ELFheader、programheadertable、sectionheadertable之外,Section包含了对象文件中的所有信息。另外,对象文件的section还必须满足以下几个要求:

  1.对象文件中的每个section在sectionheadertable中都必须有一个表项来描述它。即使一个section都没有,sectionheadertable也可以存在;

  2.每个section在文件中都占用一段连续字节的空间(当然也可以为空);

  3.一个文件中的sections不能重叠,文件中的一个字节不能同时位于一个以上的section中;

  4.对象文件中可以有不活动的空间,大量的Headers以及sections不一定会覆盖对象文件的每个字节,不活动数据的内容是不确定的。

  1.2.4sectionheadertablesectionheader

  1.2.4.1sectionheader结构

  sectionheader的结构如下:

  1.sh_name:该成员指定了section的名称,其值为section“sectionheaderstringtable”(注意sectionheaderstringtable本身构成了一个Section)中某一表项的索引,该索引中为一个以nul终止的字符串;

  2.sh_type:该成员一句section的内容和语义将section分类。section类型及其描述下面将会有详细描述;

  3.sh_flags:Section支持使用1bit标志来描述大量的属性,下面将会详细描述;

  4.sh_addr:如果某个section将会出现在进程的内存映射中,该成员给出的就是该section第一个字节驻留在内存中的地址。否则,该成员将会为0;

  5.sh_offsect:该成员给出了从文件开始处到section中第一个字节的偏移(按字节)。这里需要提到的SHT_NOBITS类型的section,其在文件中不占用任何空间,其sh_offsect则为其在文件中的虚位置;

  6.sh_size:该成员给出了section的大小尺寸(按字节),如果该section类型不是SHT_NOBITS,则该size即为该section在文件中所占的字节数。如果是,则即使该值不为0,但是其也不会在文件中占用任何空间;

  7.sh_link:该成员包含了一个sectionheadertable的索引链接,其如何解释依赖于该section的类型,下面将会详细描述;

  8.sh_info:该成员包含了些额外的信息,其如何解释也依赖于section的类型;

  9.sh_addralign:一些section可能会有地址对齐约束,例如我们要求,如果section包含了一个双字,则系统必须确保整个section按照双字对齐。也就是说,sh_addr取模sh_addralign的值必须为0。目前只有0和2的整数次幂值可以在此处使用,0和1意味着无需对齐;

  10.sh_entsize:有些section包含的是一组固定大小表项的表,例如符号表,对于这样的section,该成员给出了每个表项的尺寸大小。如果section不包括这样的内容,则该值为0。

  1.2.4.2sectionheadersectiontype

  sectionheader的sh_type成员包含了如下的语义:

  1.SHT_NULL:该值表示该sectionheader是不活动的,其没有对应的section,此时sectionheader中其他的成员都没有意义;

  2.SHT_PROGBITS:该section包含了程序自定义信息,其格式和含义由程序自行决定;

  3.SHT_SYMTAB和SHT_DYNSYM:该section包含了符号表。当前每种类型的section在对象文件中只能有一个,该限制在未来有望被放开。SHT_SYMTAB为连接器提供了符号,当然其也包含了用于动态链接的符号。但是由于一个完整的符号表可能会包含了大量的对于动态链接没有用的符号,所以,对象文件或许也应该包含一个SHT_DYNSYMsection,其中包含了一组最小化的动态链接符号,用来节省空间;

  4.SHT_STRTAB:该section包含了一个stringtable。一个对象文件可以有多个stringtablesections;

  5.SHT_RELA:该section包含了重组表项(withexplicitaddends);

  6.SHT_HASH:该section包含了符号hash表,所有参与动态链接的对象都必须包含一个符号hash表;

  7.SHT_DYNAMIC:该section包含了动态链接信息;

  8.SHT_NOTE:该section包含了特定的信息,详见NoteSection;

  9.SHT_NOBITS:该section在文件中不占用空间,但是其类似与SHT_PROGBITS,虽然该section不包含任何字节,但是其sh_offset成员仍然包含了概念上的相对文件起始的偏移地址;

  10.SHT_REL:该section包含了重组表项(withoutexplicitaddends);

  11.SHT_SHLIB:该section类型是保留的,还没有被指定语义,和ABI一致的程序不应该包含该section;

  12.SHT_LOPROC到SHT_HIPROC:该范围内的值是为特定处理器语义保留的;

  13.SHT_LOUSER:该值指定了为应用程序编程者保留的索引范围的低端;

  14.SHT_HIUSER:该值指定了为应用程序编程者保留的索引范围的高端,在SHT_LOUSER到SHT_HIUSER之间的类型的section可以被应用程序使用,而不会同当前的或者未来的为系统定义的类型起冲突;

  除上述类型之以外,剩余所有的类型值统统保留,

  1.2.4.3sectionheadersectionflag属性

  sectionheader的sh_flags成员包含了1比特标志,用来描述该section的属性,定义的值如下:

  如果sh_flags中其中一个标志bit位被设置,则该属性就为section打开了。

  1.SHF_WRITE:该section包含了在进程执行期间可写的数据;

  2.SHF_ALLOC:该section在进程执行期间会占用内存。一些控制section不会驻留在对象文件的内存映像里,对于这些section,该属性就为OFF;

  3.SHF_EXECINSTR:该section包含了可执行的机器指令;

  4.SHF_MASKPROC:所有包含在该mask中的属性都用于特定处理器的语义;

  1.2.4.4sectionheadersh_link和sh_info属性

  sectionheader中的sh_link和sh_info成员根据sectiontype的不同,包含了不同的特殊信息。

  Figure1-13:sh_link和sh_info说明

  sh_typesh_linksh_info

  SHT_DYNAMIC对于当前的sh_type,该属性的值即为该section所使用的stringtablesection在sectionheadertable中的索引0

  SHT_HASH对于当前的sh_type,该属性的值即为该hash表section所使用的符号表section在sectionheadertable中的索引0

  SHT_REL

  SHT_RELA对于当前的sh_type,该属性的值即为该section所相关的符号表section在sectionheadertable中的索引对于当前的sh_type,该属性的值即为该section将要应用重组的section在sectionheadertable中的索引

  SHT_SYMTAB

  SHT_DYNSYM对于当前的sh_type,该属性的值即为该section所相关的符号表string在sectionheadertable中的索引比符号表中最后一个Local符号(STB_LOCAL)索引还要大的数值

  otherSHN_UNDEF0

  1.2.4.5sectionheader特殊的section

  几个特殊的sections说明:

  1..bss,该section包含了在内存中的程序的未初始化的数据,当程序开始运行时,系统将用0来初始化该区域。该section不占用文件空间,该sectiontype=SHT_NOBITS;

  2..comment,该section包含了版本控制信息;

  3..data和.data1,该section包含了在内存中的程序的初始化数据;

  4..debug,该section包含了符号调试信息,其中内容没有硬性规定;

  5..dynamic,该section包含了动态链接信息,该section属性将包含SHF_ALLOC比特位,而SHF_WRITE比特位是否为1取决于处理器;

  6..dynstr,该section包含了用于动态链接的字符串,通常是符号表项名称字符串;

  7..dynsym,该section包含了动态链接符号表;

  8..fini,该section包含了用于终止进程可执行指令代码;

  9..got,该section包含了全局偏移表;

  10..hash,该section包含了符号hash表;

  11..init,该section包含了用于初始化进程的可执行代码,也就是说,当一个程序开始运行的时候,系统将会执行在该section中的代码,然后才会调用程序的入口点(对于C程序而言就是main);

  12..interp,该section包含了程序解释其的路径;

  13..line,该section包含了符号调试信息的行号,其用于描述程序源代码和机器码之间的相应关系;

  14..note,该section包含了供应商及程序兼容信息等;

  15..plt,该section包含了程序链接表;

  16..relname和.relaname,该section包含了relocation信息,该section的属性包括了SHF_ALLOC比特位,通常,name为将要被重组的section的名称,例如如果要重组.text,那么名称就为.rel.text或者.rela.text;

  17..rodata和.rodata1,该section包含了只读数据,通常进程中的不可写段,例如ProgramHeader;

  18..shstrtab,该section包含了section名称;

  19..strtab,该section包含了符号表项名称字符串,如果文件包含了一个可加载的并且包含了符号字符串表的segment,则section的SHF_ALLOC比特位属性将被设置;

  20..symtab,该section包含了符号表,如果文件包含了一个可加载的并且包含了符号表的segment,则section的SHF_ALLOC比特位属性将被设置;

  21..text,该section包含了程序的可执行指令。

  【求赏钱】
【数 额】:1

打赏我1RDB吧!谢谢
发表于 2012-3-23 12:04:11 | 显示全部楼层
爷赏你一个
点评回复

使用道具 举报

高级模式
B Color Image Link Quote Code Smilies

本版积分规则

Archiver|手机版|小黑屋|52RD我爱研发网 ( 沪ICP备2022007804号-2 )

GMT+8, 2025-1-29 13:51 , Processed in 0.068696 second(s), 17 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表