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

文档信息

前言

1.  Oracle Solaris 链接编辑器介绍

2.  链接编辑器

调用链接编辑器

直接调用

使用编译器驱动程序

32 位链接编辑器和 64 位链接编辑器

跨链接编辑

指定链接编辑器选项

输入文件处理

归档处理

共享目标文件处理

与其他库链接

库命名约定

同时链接共享目标文件和归档

命令行中归档的位置

链接编辑器搜索的目录

使用命令行选项

使用环境变量

运行时链接程序搜索的目录

初始化节和终止节

符号处理

符号解析

简单解析

复杂解析

致命解析

未定义符号

生成可执行输出文件

生成共享目标文件输出文件

弱符号

输出文件中的暂定符号顺序

定义其他符号

使用 -u 选项定义其他符号

定义符号引用

定义绝对符号

定义暂定 (tentative) 符号

扩充符号定义

缩减符号作用域

删除符号

外部绑定

字符串表压缩

生成输出文件

标识功能要求

标识平台功能

标识计算机功能

标识硬件功能

标识软件功能

软件功能帧指针处理

创建符号功能函数系列

创建符号功能数据项系列

将目标文件功能转换为符号功能

功能系列试验

重定位处理

位移重定位

桩目标文件

调试帮助

3.  运行时链接程序

4.  共享目标文件

5.  应用程序二进制接口与版本控制

6.  支持接口

7.  目标文件格式

8.  线程局部存储

9.  Mapfile

A.  链接编辑器快速参考

B.  版本控制快速参考

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

D.  直接绑定

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

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

索引

桩目标文件

桩目标文件是可提供与实际目标文件相同的链接接口但不包含代码或数据的共享目标文件,完全由 mapfile 生成。桩目标文件不能在运行时使用。不过,可以根据桩目标文件生成应用程序,桩目标文件可以提供在运行时要使用的实际目标文件名称。

在生成桩目标文件时,链接编辑器将忽略在命令行中指定的任何目标文件或库文件,无需存在这些文件即可生成桩目标文件。由于可以省略编译步骤,并且相对而言链接编辑器只需进行少量操作,因此可以很快生成桩目标文件。

桩目标文件可用于解决各种生成问题。

桩共享目标文件提供了一种替代方法,用于生成可避免上述问题的代码。对于该生成产生的所有共享目标文件,可以快速生成桩目标文件。然后,使用桩目标文件代替链接时的实际目标文件,按照任意顺序并行生成所有实际共享目标文件和可执行文件。之后,保留可执行文件和实际共享目标文件,并废弃桩共享目标文件。

桩目标文件由一个或多个必须共同满足以下要求的 mapfile 生成。

如果提供了此类 mapfile,则可使用相同的命令行为每个共享目标文件生成桩共享目标文件版本和实际共享目标文件版本。将 -z stub 选项添加到桩目标文件的链接编辑中,并在实际目标文件的链接编辑中省略该选项。

为说明上述方法,以下代码将实现一个名为 idx5 的共享目标文件,该共享目标文件可从包含 5 个整数元素的数组中导出数据。对每个元素进行初始化以包含从零开始的数组索引。此数据采用全局数组、使用弱绑定的替代别名数据符号形式,并通过功能接口提供。

$ cat idx5.c
int _idx5[5] = { 0, 1, 2, 3, 4 };
#pragma weak idx5 = _idx5

int
idx5_func(int index)
{
        if ((index < 0) || (index > 4))
                return (-1);
        return (_idx5[index]);
}

必须使用 mapfile 来描述此共享目标文件提供的接口。

$ cat mapfile
$mapfile_version 2
STUB_OBJECT;
SYMBOL_SCOPE {
        _idx5   {
                        ASSERT { TYPE=data; SIZE=4[5] };
                };
        idx5    {
                        ASSERT { BINDING=weak; ALIAS=_idx5 };
                };
        idx5_func;
    local:
        *;
};

以下主程序用于打印 idx5 共享目标文件中的所有可用索引值。

$ cat main.c
#include <stdio.h>

extern int      _idx5[5], idx5[5], idx5_func(int);

int
main(int argc, char **argv)
{
        int     i;
        for (i = 0; i < 5; i++)
                (void) printf("[%d] %d %d %d\n",
                    i, _idx5[i], idx5[i], idx5_func(i));
        return (0);
}

以下命令在名为 stublib 的子目录中创建此共享目标文件的桩目标文件版本。elfdump 命令用于检验生成的目标文件是否为桩目标文件。用于生成桩目标文件的命令不同于生成实际目标文件所用命令,其差别仅在于前者添加了 -z stub 选项,并使用了不同的输出文件名。这说明很容易将桩目标文件生成代码添加到现有代码中。

$ cc -Kpic -G -M mapfile -h libidx5.so.1 idx5.c -o stublib/libidx5.so.1 -zstub
$ ln -s libidx5.so.1 stublib/libidx5.so
$ elfdump -d stublib/libidx5.so | grep STUB
      [11]  FLAGS_1           0x4000000           [ STUB ]

现在可以使用桩目标文件代替实际共享目标文件,并设置会在运行时查找实际目标文件的运行路径,以此生成主程序。不过,由于实际目标文件尚未生成,此程序还不能运行。让系统装入桩目标文件的尝试将被拒绝,因为运行时链接程序知道桩目标文件缺少实际目标文件中的实际代码和数据,因而无法执行。

$ cc main.c -L stublib -R '$ORIGIN/lib' -lidx5 -lc
$ ./a.out
ld.so.1: a.out: fatal: libidx5.so.1: open failed: \
    No such file or directory
Killed
$ LD_PRELOAD=stublib/libidx5.so.1 ./a.out
ld.so.1: a.out: fatal: stublib/libidx5.so.1: stub shared object \
    cannot be used at runtime
Killed

使用生成桩目标文件时使用的命令生成实际目标文件。省略 -z stub 选项,并指定实际输出文件的路径。

$ cc -Kpic -G -M mapfile -h libidx5.so.1 idx5.c -o lib/libidx5.so.1

一旦在 lib 子目录下生成了实际目标文件,便可以运行程序。

$ ./a.out
[0] 0 0 0
[1] 1 1 1
[2] 2 2 2
[3] 3 3 3
[4] 4 4 4