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.  直接绑定

观察符号绑定

启用直接绑定

使用 -B direct 选项

使用 -z direct 选项

使用 DIRECT mapfile 关键字

直接绑定和插入

本地化符号实例

删除多次定义的同名符号

定义显式插入

阻止直接绑定到某个符号

使用 -B nodirect 选项

使用 NODIRECT mapfile 关键字

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

8.  mapfile

9.  接口和版本控制

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

11.  可扩展性机制

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

12.  目标文件格式

13.  程序装入和动态链接

14.  线程局部存储

第 5 部分附录

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

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

索引

观察符号绑定

为了解缺省的符号搜索模型并将其与直接绑定进行比较,我们使用以下组件来生成一个进程。

$ cat main.c
extern int W(), X();

int main() { return (W() + X()); }

$ cat W.c
extern int b();

int a() { return (1); }
int W() { return (a() - b()); }

$ cat w.c
int b() { return (2); }

$ cat X.c
extern int b();

int a() { return (3); }
int X() { return (a() - b()); }

$ cat x.c
int b() { return (4); }

$ cc -o w.so.1 -G -Kpic w.c
$ cc -o W.so.1 -G -Kpic W.c -R. w.so.1
$ cc -o x.so.1 -G -Kpic x.c
$ cc -o X.so.1 -G -Kpic X.c -R. x.so.1
$ cc -o prog1 -R. main.c W.so.1 X.so.1

应用程序的组件按以下顺序装入。

$ ldd prog1
        W.so.1 =>        ./W.so.1
        X.so.1 =>        ./X.so.1
        w.so.1 =>        ./w.so.1
        x.so.1 =>        ./x.so.1

W.so.1X.so.1 文件都定义了一个名为 a() 的函数。w.so.1x.so.1 文件都定义了一个名为 b() 的函数。此外,W.so.1X.so.1 文件都引用了函数 a()b()

通过设置 LD_DEBUG 环境变量,可以观察使用缺省搜索模型及最终绑定的运行时符号搜索。从运行时链接程序诊断信息中,可以发现到函数 a()b() 的绑定。

$ LD_DEBUG=symbols,bindings prog1
.....
17375: symbol=a;  lookup in file=prog1  [ ELF ]
17375: symbol=a;  lookup in file=./W.so.1  [ ELF ]
17375: binding file=./W.so.1 to file=./W.so.1: symbol `a'
.....
17375: symbol=b;  lookup in file=prog1  [ ELF ]
17375: symbol=b;  lookup in file=./W.so.1  [ ELF ]
17375: symbol=b;  lookup in file=./X.so.1  [ ELF ]
17375: symbol=b;  lookup in file=./w.so.1  [ ELF ]
17375: binding file=./W.so.1 to file=./w.so.1: symbol `b'
.....
17375: symbol=a;  lookup in file=prog1  [ ELF ]
17375: symbol=a;  lookup in file=./W.so.1  [ ELF ]
17375: binding file=./X.so.1 to file=./W.so.1: symbol `a'
.....
17375: symbol=b;  lookup in file=prog1  [ ELF ]
17375: symbol=b;  lookup in file=./W.so.1  [ ELF ]
17375: symbol=b;  lookup in file=./X.so.1  [ ELF ]
17375: symbol=b;  lookup in file=./w.so.1  [ ELF ]
17375: binding file=./X.so.1 to file=./w.so.1: symbol `b'

对函数 a()b() 其中之一的每个引用都会导致从应用程序 prog1 开始搜索关联的符号。对 a() 的每个引用都绑定到在 W.so.1 中发现的符号的第一个实例。对 b() 的每个引用都绑定到在 w.so.1 中发现的符号的第一个实例。此示例揭示了 W.so.1w.so.1 中的函数定义如何插入到 X.so.1x.so.1 中的函数定义。使用直接绑定时会发生插入,这是使用直接绑定时需要考虑的一个重要因素。下面的几节中详细介绍了插入。

此示例很简洁,很容易遵循关联的诊断信息。然而,大多数应用程序是基于许多动态组件构造的,要复杂得多。这些组件是从不同的源根基生成的,通常异步提交。

对来自复杂进程的诊断信息进行分析可能比较有难度。分析动态目标文件的接口需求的另一种方法是使用 lari(1) 实用程序。lari 分析进程的绑定信息以及每个目标文件提供的接口定义。该信息使得 lari 能够简明地转换关于进程符号依赖项的受关注信息。在分析伴随着直接绑定发生的插入时,该信息非常有用。

缺省情况下,lari 将转换它认为受关注的信息。该信息源自一个符号定义的多个实例。lariprog1 揭示以下信息。

$ lari prog1
[2:2ES]: a(): ./W.so.1
[2:0]: a(): ./X.so.1
[2:2E]: b(): ./w.so.1
[2:0]: b(): ./x.so.1

在此示例中,从 prog1 建立的进程包含两个多次定义的符号:a()b()。输出诊断信息中的初始元素(括在方括号中的那些元素)描述了关联的符号。

第一个十进制值表示关联符号的实例数。a()b() 都存在两个实例。第二个十进制值表示已解析为此符号的绑定数。来自 W.so.1 的符号定义 a() 揭示已建立了到此依赖项的两个绑定。同样,来自 w.so.1 的符号定义 b() 揭示已建立了到此依赖项的两个绑定。绑定数之后的字母用于限定绑定。字母 "E" 表示已从外部 (external) 目标文件建立了绑定。字母 "S" 表示已从同一 (same) 目标文件建立了绑定。

在接下来的几节中,将使用 LD_DEBUGlari 以及从这些组件生成的进程示例来进一步研究直接绑定情况。