=========================== 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"。
* SHT_DYNAMIC
该section保存着动态连接的信息。当前的,一个object可能只有一个动态
的section,但是,将来这个限制可能被取消。详细细节看第二部分的动态
section(“Dynamic Section”)。
* SHT_NOTE
该section保存着其他的一些标志文件的信息。详细细节看第二部分的“Note
Section” 。
* SHT_NOBITS
该类型的section在文件中不占空间,但是类似SHT_PROGBITS。尽管该section
不包含字节,sh_offset成员包含了概念上的文件偏移量。
* SHT_REL
该section保存着具有明确加数的重定位的入口。
就象object文件32位类型Elf32_Rel类型。一个object文件可能有多个
重定位的sections。具体细节看重定位``Relocation''部分。
* SHT_SHLIB
该section类型保留但语意没有指明。包含这个类型的section的程序
是不符合ABI的。
* SHT_LOPROC through SHT_HIPROC
在这范围之间的值为特定处理器语意保留的。
* SHT_LOUSER
该变量为应用程序保留的索引范围的最小边界。
* SHT_HIUSER
该变量为应用程序保留的索引范围的最大边界。在SHT_LOUSER和HIUSER的
section类型可能被应用程序使用,这和当前或者将来系统定义的section
类型是不矛盾的。
其他section类型的变量是保留的。前面提到过,索引0(SHN_UNDEF)的section
头存在的,甚至索引标记的是未定义的section引用。这个入口保存着以下的
信息。
+ 图1-11: Section Header Table Entry: Index 0
Name Value Note
==== ===== ====
sh_name 0 No name
sh_type SHT_NULL Inactive
sh_flags 0 No flags
sh_addr 0 No address
sh_offset 0 No file offset
sh_size 0 No size
sh_link SHN_UNDEF No link information
sh_info 0 No auxiliary information
sh_addralign 0 No alignment
sh_entsize 0 No entries
一个section报头(section header table)的sh_flags成员保存着1位标记,
用来描述section的属性。以下是定义的值;其他的值保留。
+ 图1-12: Section Attribute Flags, sh_flags
Name Value
==== =====
SHF_WRITE 0x1
SHF_ALLOC 0x2
SHF_EXECINSTR 0x4
SHF_MASKPROC 0xf0000000
假如在sh_flags中的一个标记位被设置,该section相应的属性也被打开。
否则,该属性没有被应用。未明的属性就设为0。
* SHF_WRITE
该section包含了在进程执行过程中可被写的数据。
* SHF_ALLOC
该section在进程执行过程中占据着内存。一些控制section不存在一个
object文件的内存映象中;对于这些sections,这个属性应该关掉。
* SHF_EXECINSTR
该section包含了可执行的机器指令。
* SHF_MASKPROC
所有的包括在这掩码中的位为特定处理语意保留的。
在section报头中,两个成员sh_link和sh_info的解释依靠该section的类型。
+ 图1-13: sh_link and sh_info Interpretation
sh_type sh_link sh_info
======= ======= =======
SHT_DYNAMIC The section header index of 0
the string table used by
entries in the section.
SHT_HASH The section header index of 0
the symbol table to which the
hash table applies.
SHT_REL, The section header index of The section header index of
SHT_RELA the associated symbol table. the section to which the
relocation applies.
SHT_SYMTAB, The section header index of One greater than the symbol
SHT_DYNSYM the associated string table. table index of the last local
symbol (binding STB_LOCAL).
other SHN_UNDEF 0
Special Sections 特殊的Sections
不同的sections保存着程序和控制信息。下面列表中的section被系统使用,
指示了类型和属性。
+ 图1-14: Special Sections
Name Type Attributes
==== ==== ==========
.bss SHT_NOBITS SHF_ALLOC+SHF_WRITE
.comment SHT_PROGBITS none
.data SHT_PROGBITS SHF_ALLOC+SHF_WRITE
.data1 SHT_PROGBITS SHF_ALLOC+SHF_WRITE
.debug SHT_PROGBITS none
.dynamic SHT_DYNAMIC see below
.dynstr SHT_STRTAB SHF_ALLOC
.dynsym SHT_DYNSYM SHF_ALLOC
.fini SHT_PROGBITS SHF_ALLOC+SHF_EXECINSTR
.got SHT_PROGBITS see below
.hash SHT_HASH SHF_ALLOC
.init SHT_PROGBITS SHF_ALLOC+SHF_EXECINSTR
.interp SHT_PROGBITS see below
.line SHT_PROGBITS none
.note SHT_NOTE none
.plt SHT_PROGBITS see below
.rel SHT_REL see below
.rela SHT_RELA see below
.rodata SHT_PROGBITS SHF_ALLOC
.rodata1 SHT_PROGBITS SHF_ALLOC
.shstrtab SHT_STRTAB none
.strtab SHT_STRTAB see below
.symtab SHT_SYMTAB see below
.text SHT_PROGBITS SHF_ALLOC+SHF_EXECINSTR
* .bss
该sectiopn保存着未初始化的数据,这些数据存在于程序内存映象中。
通过定义,当程序开始运行,系统初始化那些数据为0。该section不占
文件空间,正如它的section类型SHT_NOBITS指示的一样。
* .comment
该section保存着版本控制信息。
* .data and .data1
这些sections保存着初始化了的数据,那些数据存在于程序内存映象中。
* .debug
该section保存着为标号调试的信息。该内容是未指明的。
* .dynamic
该section保存着动态连接的信息。该section的属性将包括SHF_ALLOC位。
是否需要SHF_WRITE是跟处理器有关。第二部分有更详细的信息。
* .dynstr
该section保存着动态连接时需要的字符串,一般情况下,名字字符串关联着
符号表的入口。第二部分有更详细的信息。
* .dynsym
该section保存着动态符号表,如“Symbol Table”的描述。第二部分有更
详细的信息。
* .fini
该section保存着可执行指令,它构成了进程的终止代码。
因此,当一个程序正常退出时,系统安排执行这个section的中的代码。
* .got
该section保存着全局的偏移量表。看第一部分的“Special Sections”和
第二部分的“Global Offset Table”获得更多的信息。
* .hash
该section保存着一个标号的哈希表。看第二部分的“Hash Table”获得更多
的信息。
* .init
该section保存着可执行指令,它构成了进程的初始化代码。
因此,当一个程序开始运行时,在main函数被调用之前(c语言称为main),
系统安排执行这个section的中的代码。
* .interp
该section保存了程序的解释程序(interpreter)的路径。假如在这个section
中有一个可装载的段,那么该section的属性的SHF_ALLOC位将被设置;否则,
该位不会被设置。看第二部分获得更多的信息。
* .line
该section包含编辑字符的行数信息,它描述源程序与机器代码之间的对于
关系。该section内容不明确的。
* .note
该section保存一些信息,使用“Note Section”(在第二部分)中提到的格式。
* .plt
该section保存着过程连接表(Procedure Linkage Table)。看第一部分的
``Special Sections''和第二部分的“Procedure Linkage Table”。
* .rel and .rela
这些section保存着重定位的信息,看下面的``Relocation''描述。
假如文件包含了一个可装载的段,并且这个段是重定位的,那么该section的
属性将设置SHF_ALLOC位;否则该位被关闭。按照惯例,由重定位适用
的section来提供。因此,一个重定位的section适用的是.text,那么该名字
就为.rel.text或者是.rela.text。
* .rodata and .rodata1
这些section保存着只读数据,在进程映象中构造不可写的段。看第二部分的
``Program Header''获得更多的资料。
* .shstrtab
该section保存着section名称。
* .strtab
该section保存着字符串,一般地,描述名字的字符串和一个标号的入口相关
联。假如文件有一个可装载的段,并且该段包括了符号字符串表,那么section
的SHF_ALLOC属性将被设置;否则不设置。
* .symtab
该section保存着一个符号表,正如在这个section里``Symbol Table''的
描述。假如文件有一个可装载的段,并且该段包含了符号表,那么section
的SHF_ALLOC属性将被设置;否则不设置。
* .text
该section保存着程序的``text''或者说是可执行指令。
前缀是点(.)的section名是系统保留的,尽管应用程序可以用那些保留的
section名。应用程序可以使用不带前缀的名字以避免和系统的sections
冲突。object文件格式可以让一个定义的section部分不出现在上面的列
表中。一个object文件可以有多个同样名字的section。
为处理器体系保留的section名的形成是通过置换成一个体系名的缩写。
该名字应该取自体系名,e_machine使用的就是。例如,.Foo.psect就是
在FOO体系上定义的名字。
现存的扩展名是历史遗留下来的。
Pre-existing Extensions
=======================
.sdata .tdesc
.sbss .lit4
.lit8 .reginfo
.gptab .liblist
.conflict
阅读(1678) | 评论(0) | 转发(0) |