⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 elf.txt

📁 序言 1. OBJECT文件 导言 ELF头(ELF Header) Sections String表(String Table) Symbol表(Symbol Table)
💻 TXT
📖 第 1 页 / 共 5 页
字号:

			  ELF 鉴别(Identification)

在上面提到的,ELF提供了一个object文件的框架结构来支持多种处理机,多
样的数据编码方式,多种机器类型。为了支持这个object文件家族,最初的几
个字节指定用来说明如何解释该文件,独立于处理器,与文件剩下的内容无关。

ELF头(也就是object文件)最初的几个字节与成员e_ident相一致。

+ 图 1-4: e_ident[] Identification Indexes

  Name           Value  Purpose
  ====           =====  =======
  EI_MAG0	     0  File identification
  EI_MAG1	     1  File identification
  EI_MAG2	     2  File identification
  EI_MAG3	     3  File identification
  EI_CLASS	     4  File class
  EI_DATA	     5  Data encoding
  EI_VERSION	     6  File version
  EI_PAD	     7  Start of padding bytes
  EI_NIDENT	    16  Size of e_ident[]

通过索引访问字节,以下的变量被定义。

* EI_MAG0 to EI_MAG3

  文件的前4个字符保存着一个魔术数(magic number),用来确定该文件是否
  为ELF的目标文件。

                  Name       Value  Position
                  ====       =====  ========
		  ELFMAG0    0x7f   e_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],用来确定文件的类型或者说是能力。

                 Name           Value  Meaning
                 ====           =====  =======
                 ELFCLASSNONE       0  Invalid class
                 ELFCLASS32         1  32-bit objects
		 ELFCLASS64         2  64-bit objects

  文件格式被设计成在不同大小机器中可移植的,在小型机上的不用大型机上
  的尺寸。类型ELFCLASS32支持虚拟地址空间最大可达4GB的机器;使用上面
  定义过的基本类型。

  类型ELFCLASS64为64位体系的机器保留。它的出现表明了object文件可能 
  改变,但是64位的格式还没有被定义。如果需要,其他类型将被定义,会
  有不同的类型和不同大小的数据尺寸。

* EI_DATA

  字节e_ident[EI_DATA]指定了在object文件中特定处理器数据的编码
  方式。当前定义了以下编码方式。

             Name           Value  Meaning
             ====           =====  =======
	     ELFDATANONE        0  Invalid data encoding
             ELFDATA2LSB        1  See below
             ELFDATA2MSB        2  See below

  更多的关于编码的信息出现在下面。其他值保留,将被分配一个新的编码
  方式,当然如果必要的话。

* EI_VERSION

  字节e_ident[EI_VERSION]表明了ELF头的版本号。
  现在这个变量的是一定要设为EV_CURRENT,作为上面e_version的解释。

* EI_PAD

  该变量标识了在e_ident中开始的未使用的字节。那些字节保留并被设置为
  0;程序把它们从object 文件中读出但应该忽略。假如当前未被使用的字节
  有了新的定义,EI_PAD变量将来会被改变。

一个文件的数据编码指出了如何来解释一个基本的object文件。在上述的
描述中,类型ELFCLAS32文件使用占用1,2和4字节的目标文件。下面定义的
编码方式,用下面的图来描绘。数据出现在左上角。


ELFDATA2LSB编码指定了2的补数值。
最小有意义的字节占有最低的地址。

+ 图1-5: Data Encoding ELFDATA2LSB

               0------+
      0x0102   |  01  |
               +------+
               0------1------+
    0x010204   |  02  |  01  |
               +------+------+
               0------1------2------3------+
  0x01020304   |  04  |  03  |  02  |  01  |
               +------+------+------+------+

ELFDATA2LSB编码指定了2的补数值。
最大有意义的字节占有最低的地址。

+ 图1-6: Data Encoding ELFDATA2MSB

               0------+
      0x0102   |  01  |
               +------+
               0------1------+
    0x010204   |  01  |  02  |
               +------+------+
               0------1------2------3------+
  0x01020304   |  01  |  02  |  03  |  04  |
               +------+------+------+------+


			 机器信息

为了确定文件,32位Intel体系结构的需要以下的变量。

+ 图1-7: 32-bit Intel Architecture Identification, e_ident 

  Position           Value
  ========           =====
  e_ident[EI_CLASS]  ELFCLASS32
  e_ident[EI_DATA]   ELFDATA2LSB

处理器确认ELF头里的e_machine成员,该成员必须为EM_386。

ELF报头里的e_flags成员保存了和文件相关的位标记。32位Intel体系上未
定义该标记;所以这个成员应该为0;


   =========================== Sections ===========================


一个object文件的section header table可以让我们定位所有的sections。
section header table是个Elf32_Shdr结构的数组(下面描述)。一个section
报头表(section header table)索引是这个数组的下标。ELF header table
的e_shoff成员给出了section报头表的偏移量(从文件开始的计数)。e_shnum
告诉我们section报头表中包含了多少个入口;e_shentsize 给出了每个
入口的大小。

一些section报头表索引是保留的;那些特别的索引在一个object文件中
将没有与之对应sections。

+ 图1-8: Special Section Indexes

  Name             Value
  ====             =====
  SHN_UNDEF            0
  SHN_LORESERVE   0xff00
  SHN_LOPROC      0xff00
  SHN_HIPROC      0xff1f
  SHN_ABS         0xfff1
  SHN_COMMON      0xfff2
  SHN_HIRESERVE   0xffff

* SHN_UNDEF

  该值表明没有定义,缺少,不相关的或者其他涉及到的无意义的section。
  例如,标号“defined”相对于section索引号SHN_UNDEF是一个没有被
  定义的标号。

注意: 虽然索引0保留作为未定义的值,section报头表包含了一个索引0的
入口。因此,假如ELF报头说一个文件的section报头表中有6个section入口
的话,e_shnum的值应该是从0到5。最初的入口的内容以后在这个section中
被指定。

* SHN_LORESERVE

  该值指定保留的索引范围的最小值。

* SHN_LOPROC through SHN_HIPROC

  该值包含了特定处理器语意的保留范围。


* SHN_ABS

  该变量是相对于相应参考的绝对地址。
  例如,section号的标号是绝对地址,不被重定位影响。

* SHN_COMMON

  该section的标号是一个公共(common)的标号,就象FORTRAN COMMON
  或者不允许的C扩展变量。

* SHN_HIRESERVE

  该值指定保留的索引范围的上限。系统保留的索引值是从SHN_LORESERVE
  到SHN_HIRESERVE;该变量不涉及到section报头表(section header table)。
  因此,section报头表不为保留的索引值包含入口。
 
sections包含了在一个object文件中的所有信息,除了ELF报头,程序报头
表(program header table),和section报头表(section header table)。
此外,object文件的sections满足几天条件:

* 每个在object文件中的section都有自己的一个section的报头来描述它。
  section头可能存在但section可以不存在。
* 每个section在文件中都占有一个连续顺序的空间(但可能是空的)。
* 文件中的Sections不可能重复。文件中没有一个字节既在这个section中
  又在另外的一个section中。
* object文件可以有"非活动的"空间。不同的报头和sections可以不覆盖到
  object文件中的每个字节。"非活动"数据内容是未指定的。

一个section头有如下的结构。

+ 图1-9: Section Header

  typedef struct {
      Elf32_Word	sh_name;
      Elf32_Word	sh_type;
      Elf32_Word	sh_flags;
      Elf32_Addr	sh_addr;
      Elf32_Off		sh_offset;
      Elf32_Word	sh_size;
      Elf32_Word	sh_link;
      Elf32_Word	sh_info;
      Elf32_Word	sh_addralign;
      Elf32_Word	sh_entsize;
  } Elf32_Shdr;

* sh_name

  该成员指定了这个section的名字。它的值是section报头字符表section的
  索引。[看以下的“String Table”], 以NULL空字符结束。

* sh_type

  该成员把sections按内容和意义分类。section的类型和他们的描述在下面。

* sh_flags

  sections支持位的标记,用来描述多个属性。  
  Flag定义出现在下面。

* sh_addr

  假如该section将出现在进程的内存映象空间里,该成员给出了一个该section
  在内存中的位置。否则,该变量为0。

* sh_offset

  该成员变量给出了该section的字节偏移量(从文件开始计数)。SHT_NOBITS
  类型的section(下面讨论)在文件中不占空间,它的sh_offset成员定位在
  文件中的概念上的位置。

* sh_size
  该成员给你了section的字节大小。除非这个section的类型为SHT_NOBITS,
  否则该section将在文件中将占有sh_size个字节。SHT_NOBITS类型的section
  可能为非0的大小,但是不占文件空间。

* sh_link

  该成员保存了一个section报头表的索引连接,它的解释依靠该section的
  类型。以下一个表描述了这些值。

* sh_info

  该成员保存着额外的信息,它的解释依靠该section的类型。以下一个表描
  述了这些值。

* sh_addralign

  一些sections有地址对齐的约束。例如,假如一个section保存着双字,系统
  就必须确定整个section是否双字对齐。所以sh_addr的值以sh_addralign的值
  作为模,那么一定为0。当然的,仅仅0和正的2的次方是允许的。值0和1意味
  着该section没有对齐要求。

* sh_entsize

  一些sections保存着一张固定大小入口的表,就象符号表。对于这样一个
  section来说,该成员给出了每个入口的字节大小。如果该section没有
  保存着一张固定大小入口的表,该成员就为0。

section头成员sh_type指出了section的语意。

+ 图1-10: Section Types, sh_type

  Name               Value
  ====               =====
  SHT_NULL               0
  SHT_PROGBITS           1
  SHT_SYMTAB             2
  SHT_STRTAB	         3
  SHT_RELA	         4
  SHT_HASH	         5
  SHT_DYNAMIC            6
  SHT_NOTE	         7
  SHT_NOBITS	         8
  SHT_REL	         9
  SHT_SHLIB             10
  SHT_DYNSYM            11
  SHT_LOPROC    0x70000000
  SHT_HIPROC    0x7fffffff
  SHT_LOUSER    0x80000000
  SHT_HIUSER    0xffffffff

* SHT_NULL

  该值表明该section头是无效的;它没有相关的section。
  该section的其他成员的值都是未定义的。

* SHT_PROGBITS

  该section保存被程序定义了的一些信息,它的格式和意义取决于程序本身。

* SHT_SYMTAB and SHT_DYNSYM

  那些sections保存着一个符号表(symbol table)。一般情况下,一个
  object文件每个类型section仅有一个,但是,在将来,这个约束可能被放宽。
  典型的是,SHT_SYMTAB为连接器提供标号,当然它也有可能被动态连接时使用。
  作为一个完整的符号表,它可能包含了一些动态连接时不需要的标号。
  因此,一个object文件可能也包含了一个SHT_DYNSYM的section,它保存着
  一个动态连接时所需最小的标号集合来节省空间。
  看下面符号表“Symbol Table”的细节。

* SHT_STRTAB

  该section保存着一个字符串表。一个object文件可以包含多个字符串表的
  section。看下面字符串表“String Table”的细节。

* SHT_RELA

  该section保存着具有明确加数的重定位入口。就象object文件32位的
  Elf32_Rela类型。一个object文件可能有多个重定位的sections。具体细节
  看重定位``Relocation''部分。

* SHT_HASH

  该标号保存着一个标号的哈希(hash)表。所有的参与动态连接的object
  一定包含了一个标号哈希表(hash table)。当前的,一个object文件
  可能只有一个哈希表。详细细节看第二部分的哈希表"Hash Table"。

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -