使用目标文件的节头表,可以定位文件的所有节。节头表是 Elf32_Shdr 或 Elf64_Shdr 结构的数组。节头表索引是此数组的下标。ELF 头的 e_shoff 成员表示从文件的起始位置到节头表的字节偏移。e_shnum 成员表示节头表包含的项数。e_shentsize 成员表示每一项的大小(以字节为单位)。
如果节数大于或等于 SHN_LORESERVE (0xff00),则 e_shnum 值为 SHN_UNDEF (0)。节头表的实际项数包含在节头中索引为 0 的 sh_size 字段中。否则,初始项的 sh_size 成员值为零。
如果上下文中限制了索引大小,则会保留部分节头表索引。例如,符号表项的 st_shndx 成员以及 ELF 头的 e_shnum 和 e_shstrndx 成员。在这类上下文中,保留的值不表示目标文件中的实际各节。同样在这类上下文中,转义值表示会在其他位置(较大字段中)找到实际节索引。
表 12-4 ELF 特殊节索引
|
注 - 虽然索引 0 保留为未定义的值,但节头表包含对应于索引 0 的项。即,如果 ELF 头的 e_shnum 成员表示文件在节头表中具有 6 项,则这些节的索引为 0 到 5。初始项的内容会在本节的后面指定。
此节索引用于在可重定位目标文件中提供临时符号定义。保留供 dtrace(1M) 内部使用。
与 SHF_LINK_ORDER 和 SHF_ORDERED 节标志一起提供初始和最终节排序。请参见表 12-8。
相对于此节而定义的符号为通用符号,如 FORTRAN COMMON 或未分配的 C 外部变量。这些符号有时称为暂定符号。
保留索引的范围的上界。系统保留了 SHN_LORESERVE 和 SHN_HIRESERVE 之间的索引(包括这两个值)。这些值不会引用节头表。节头表不包含对应于保留索引的项。
节包含目标文件中的所有信息,但 ELF 头、程序头表和节头表除外。此外,目标文件中的各节还满足多个条件:
目标文件中的每一节仅有一个说明该节的节头。可能会有节头存在但节不存在的情况。
每一节在文件中占用可能为空的一系列相邻字节。
文件中的各节不能重叠。文件中的字节不能位于多个节中。
目标文件可以包含非活动空间。各种头和节可能不会包括目标文件中的每个字节。非活动数据的内容未指定。
节头具有以下结构。请参见 sys/elf.h。
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; typedef struct { Elf64_Word sh_name; Elf64_Word sh_type; Elf64_Xword sh_flags; Elf64_Addr sh_addr; Elf64_Off sh_offset; Elf64_Xword sh_size; Elf64_Word sh_link; Elf64_Word sh_info; Elf64_Xword sh_addralign; Elf64_Xword sh_entsize; } Elf64_Shdr;
节的名称。此成员值是节头字符串表节的索引,用于指定以空字符结尾的字符串的位置。表 12-10 中列出了节名称及其说明。
用于将节的内容和语义分类。表 12-5 中列出了节类型及其说明。
节可支持用于说明杂项属性的 1 位标志。表 12-8 中列出了标志定义。
如果节显示在进程的内存映像中,则此成员会指定节的第一个字节所在的地址。否则,此成员值为零。
从文件的起始位置到节中第一个字节的字节偏移。对于 SHT_NOBITS 节,此成员表示文件中的概念性偏移,因为该节在文件中不占用任何空间。
节的大小(以字节为单位)。除非节类型为 SHT_NOBITS,否则该节将在文件中占用 sh_size 个字节。SHT_NOBITS 类型的节大小可以不为零,但该节在文件中不占用任何空间。
节头表索引链接,其解释依赖于节类型。表 12-9 说明了相应的值。
额外信息,其解释依赖于节类型。表 12-9 说明了相应的值。如果此节头的 sh_flags 字段包含属性 SHF_INFO_LINK,则此成员表示节头表索引。
一些节具有地址对齐约束。例如,如果某节包含双字,则系统必须确保整个节双字对齐。在此情况下,sh_addr 的值在以 sh_addralign 的值为模数进行取模时,同余数必须等于 0。当前,仅允许使用 0 和 2 的正整数幂。值 0 和 1 表示节没有对齐约束。
一些节包含固定大小的项的表,如符号表。对于这样的节,此成员会指定每一项的大小(以字节为单位)。如果节不包含固定大小的项的表,则此成员值为零。
节头的 sh_type 成员用于指定节的语义,如下表中所示。
表 12-5 ELF 节类型 sh_type
|
标识符号表。通常,SHT_SYMTAB 节会提供用于链接编辑的符号。作为完整的符号表,该表可能包含许多对于动态链接不必要的符号。因此,目标文件还可以包含一个 SHT_DYNSYM 节,其中包含一组尽可能少的动态链接符号,从而节省空间。
SHT_DYNSYM 还可以使用 SHT_SUNW_LDYNSYM 节进行扩充。此附加节为运行时环境提供局部函数符号,但对于动态链接来说不是必需的。当不可分配的 SHT_SYMTAB 不可用或已从文件中剥离时,调试器通过使用此节可在运行时上下文中产生精确的栈跟踪。此节还可以为运行时环境提供其他符号信息,以便与 dladdr(3C) 一起使用。
如果 SHT_SUNW_LDYNSYM 节和 SHT_DYNSYM 节同时存在,链接编辑器会将这两者的数据区域紧邻彼此放置。SHT_SUNW_LDYNSYM 节位于 SHT_DYNSYM 节的前面。这种放置方式可以使两个表看起来像是一个更大的连续符号表,其中包含 SHT_SYMTAB 中的缩减符号集合。
有关详细信息,请参见符号表节。
标识字符串表。目标文件可以有多个字符串表节。有关详细信息,请参见字符串表节。
标识包含显式加数的重定位项,如 32 位目标文件类的 Elf32_Rela 类型。目标文件可以有多个重定位节。有关详细信息,请参见重定位节。
标识符号散列表。动态链接的目标文件必须包含符号散列表。当前,目标文件只能有一个散列表,但此限制在将来可能会放宽。有关详细信息,请参见散列表节。
标识动态链接的信息。当前,目标文件只能有一个动态节。有关详细信息,请参见动态节。
标识以某种方法标记文件的信息。有关详细信息,请参见注释节。
标识在文件中不占用任何空间,但在其他方面与 SHT_PROGBITS 类似的节。虽然此节不包含任何字节,但 sh_offset 成员包含概念性文件偏移。
标识不包含显式加数的重定位项,如 32 位目标文件类的 Elf32_Rel 类型。目标文件可以有多个重定位节。有关详细信息,请参见重定位节。
标识包含指针数组的节,这些指针指向初始化函数。数组中的每个指针都被视为不返回任何值的无参数过程。有关详细信息,请参见初始化节和终止节。
标识包含指针数组的节,这些指针指向终止函数。数组中的每个指针都被视为不返回任何值的无参数过程。有关详细信息,请参见初始化节和终止节。
标识包含指针数组的节,这些指针指向在其他所有初始化函数之前调用的函数。数组中的每个指针都被视为不返回任何值的无参数过程。有关详细信息,请参见初始化节和终止节。
标识节组。节组标识一组相关的节,这些节必须作为一个单元由链接编辑器进行处理。SHT_GROUP 类型的节只能出现在可重定位目标文件中。有关详细信息,请参见组节。
标识包含扩展节索引的节,扩展节索引与符号表关联。如果符号表引用的任何节头索引包含转义值 SHN_XINDEX,则需要关联的 SHT_SYMTAB_SHNDX。
SHT_SYMTAB_SHNDX 节是 Elf32_Word 值的数组。对于关联的符号表项中的每一项,此数组都包含对应的一项。这些值表示针对其定义符号表项的节头索引。仅当对应符号表项的 st_shndx 字段包含转义值 SHN_XINDEX 时,匹配的 Elf32_Word 才会包含实际的节头索引。否则,该项必须为 SHN_UNDEF (0)。
收集功能系列成员的索引数组。该数组的第一个元素是链版本号。此元素的后面是以 0 结尾的功能符号索引链。每个以 0 结尾的索引组都表示一个功能系列。每个系列的第一个元素是功能前置符号。后面的元素指向系列成员。有关详细信息,请参见功能节。
将符号表项与功能要求及其前置功能符号关联起来的索引数组。定义符号功能的目标文件包含 SHT_SUNW_cap 节。SHT_SUNW_cap 节头信息指向关联的 SHT_SUNW_capinfo 节。SHT_SUNW_capinfo 节头信息指向关联的符号表节。有关详细信息,请参见功能节。
由相邻的 SHT_SUNW_LDYNSYM 节和 SHT_DYNSYM 节构成的动态符号表的索引数组。这些索引相对于 SHT_SUNW_LDYNSYM 节的开头。这些索引引用包含内存地址的符号。该索引已进行排序,以使索引按照地址递增的顺序引用符号。
由相邻的 SHT_SUNW_LDYNSYM 节和 SHT_DYNSYM 节构成的动态符号表的索引数组。这些索引相对于 SHT_SUNW_LDYNSYM 节的开头。这些索引引用线程局部存储符号。请参见第 14 章。该索引已进行排序,以使索引按照偏移递增的顺序引用符号。
非全局符号的动态符号表。请参见前面的 SHT_SYMTAB、SHT_DYNSYM、SHT_SUNW_LDYNSYM 说明。
保留供 dtrace(1M) 内部使用。
指定功能要求。有关详细信息,请参见功能节。
注释节的处理遵循处理节的所有缺省规则。仅当注释节位于不可分配的内存中时,才会发生异常。如果未设置节头标志 SHF_ALLOC,则链接编辑器将在不给出任何提示的情况下忽略针对此节的所有未满足的重定位。
标识调试信息。使用链接编辑器的 -z strip-class 选项,或者在链接编辑之后使用 strip(1),可以将此类型的节从目标文件中剥离。
标识用于处理部分初始化的符号的数据。有关详细信息,请参见移动节。
标识允许将相同数据的多个副本减少为单个副本的节。有关详细信息,请参见COMDAT 节。
标识其他符号信息。有关详细信息,请参见Syminfo 表节。
标识此文件定义的细分版本。有关详细信息,请参见版本定义章节。
标识此文件所需的细分依赖性。有关详细信息,请参见版本依赖性节。
标识用于说明符号与文件提供的版本定义之间关系的表。有关详细信息,请参见版本符号节。
标识特定于 SPARC 的数据,使用相对于 GOT 的寻址引用这些数据。即,相对于指定给符号 _GLOBAL_OFFSET_TABLE_ 的地址的偏移。对于 64 位 SPARC,此节中的数据必须在链接编辑时绑定到偏离 GOT 地址不超过 {+-} 2^32 字节的位置。
指定保留用于应用程序的索引范围的上界。应用程序可以使用 SHT_LOUSER 和 SHT_HIUSER 之间的节类型,而不会与当前或将来系统定义的节类型产生冲突。
其他节类型值保留。如前所述,即使索引 0 (SHN_UNDEF) 标记了未定义的节引用,仍会存在对应于该索引的节头。下表显示了这些值。
表 12-6 ELF 节头表项:索引 0
|
如果节或程序头的数目超过 ELF 头数据大小,则节头 0 的各元素将用于定义扩展的 ELF 头属性。下表显示了这些值。
表 12-7 ELF 扩展的节头表项:索引 0
|
节头的 sh_flags 成员包含用于说明节属性的 1 位标志。
表 12-8 ELF 节属性标志
|
如果在 sh_flags 中设置了标志位,则该节的此属性处于启用状态。否则,此属性处于禁用状态,或者不适用。未定义的属性会保留并设置为零。
标识可以将其中包含的数据合并以消除重复的节。除非还设置了 SHF_STRINGS 标志,否则该节中的数据元素大小一致。每个元素的大小在节头的 sh_entsize 字段中指定。如果还设置了 SHF_STRINGS 标志,则数据元素会包含以空字符结尾的字符串。每个字符的大小在节头的 sh_entsize 字段中指定。
此节向链接编辑器中添加特殊排序要求。如果此节头的 sh_link 字段引用其他节(链接到的节),则会应用这些要求。如果将此节与输出文件中的其他节合并,则此节将按照相同的相对顺序(相对于这些节)显示。同样,链接到的节也将按照相同的相对顺序(相对于与其合并的节)显示。链接到的节必须是未排序的,因而不能指定 SHF_LINK_ORDER 或 SHF_ORDERED。
特殊的 sh_link 值 SHN_BEFORE 和 SHN_AFTER(请参见表 12-4)表示,已排序的节将分别位于要排序的集合中其他所有各节之前或之后。如果已排序集合中的多个节包含这些特殊值之一,则会保持输入文件链接行的顺序。
此标志的一个典型用法是生成按地址顺序引用文本或数据节的表。
如果缺少 sh_link 排序信息,则合并到输出文件一个节内的单个输入文件中的节是相邻的。这些节会与输入文件中的节一样进行相对排序。构成多个输入文件的节按照链接行顺序显示。
此节除了要求标准链接规则之外,还要求特定于操作系统的特殊处理,以避免不正确的行为。如果此节具有 sh_type 值,或者对于这些字段包含特定于操作系统范围内的 sh_flags 位,并且链接编辑器无法识别这些值,则包含此节的目标文件会由于出错而被拒绝。
此节是节组的一个成员(可能是唯一的成员)。此节必须由 SHT_GROUP 类型的节引用。只能对可重定位目标文件中包含的节设置 SHF_GROUP 标志。有关详细信息,请参见组节。
此节包含线程局部存储。进程中的每个线程都包含此数据的一个不同实例。有关详细信息,请参见第 14 章。
x64 的缺省编译模型仅用于 32 位位移。此位移限制了节的大小,并最终限制段的大小不得超过 2 GB。此属性标志用于标识可包含超过 2 GB 数据的节。此标志允许链接使用不同代码模型的目标文件。
不包含 SHF_AMD64_LARGE 属性标志的 x64 目标文件节可以由使用小代码模型的目标文件任意引用。包含此标志的节只能由使用较大代码模型的目标文件引用。例如,x64 中间代码模型目标文件可以引用包含此属性标志的节和不包含此属性标志的节中的数据。但是,x64 小代码模型目标文件只能引用不包含此标志的节中的数据。
SHF_ORDERED 是 SHF_LINK_ORDER 所提供的旧版本功能,并且已被 SHF_LINK_ORDER 取代。SHF_ORDERED 提供两种不同的功能。首先,可以指定输出节,其次,链接编辑器具有特殊排序要求。
SHF_ORDERED 节的 sh_link 字段可以构成节的链接列表。此列表以包含指向其自身的 sh_link 的最终节结束。此列表中的所有节都将指定给具有此列表中最终节的名称的输出节。
如果已排序节的 sh_info 项在相同输入文件中是有效节,则将基于由 sh_info 项所指向的节的输出文件内的相对排序,对已排序的节进行排序。sh_info 项指向的节必须尚未排序,因而不能指定 SHF_LINK_ORDER 或 SHF_ORDERED。
特殊的 sh_info 值 SHN_BEFORE 和 SHN_AFTER(请参见表 12-4)表示,已排序的节将分别位于要排序的集合中其他所有各节之前或之后。如果已排序集合中的多个节包含这些特殊值之一,则会保持输入文件链接行的顺序。
如果缺少 sh_info 排序信息,则合并到输出文件一个节内的单个输入文件中的各节是相邻的。这些节会与输入文件中的节一样进行相对排序。构成多个输入文件的节按照链接行顺序显示。
此节不包括在可执行文件或共享目标文件的链接编辑的输入中。如果还设置了 SHF_ALLOC 标志,或者存在针对此节的重定位,则会忽略此标志。
根据节类型,节头中的两个成员 sh_link 和 sh_info 包含特殊信息。
表 12-9 ELF sh_link 和 sh_info 解释
|