Oracle® Solaris 11.2 链接程序和库指南

退出打印视图

更新时间: 2014 年 7 月
 
 

使用 NODIRECT mapfile 关键字

NODIRECT mapfile 关键字提供了一种阻止直接绑定到各个符号的方法。在阻止直接绑定方面,该关键字提供了比 –B nodirect 选项更细粒度的控制。

从之前示例使用的组件中,可以将 O.so.2 生成为阻止直接绑定到函数 o()

$ cat mapfile
$mapfile_version 2
SYMBOL_SCOPE {
        global:
                o       { FLAGS = NODIRECT };
};
$ cc -o O.so.2 -G -Kpic o.c -Mmapfile -zdirect -R. X.so.1
$ cc -o A.so.2 -G -Kpic a.c -Bdirect -R. O.so.2 X.so.1

可以使用 elfdump(1) 来查看 A.so.2O.so.2 的符号信息。

$ elfdump -y A.so.2
     [1]  DBL     [3] X.so.1            x
     [5]  DBL     [3] X.so.1            y
     [6]  DL      [1] O.so.1            o
     [9]  DBL     [1] O.so.1            p
$ elfdump -y O.so.1
     [3]  DB      [0] X.so.1            x
     [4]  DB      [0] X.so.1            y
     [6]  N                             o
     [7]  D           <self>            p

O.so.1 只声明了不能直接绑定到函数 o()。因此,A.so.2 能够直接绑定到 O.so.1 中的函数 p()

Oracle Solaris 库内的各个接口已被定义为不允许直接绑定。其中之一是数据项 errno。该数据项是在 libc.so.1 中定义的。可以通过包含头文件 stdio.h 来引用该数据项。但是,通常会指示许多应用程序定义其自己的 errno。如果交付了直接绑定到 libc.so.1 中定义的 errno 的一系列系统库,则这些应用程序会被损害。

已定义为阻止绑定到的另一个接口系列是 malloc(3C) 系列。malloc() 系列是用户应用程序内经常会实现的另一组接口。这些用户实现的目的是在任何系统定义上进行插入。


注 - 随 Oracle Solaris OS 提供了各种系统插入库,这些库提供了替代的 malloc() 实现。此外,每个实现都期望成为在一个进程内使用的唯一实现。所有 malloc() 插入库都是使用 –z interpose 选项生成的。该选项实际上不是必需的,因为 libc.so.1 内的 malloc() 系列已标记为阻止任何直接绑定。

不过,仍然使用了 –z interpose 选项生成这些插入库是为了给插入项的生成设定一个惯例。该显式插入与在 libc.so.1 中建立的直接绑定阻止定义之间没有任何不利的相互影响。


不能直接绑定到指定了 STV_SINGLETON 可见性的符号。请参见Table 12–23。编译系统可将这些符号指定给一个实现,该实现可能会在进程内的多个目标文件中多次实例化。所有的单件符号引用都绑定到进程中第一次出现的单件符号。