SYMBOL_SCOPE 和 SYMBOL_VERSION 指令用于指定全局符号的作用域和属性。SYMBOL_SCOPE 在未命名的基础符号版本的上下文中工作,而 SYMBOL_VERSION 用于将符号收集到显式命名的全局版本中。SYMBOL_VERSION 指令允许创建稳定接口,该接口支持目标文件以向下兼容方式发展。
SYMBOL_VERSION 的语法如下。
SYMBOL_VERSION version_name { symbol_scope: *; symbol_name; symbol_name { ASSERT = { ALIAS = symbol_name; BINDING = symbol_binding; TYPE = symbol_type; SIZE = size_value; SIZE = size_value[count]; VALUE = value; }; AUXILIARY = soname; FILTER = soname; FLAGS = symbol_flags....; SIZE = size_value; SIZE = size_value[count]; TYPE = symbol_type; VALUE = value; }; } [inherited_version_name....];
SYMBOL_SCOPE 不接受版本名称,除此之外都相同。
SYMBOL_SCOPE { .... };
在 SYMBOL_VERSION 指令中,version_name 为该符号定义集合提供一个标签。该标签标识输出目标文件中的 version definition。可以指定一个或多个由空格分隔的继承版本 (inherited_version_name),这时新定义的版本将从命名的版本继承。请参见Chapter 9, 接口和版本控制。
symbol_scope 定义 SYMBOL_SCOPE 或 SYMBOL_VERSION 指令中符号的作用域。缺省情况下,符号被假定为具有全局作用域。通过指定 symbol_scope 并后跟一个冒号 (:) 可以修改此缺省设置。这些行确定其后所有符号的符号作用域,直至后续作用域声明做出更改。下表给出了可能的作用域值及其含义。
|
symbol_name 是符号的名称。该名称可生成符号定义或符号引用,具体取决于任何限定属性。在最简单的没有任何限定属性的形式中,将创建符号引用。该引用与使用–Defining Additional Symbols with the -u option中所讨论的 使用 -u 选项定义其他符号 选项生成的引用完全相同。通常,如果符号名称后跟任何限定属性,则使用关联的属性生成符号定义。
定义了局部作用域时,可以将符号名称定义为特殊自动缩减指令 "*"。没有显式定义可见性的符号将在所生成的动态目标文件中降级为局部绑定。显式可见性定义源自 mapfile 定义或封装在可重定位目标文件中的可见性定义。类似地,定义了 eliminate(删除)作用域时,可以将符号名称定义为特殊自动删除指令 "*"。没有显式定义可见性的符号将从所生成的动态目标文件中删除。
如果指定了 SYMBOL_VERSION 指令,或者如果使用 SYMBOL_VERSION 或 SYMBOL_SCOPE 指定了自动缩减,则会在所创建的映像中记录版本控制信息。如果此映像是可执行目标文件或共享目标文件,则还会应用任何符号缩减。
如果要创建的映像是可重定位目标文件,则缺省情况下不会应用符号缩减。在这种情况下,任何符号缩减都将记录在版本控制信息中。当最终使用可重定位目标文件来生成可执行文件或共享目标文件时,将应用这些符号缩减。在生成可重定位目标文件时,可以使用链接编辑器的 –B reduce 选项强制执行符号缩减。
Chapter 9, 接口和版本控制中提供了版本控制信息的更详细说明。
symbol_name 可单独列出,以便仅将符号分配给一个版本和/或指定其作用域。可以在 {} 括号中指定可选符号属性。下面将说明各个有效属性。
ASSERT 属性用于指定符号的预期特征。链接编辑器会比较通过链接编辑所获得的符号特征与 ASSERT 属性指定的符号特征。如果实际属性与声明的属性不一致,则会发出致命错误并且不会创建输出目标文件。
ASSERT 属性的解释取决于是使用 STUB_OBJECT 指令还是使用 –z stub 命令行选项。三种可能的情况如下所述。
不使用 STUB_OBJECT 指令时,将不需要 ASSERT 属性。但是,如果 ASSERT 属性存在,则会根据通过链接编辑收集到的实际值对其属性进行验证。如果任何 ASSERT 属性与其关联的实际值不匹配,则链接编辑过程将终止且不成功。
使用 STUB_OBJECT 指令且指定了 –z stub 命令行选项时,链接编辑器将使用 ASSERT 指令定义目标文件提供的全局符号的属性。请参见桩目标文件。
使用 STUB_OBJECT 指令但未指定 –z stub 命令行选项时,链接编辑器要求所获得的目标文件中的所有全局数据都有一个将其声明为数据并提供大小的关联 ASSERT 指令。在此模式下,如果未指定 TYPE ASSERT 属性,则假定为 GLOBAL。类似地,如果未指定 SH_ATTR,则假定为缺省值 BITS。这些缺省值可确保桩目标文件和实际目标文件的数据属性是兼容的。所获得的 ASSERT 语句的计算方式与上述第一种情况相同。请参见STUB_OBJECT 指令。
ASSERT 接受以下属性。
为之前定义的符号定义别名。别名符号具有与主符号相同的类型、值和大小。ALIAS 属性不能与 TYPE、SIZE 和 SH_ATTR 属性一起使用。指定了 ALIAS 时,类型、大小和节属性将从别名符号中获取。
指定 ELF symbol_binding,它可以是 <sys/elf.h> 中定义的任意 STB_ 值,但去掉 STB_ 前缀。例如,GLOBAL 或 WEAK。
指定 ELF symbol_type,它可以是 <sys/elf.h> 中定义的任何 STT_ 常量,且不带 STT_ 前缀。例如,OBJECT、COMMON 或 FUNC。此外,为与其他 mapfile 使用情况兼容,还可以分别为 STT_FUNC 和 STT_OBJECT 指定 FUNCTION 和 DATA。TYPE 不能与 ALIAS 一起使用。
指定与符号关联的节的属性。Table 8–9 列出了可指定的 section_attributes。SH_ATTR 不能与 ALIAS 一起使用。
指定预期符号大小。SIZE 不能与 ALIAS 一起使用。size_value 参数的语法如 SIZE 属性的讨论中所述。请参见 SIZE 属性。
指定预期的符号值。
|
指示此符号是共享目标文件名称 (soname) 的辅助过滤器。请参见生成辅助过滤器。
指示此符号是共享目标文件 name 的过滤器。请参见生成标准过滤器。过滤器符号不需要输入可重定位目标文件提供任何后备实现。因此,使用此指令并定义符号的类型可以创建绝对符号表项。
symbol_flags 将符号属性指定为一个或多个以下值的空格分隔列表。
|
设置大小属性。此属性会导致创建符号定义。
size_value 参数可以是数字值,或者是符号名称 addrsize。addrsize 表示可保存一个内存地址的计算机字的大小。在生成 32 位目标文件时,链接编辑器会将 addrsize 替换为值 4,在生成 64 位目标文件时替换为值 8。addrsize 对于表示类型为 long 的指针变量和 C 变量的大小很有用,因为它会自动针对 32 位和 64 位目标文件进行调整,而无需使用条件输入。
可以选择为 size_value 参数添加一个括在方括号中的 count 值后缀。如果存在 count,则 size_value 和 count 将相乘以得出最终的大小值。
符号类型属性。此属性可以是 COMMON、DATA 或 FUNCTION。COMMON 会生成一个暂定符号定义。DATA 和 FUNCTION 会生成一个节符号定义或绝对符号定义。请参见符号表节。
数据属性会导致创建 OBJT 符号。带有大小但不含值的数据属性会通过将符号与某个 ELF 节相关联来创建节符号。此节将填充零。函数属性会导致创建 FUNC 符号。
带有大小但不含值的函数属性会通过将符号与某个 ELF 节相关联来创建节符号。一个由链接编辑器生成的带有以下签名的 void 函数将指定给此节。
void (*)(void)
含有值的数据或函数属性将生成相应符号类型并带有一个绝对 ABS 节索引。
创建节数据符号对于创建过滤器很有用。从可执行文件中对过滤器的节数据符号的外部引用会导致生成相应的复制重定位。请参见复制重定位。
指示值属性。此属性会导致创建符号定义。