JavaScript is required to for searching.
跳过导航链接
退出打印视图
Oracle Solaris 11.1 链接程序和库指南     Oracle Solaris 11.1 Information Library (简体中文)
为本文档评分
search filter icon
search icon

文档信息

前言

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

1.  Oracle Solaris 链接编辑器介绍

2.  链接编辑器

3.  运行时链接程序

4.  共享目标文件

第 2 部分快速参考

5.  链接编辑器快速参考

第 3 部分高级主题

6.  直接绑定

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

使用 elfdump 分析文件

底层系统

延迟装入动态依赖项

与位置无关的代码

-K pic-K PIC 选项

删除未使用的材料

删除未使用的节

删除未使用的文件

删除未使用的依赖项

最大化可共享性

将只读数据移动到文本中

折叠多重定义数据

使用自动变量

动态分配缓冲区

最小化分页活动

重定位

符号查找

执行重定位的时间

组合重定位节

复制重定位

使用 -B symbolic 选项

配置共享目标文件

8.  Mapfile

9.  接口和版本控制

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

11.  可扩展性机制

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

12.  目标文件格式

13.  程序装入和动态链接

14.  线程局部存储

第 5 部分附录

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

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

索引

请告诉我们如何提高我们的文档:
过于简略
不易阅读或难以理解
重要信息缺失
错误的内容
需要翻译的版本
其他
Your rating has been updated
感谢您的反馈!

您的反馈将非常有助于我们提供更好的文档。 您是否愿意参与我们的内容改进并提供进一步的意见?

与位置无关的代码

动态可执行文件中的代码通常是位置相关的,并且与内存中的某个固定地址相关联。相反,共享目标文件可装入不同进程中的不同地址。位置无关代码不与特定地址关联。这种无关性允许在每个使用此类代码的进程中的不同地址有效地执行代码。建议在创建共享目标文件时使用与位置无关的代码。

使用 -K pic 选项,编译器可以生成与位置无关的代码。

如果共享目标文件根据位置相关代码生成,则在运行时可能需要修改文本段。通过此修改,可以为已装入目标文件的位置指定可重定位引用。本段的重定位需要将此段重映射为可写段。这种修改需要预留交换空间,并且会形成此进程的文本段专用副本。此文本段不再供多个进程共享。通常,位置相关代码比相应的与位置无关的代码需要更多的运行时重定位。总体而言,处理文本重定位的开销可能会严重降低性能。

根据与位置无关的代码生成共享目标文件时,会通过共享目标文件数据段中的数据间接生成可重定位引用。文本段中的代码不需要进行任何修改。所有重定位更新都会应用于数据段中的相应项。有关特定间接技术的更多详细信息,请参见全局偏移表(特定于处理器)过程链接表(特定于处理器)

如果存在文本重定位,运行时链接程序便会尝试处理这些重定位。但是,某些重定位无法在运行时实现。

x64 位置相关代码序列可生成的代码只能装入内存的低 32 位。任何地址的高 32 位必须全部为零。由于共享目标文件通常装入内存高位,因此需要地址的高 32 位。这样,x64 共享目标文件中位置相关代码便无法满足重定位要求。在共享目标文件中使用此类代码会导致出现运行时重定位错误。

$ prog
ld.so.1: prog: fatal: relocation error: R_AMD64_32: file \
    libfoo.so.1: symbol (unknown): value 0xfffffd7fff0cd457 does not fit

与位置无关的代码可以装入内存中的任何区域,从而可以满足 x64 共享目标文件的要求。

这种情况不同于用于 64 位 SPARCV9 代码的缺省 ABS64 模式。这种位置相关代码通常兼容整个 64 位地址范围。因此,位置相关代码序列可以存在于 SPARCV9 共享目标文件中。针对 64 位 SPARCV9 代码使用 ABS32 模式或 ABS44 模式仍会导致无法在运行时解析的重定位。但是,这两种模式都需要运行时链接程序对文本段进行重定位。

无论运行时链接程序功能如何,也无论重定位要求的差异如何,共享目标文件都应该使用与位置无关的代码生成。

可以根据文本段确定需要重定位的共享目标文件。以下示例使用 elfdump(1) 确定是否存在 TEXTREL 项动态项。

$ cc -o libfoo.so.1 -G -R. foo.c
$ elfdump -d libfoo.so.1 | grep TEXTREL
       [9]  TEXTREL       0

注 - TEXTREL 项的值无关紧要。共享目标文件中存在此项表示存在文本重定位。


要防止创建包含文本重定位的共享目标文件,可使用链接编辑器的 -z text 标志。此标志会导致链接编辑器生成指示将位置相关代码源用作输入的诊断。以下示例显示位置相关代码如何导致无法生成共享目标文件。

$ cc -o libfoo.so.1 -z text -G -R. foo.c
Text relocation remains                       referenced
    against symbol                  offset      in file
foo                                 0x0         foo.o
bar                                 0x8         foo.o
ld: fatal: relocations remain against allocatable but \
non-writable sections

因为通过 foo.o 文件生成了位置相关代码,因此将根据文本段生成两个重定位。如有可能,这些诊断会指明执行重定位所需的任何符号引用。在这种情况下,将根据符号 foobar 进行重定位。

如果包括手写汇编程序代码,但不包括相应的位置无关原型,则在共享目标文件中也会出现文本重定位。


注 - 可能需要使用一些简单的源文件进行实验,以确定启用位置无关性的编码序列。请使用编译器功能来生成中间汇编程序输出。


-K pic-K PIC 选项

对于 SPARC 二进制文件,-K pic 选项与备用 -K PIC 选项之间的细微差异会影响对全局偏移表项的引用。请参见全局偏移表(特定于处理器)

全局偏移表是一个指针数组,对于 32 位(4 个字节)和 64 位(8 个字节)目标文件,其项大小为常量。以下代码序列可引用 -K pic 下的某个项。

        ld    [%l7 + j], %o0    ! load &j into %o0

其中,%l7 是执行引用的目标文件的 _GLOBAL_OFFSET_TABLE_ 符号的预计算值。

此代码序列为全局偏移表项提供了 13 位位移常量。因此,此位移为 32 位目标文件提供了 2048 个唯一项,为 64 位目标文件提供了 1024 个唯一项。如果创建目标文件需要的项数多于可用项数,则链接编辑器会生成一个致命错误。

$ cc -K pic -G -o lobfoo.so.1 a.o b.o ... z.o
ld: fatal: too many symbols require `small' PIC references:
        have 2050, maximum 2048 -- recompile some modules -K PIC.

要克服这种错误情况,可使用 -K PIC 选项编译某些输入可重定位目标文件。此选项为全局偏移表项提供 32 位常量。

        sethi %hi(j), %g1
        or    %g1, %lo(j), %g1    ! get 32–bit constant GOT offset
        ld    [%l7 + %g1], %o0    ! load &j into %o0

可以使用带 -G 选项的 elfdump(1) 查看目标文件的全局偏移表要求。还可以使用链接编辑器调试标记 -D got,detail 在链接编辑过程中检查这些项的处理。

理论上,使用 -K pic 模型对经常访问的数据项有益。可以使用这两种模型引用单个项。但是,确定哪些可重定位目标文件应该使用其中一个选项进行编译可能会相当耗时,并且不会显著改善性能。通常,使用 -K PIC 选项可轻松重新编译所有可重定位目标文件。