一些节会出现在相关的组中。例如,内置函数的外部定义除了要求包含可执行指令的节外,还会要求其他信息。此附加信息可以是包含引用的字面值的只读数据节、一个或多个调试信息节或其他信息节。
组节之间可以存在内部引用。但是,如果删除了其中某节,或者将其中某节替换为另一个目标文件的副本,则这些引用将没有意义。因此,应将这些组作为一个单位包括在链接目标文件中或从中忽略。
SHT_GROUP 类型的节可定义这样分组的一组节:其中一个所包含目标文件的符号表中的符号名称将为节组提供签名。SHT_GROUP 节的节头会指定标识符号项。sh_link 成员包含符号表节的节头索引,其中会包含该项。sh_info 成员包含标识项的符号表索引。节头的 sh_flags 成员值为零。节名 (sh_name) 未指定。
SHT_GROUP 节的节数据是 Elf32_Word 项的数组。第一项是一个标志字。其余项是一系列节头索引。
表 7–11 ELF 组节标志
名称 |
值 |
---|---|
GRP_COMDAT |
0x1 |
GRP_COMDAT 是一个 COMDAT 组。该组可以与另一个目标文件中的 COMDAT 组重复,其中,重复的定义是具有相同的组签名。在这类情况下,链接编辑器将仅保留其中一个重复组。其余组的成员会被废弃。
SHT_GROUP 节中的节头索引可标识构成该组的节。这些节必须在其 sh_flags 节头成员中设置 SHF_GROUP 标志。如果链接编辑器决定删除节组,则它将删除组的所有成员。
为了便于删除组,并且不保留未使用的引用,同时仅对符号表进行最少的处理,请遵循以下规则:
必须使用符号表各项中包含的 STB_GLOBAL 或 STB_WEAK 绑定和节索引 SHN_UNDEF,才能从组外的节中引用包含该组的节。包含引用的目标文件中定义的相同符号必须具有与独立于该引用的符号表项。组外的各节不能引用对组节中包含的地址具有 STB_LOCAL 绑定的符号,包括 STT_SECTION 类型的符号。
不允许从组外对包含该组的节进行非符号引用。例如,不能在 sh_link 或 sh_info 成员中使用组成员的节头索引。
如果废弃了某个组的成员,则可以删除所定义的与该组某一节相关的符号表项。如果此符号表项包含在不属于该组的符号表节中,则会进行此删除。