JavaScript is required to for searching.
跳过导航链接
退出打印视图
链接程序和库指南     Oracle Solaris 10 1/13 Information Library (简体中文)
search filter icon
search icon

文档信息

前言

第 1 部分使用链接编辑器和运行时链接程序

1.  Oracle Solaris 链接编辑器介绍

2.  链接编辑器

3.  运行时链接程序

4.  共享目标文件

第 2 部分快速参考

5.  链接编辑器快速参考

第 3 部分高级主题

6.  直接绑定

7.  生成目标文件以优化系统性能

8.  mapfile

mapfile 结构和语法

mapfile 版本

条件输入

指令语法

mapfile 指令

CAPABILITY 指令

HW 属性

HW_1 / HW_2 属性

MACHINE 属性

PLATFORM 属性

SF 属性

SF_1 属性

DEPEND_VERSIONS 指令

ALLOW 属性

REQUIRE 属性

HDR_NOALLOC 指令

PHDR_ADD_NULL 指令

LOAD_SEGMENT / NOTE_SEGMENT / NULL_SEGMENT 指令

ALIGN 属性(仅限 LOAD_SEGMENT)

ASSIGN_SECTION 属性

DISABLE 属性

FLAGS 属性(仅限 LOAD_SEGMENT)

IS_ORDER 属性

MAX_SIZE 属性(仅限 LOAD_SEGMENT)

NOHDR 属性(仅限 LOAD_SEGMENT)

OS_ORDER 属性

PADDR 属性(仅限 LOAD_SEGMENT)

ROUND 属性(仅限 LOAD_SEGMENT)

SIZE_SYMBOL 属性(仅限 LOAD_SEGMENT)

VADDR(仅限 LOAD_SEGMENT)

SEGMENT_ORDER 指令

STACK 指令

STUB_OBJECT 指令

SYMBOL_SCOPE / SYMBOL_VERSION 指令

ASSERT 属性

AUXILIARY 属性

FILTER 属性

FLAGS 属性

SIZE 属性

TYPE 属性

VALUE 属性

预定义段

映射示例

示例:节到段的分配

示例:预定义节的修改

链接编辑器内部:节和段的处理

节到段的分配

预定义段和入口条件的 mapfile 指令

9.  接口和版本控制

10.  使用动态字符串标记建立依赖性

11.  可扩展性机制

第 4 部分ELF 应用程序二进制接口

12.  目标文件格式

13.  程序装入和动态链接

14.  线程局部存储

第 5 部分附录

A.  链接程序和库的更新及新增功能

B.  System V 发行版 4(版本 1)mapfile

索引

mapfile 结构和语法

mapfile 指令可以超出一行,并且可以具有任意数量的空格,包括换行符。

对于所有语法讨论,以下表示法都适用。

表 8-1 双引号文本转义序列

转义序列
含义
\a
警报(响铃)
\b
退格键
\f
换页
\n
换行
\r
回车
\t
水平制表符
\v
垂直制表符
\\
反斜杠
\'
单引号
\”
双引号
\ooo
一个八进制常数,其中 ooo 是一到三个八进制数字 (0...7)

表 8-2 mapfile 中的名称和其他广泛使用的字符串

名称
目的
segment_name
ELF 段的名称
section_name
ELF 节的名称
symbol_name
ELF 符号的名称
file_path
用于引用 ELF 目标文件或包含 ELF 目标文件的归档文件的斜杠 (/) 分隔名称的 Unix 文件路径
file_basename
file_path 的最终组件 (basename(1))
objname
file_basename 或包含在归档文件中的目标文件的名称
soname
可共享目标文件名称,用于可共享目标文件的 SONAME(例如 libc.so.1
version_name
符号版本的名称,用在 ELF 版本控制节中
inherited_version_name
由另一个符号版本继承的符号版本的名称

表 8-3 段标志

标志值
含义
READ
段是可读的
WRITE
段是可写的
EXECUTE
段是可执行的
0
清除所有权限标志
DATA
适用于目标平台上的数据段的 READ、WRITE 和 EXECUTE 标志的组合
STACK
适用于目标平台的 READ、WRITE 和 EXECUTE 标志的组合,由平台 ABI 定义

mapfile 版本

mapfile 中的第一个非注释、非空行应是 mapfile 版本声明。该声明确定文件其余部分使用的 mapfile 语言的版本。本手册中所探讨的 mapfile 语言为版本 2。

        $mapfile_version 2

没有以版本声明开始的 mapfile 将被视为是以 AT&T 为 System V 发行版 4 Unix (SVR4) 定义的原始 mapfile 语言编写的。链接编辑器保留了处理此类 mapfile 的功能。附录 B 说明了其语法。

条件输入

mapfile 中的行可以设置条件以只应用于特定 ELFCLASS(32 或 64 位)或计算机类型。

        $if expr
        ...
        [$elif expr]
        ...
        [$else]
        ...
        $endif

条件输入表达式将计算得出一个逻辑 truefalse 值。每个指令($if$elif$else$endif)都单独出现在一行中。$if 和后续 $elif 行中的表达式将依序计算,直至找到计算结果为 true 的表达式。值为 false 的行后面的文本将被放弃。成功指令行后面的文本将得到正常处理。这里的文本是指不属于条件结构的任何内容。找到成功的 $if$elif 并处理了其文本后,后续的 $elif$else 行及其文本将被放弃。如果所有表达式都为零,并且有一个 $else,则会正常处理该 $else 之后的文本。

$if 指令的作用域不能跨越多个 mapfile。$if 指令必须由使用该 $if 指令的 mapfile 中的匹配 $endif 终止,否则链接编辑器将发出错误。

链接编辑器会维护一个内部名称表,这些名称可用在由 $if$elif 计算的逻辑表达式中。启动时,该表将使用下表中适用于要创建的输出目标文件的每个名称进行初始化。

表 8-4 预定义的条件表达式名称

名称
含义
_ELF32
32 位目标文件
_ELF64
64 位目标文件
_ET_DYN
共享目标文件
_ET_EXEC
可执行目标文件
_ET_REL
可重定位目标文件
_sparc
Sparc 计算机(32 或 64 位)
_x86
x86 计算机(32 或 64 位)
true
始终定义

名称区分大小写,并且必须完全按照所示形式使用。例如,定义了 true,但未定义 TRUE。其中的任何名称都可以由自身用作逻辑表达式。例如:

        $if _ELF64
        ...
        $endif

该示例的计算结果为 true,并且在输出目标文件为 64 位时允许链接编辑器处理所含的文本。虽然这些逻辑表达式中不允许使用数字值,但值 10 例外,它们的计算结果分别为 truefalse

任何未定义的名称计算结果将为 false。使用未定义的名称 false 标记应无条件跳过的输入行是一种常见做法。

        $if false
        ...
        $endif

使用下表中所示的运算符可以编写更复杂的逻辑表达式。

表 8-5 条件表达式运算符

运算符
含义
&&
逻辑与
||
逻辑或
( expr )
子表达式
!
对后面表达式的布尔值求反

表达式从左至右计算。子表达式先于外围表达式进行计算。

例如,在为 x86 平台生成 64 位目标文件时,将计算以下构造中的行。

        $if _ELF64 && _x86
        ...
        $endif

$add 指令可用于向链接编辑器的已知名称表中添加新名称。在上述示例中,定义名称 amd64 以表示 64 位 x86 目标文件可能会便于简化 $if 指令。

        $if _ELF64 && _x86
        $add amd64
        $endif

这可用于简化上述示例。

        $if amd64
        ...
        $endif

$clear 指令是 $add 指令的逆操作。它用于从内部表中删除名称。

        $clear amd64

$add 指令的作用一直持续到使用该 $addmapfile 的最后,并且对于由相同链接操作中的链接编辑器处理的任何后续 mapfile 均可见。如果不希望这样,可在包含 $addmapfile 的最后使用 $clear 删除该定义。

最后,$error 指令会导致链接编辑器将行中的所有剩余文本打印为致命错误,并停止链接操作。$error 指令可用于确保将目标文件移植到新计算机类型的程序员将无法在无提示的情况下生成缺少必要 mapfile 定义的错误目标文件。

        $if _sparc
        ...
        $elif _x86
        ...
        $else
        $error unknown machine type
        $endif

C 语言程序员会发现用于 mapfile 条件输入的语法与 C 预处理程序宏语言类似。这种相似性是有意为之的。不过,mapfile 条件输入指令远不如 C 预处理程序提供的指令强大,这也是有意如此的。它们只能提供支持跨平台环境中的链接操作所需的最基本的功能。

这两种语言之间存在显著差异,其中包括:

如果需要进行更复杂的宏处理,则应考虑使用外部宏处理程序,例如 m4(1)。

指令语法

mapfile 指令可用于指定输出目标文件的很多方面。这些指令具有通用的语法,即为属性使用名称值对,并使用 {...} 构造表示分层结构和分组。

mapfile 指令的语法以下列通用形式为基础。

最简单的形式是一个不带值的指令名称。

        directive;

第二种形式是带有一个值或由空格分隔的值列表的指令名称。

        directive = value...;

除了所示的 "=" 赋值运算符外,还允许使用 "+=" 和 "-=" 形式的赋值。"=" 运算符将给定指令设置为给定值或值列表。"+=" 运算符用于将右侧值添加到当前值中,"-=" 运算符用于删除值。

更复杂的指令可以处理将多个属性放在花括号 {...} 中以便将其分组为一个单元的项目。

        directive [name] {
                attribute [directive = value];
                ...
        } [name];

左括号 ({) 前面可以有一个名称,用于命名给定语句的结果。类似地,在右括号 (}) 后面、终止分号 (;) 之前可以带有一个或多个可选名称。这些名称用于表示所定义的项目与其他命名项目具有某种关系。

请注意,分组中的属性的格式采用与前面所述的带有值的简单指令相同的语法,即带有一个赋值运算符 (=, +=, -=) 并后跟一个值,或是一个由空格分隔的值列表,并由分号 (;) 终止。

指令可以具有属性,后者又可以具有子属性。在这种情况下,子属性也分组在嵌套的花括号 {...} 中以反映此分层结构。

        directive [name] {
                attribute {
                        subatribute [= value];
                        ...
                };
        } [name...];

mapfile 语法对于这种嵌套所允许的深度没有限制。嵌套深度只取决于指令的要求。