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.  共享目标文件

命名约定

记录共享目标文件名称

在归档中包含共享目标文件

已记录名称冲突

具有依赖项的共享目标文件

依赖项排序

作为过滤器的共享目标文件

生成标准过滤器

生成辅助过滤器

过滤组合

filtee 处理

第 2 部分快速参考

5.  链接编辑器快速参考

第 3 部分高级主题

6.  直接绑定

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

8.  mapfile

9.  接口和版本控制

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

11.  可扩展性机制

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

12.  目标文件格式

13.  程序装入和动态链接

14.  线程局部存储

第 5 部分附录

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

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

索引

命名约定

链接编辑器和运行时链接程序都不会根据文件名解释文件。将检查所有文件以确定其 ELF 类型(请参见ELF 头)。链接编辑器使用此信息来推导文件的处理要求。但是,共享目标文件通常遵循两种命名约定之一,具体取决于这些目标文件是用作编译环境的一部分还是用作运行时环境的一部分。

用作编译环境的一部分时,共享目标文件由链接编辑器读取并处理。虽然可以在传递到链接编辑器的命令中通过显式文件名指定这些共享目标文件,但是通常使用 -l 选项来利用链接编辑器的库搜索功能。请参见共享目标文件处理

应该使用前缀 lib 和后缀 .so 来指定适用于此链接编辑器处理的共享目标文件。例如,/lib/libc.so 便是可用于编译环境的标准 C 库的共享目标文件。根据约定,64 位共享目标文件位于 lib 目录中名为 64 的子目录中。例如,/lib/libc.so.1 的对应 64 位名称是 /lib/64/libc.so.1

用作运行时环境的一部分时,共享目标文件由运行时链接程序读取和处理。要允许在一系列软件发行版中对共享目标文件的导出接口进行更改,可将共享目标文件作为版本化文件名提供。

版本化文件名通常采用 .so 后缀后跟版本号的形式。例如,/lib/libc.so.1 便是可用于运行时环境的第一版标准 C 库的共享目标文件。

如果从不打算在编译环境中使用共享目标文件,则可能会从共享目标文件名称中删除常规的 lib 前缀。仅用于 dlopen(3C) 的共享目标文件便是此类共享目标文件。仍然建议使用后缀 .so 来指示实际文件类型。此外,强烈建议使用版本号以便在一系列软件发行版中提供正确的共享目标文件绑定。第 9 章更详细地介绍了版本控制。


注 - dlopen(3C) 中使用的共享目标文件名称通常表示为不包含 "/" 的简单文件名。然后,运行时链接程序可以使用一组规则来查找实际文件。有关更多详细信息,请参见装入其他目标文件


记录共享目标文件名称

缺省情况下,动态可执行文件或共享目标文件中的依赖项记录将是链接编辑器所引用的关联共享目标文件的文件名。例如,根据同一共享目标文件 libfoo.so 生成的以下动态可执行文件会导致对同一依赖项具有不同的解释。

$ cc -o ../tmp/libfoo.so -G foo.o
$ cc -o prog main.o -L../tmp -lfoo
$ elfdump -d prog | grep NEEDED
       [1]  NEEDED        0x123         libfoo.so.1

$ cc -o prog main.o ../tmp/libfoo.so
$ elfdump -d prog | grep NEEDED
       [1]  NEEDED        0x123         ../tmp/libfoo.so

$ cc -o prog main.o /usr/tmp/libfoo.so
$ elfdump -d prog | grep NEEDED
       [1]  NEEDED        0x123         /usr/tmp/libfoo.so

如这些示例所示,这种记录依赖项机制会因编译技术的不同而出现不一致性。此外,在链接编辑过程中引用的共享目标文件的位置也可能会与已安装系统上的共享目标文件的最终位置有所不同。为了提供更一致的指定依赖项的方法,共享目标文件可以在自身中记录运行时据以引用共享目标文件的文件名。

在链接编辑共享目标文件过程中,可以使用 -h 选项在共享目标文件自身中记录其运行时名称。在以下示例中,将在文件自身中记录共享目标文件的运行时名称 libfoo.so.1。此标识称为 soname

$ cc -o ../tmp/libfoo.so -G -K pic -h libfoo.so.1 foo.c

以下示例说明如何使用 elfdump(1) 和引用具有 SONAME 标记的项来显示 soname 记录。

$ elfdump -d ../tmp/libfoo.so | grep SONAME
       [1]  SONAME        0x123         libfoo.so.1

链接编辑器处理包含 soname 的共享目标文件时,此名称便是作为要生成的输出文件中的依赖项记录的名称。

如果在上一示例的创建动态可执行文件 prog 的过程中使用此新版本的 libfoo.so,则所有三种创建可执行文件的方法都会记录同一依赖项。

$ cc -o prog main.o -L../tmp -lfoo
$ elfdump -d prog | grep NEEDED
       [1]  NEEDED        0x123         libfoo.so

$ cc -o prog main.o ../tmp/libfoo.so
$ elfdump -d prog | grep NEEDED
       [1]  NEEDED        0x123         libfoo.so

$ cc -o prog main.o /usr/tmp/libfoo.so
$ elfdump -d prog | grep NEEDED
       [1]  NEEDED        0x123         libfoo.so

在上述示例中,使用 -h 选项来指定不包含 "/" 的简单文件名。借助此约定,运行时链接程序可以使用一组规则来查找实际文件。有关更多详细信息,请参见查找共享目标文件依赖项

在归档中包含共享目标文件

如果共享目标文件始终通过归档库进行处理,则在共享目标文件中记录 soname 是基本的机制。

归档可以根据一个或多个共享目标文件生成,并可用于生成动态可执行文件或共享目标文件。可以从归档中提取共享目标文件来满足链接编辑的要求。与处理可重定位目标文件(串联成要创建的输出文件)不同,从归档中提取的任何共享目标文件都将记录为依赖项。有关归档提取条件的更多详细信息,请参见归档处理

归档成员的名称由链接编辑器构造,并且由归档名称和归档中的目标文件串联而成。例如:

$ cc -o libfoo.so.1 -G -K pic foo.c
$ ar -r libfoo.a libfoo.so.1
$ cc -o main main.o libfoo.a
$ elfdump -d main | grep NEEDED
       [1]  NEEDED        0x123         libfoo.a(libfoo.so.1)

由于具有此串联名称的文件无法在运行时存在,因此,在共享目标文件中提供 soname 是生成有意义的依赖项运行时文件名的唯一方法。


注 - 运行时链接程序不会从归档中提取目标文件。因此,在此示例中,必须从归档中提取所需的共享目标文件依赖项,并使其可用于运行时环境。


已记录名称冲突

使用共享目标文件创建动态可执行文件或其他共享目标文件时,链接编辑器会执行多项一致性检查。这些检查可确保输出文件中记录的任何依赖项名称都是唯一的。

如果在链接编辑过程中用作输入文件的两个共享目标文件包含相同的 soname,依赖项名称可能会发生冲突。例如:

$ cc -o libfoo.so -G -K pic -h libsame.so.1 foo.c
$ cc -o libbar.so -G -K pic -h libsame.so.1 bar.c
$ cc -o prog main.o -L. -lfoo -lbar
ld: fatal: recording name conflict: file `./libfoo.so' and \
    file `./libbar.so' provide identical dependency names: libsame.so.1
ld: fatal: File processing errors. No output written to prog

如果某个没有已记录 soname 的共享目标文件的文件名与同一链接编辑过程使用的其他共享目标文件的 soname 匹配,则也会出现类似的错误情况。

如果要生成的共享目标文件的运行时名称与它的某个依赖项匹配,则链接编辑器也会报告名称冲突。

$ cc -o libbar.so -G -K pic -h libsame.so.1 bar.c -L. -lfoo
ld: fatal: recording name conflict: file `./libfoo.so' and \
    -h option provide identical dependency names: libsame.so.1
ld: fatal: File processing errors. No output written to libbar.so