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.2 和 O.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() 系列是用户应用程序内经常会实现的另一组接口。这些用户实现的目的是在任何系统定义上进行插入。
不过,仍然使用了 –z interpose 选项生成这些插入库是为了给插入项的生成设定一个惯例。该显式插入与在 libc.so.1 中建立的直接绑定阻止定义之间没有任何不利的相互影响。
不能直接绑定到指定了 STV_SINGLETON 可见性的符号。请参见Table 12–23。编译系统可将这些符号指定给一个实现,该实现可能会在进程内的多个目标文件中多次实例化。所有的单件符号引用都绑定到进程中第一次出现的单件符号。