运行时链接程序允许您使用环境变量 LD_PRELOAD 在进程初始化期间引入新目标文件,从而提供其他级别的灵活性。此环境变量可初始化为共享目标文件或可重定位目标文件名,也可初始化为用空格分隔的文件名字符串。这些目标文件将在装入动态可执行文件之后以及装入任何依赖项之前装入。这些目标文件都被指定了 world 搜索作用域和 global 符号可见性。
在以下示例中,首先装入动态可执行文件 prog,然后装入共享目标文件 newstuff.so.1。接下来装入在 prog 中定义的依赖项。
$ LD_PRELOAD=./newstuff.so.1 prog
可以使用 ldd(1) 显示这些目标文件的处理顺序。
$ ldd -e LD_PRELOAD=./newstuff.so.1 prog ./newstuff.so.1 => ./newstuff.so libc.so.1 => /lib/libc.so.1
在以下示例中,预装入比较复杂且耗时。
$ LD_PRELOAD="./foo.o ./bar.o" prog
运行时链接程序首先会对可重定位目标文件 foo.o 和 bar.o 进行链接编辑,以生成在内存中保存的共享目标文件。然后,会按照前面示例中预装入共享目标文件 newstuff.so.1 的方式,在动态可执行文件及其依赖项之间插入此内存映像。同样,可以使用 ldd(1) 显示这些目标文件的处理顺序:
$ ldd -e LD_PRELOAD="./foo.o ./bar.o" ldd prog ./foo.o => ./foo.o ./bar.o => ./bar.o libc.so.1 => /lib/libc.so.1
在动态可执行文件后插入目标文件的这些机制将插入概念引入到另一个层次。您可以使用这些机制来试验驻留在标准共享目标文件中的函数的新实现。如果预装入包含此函数的目标文件,则该目标文件将插入到原始功能中。因此,原始功能会完全隐藏在新的预装入版本之后。
预装入的另一个用途是扩充驻留在标准共享目标文件中的函数。通过在原始符号中插入新符号,新函数可以执行其他处理。新函数还可调用原始函数。此机制通常会将 dlsym(3C) 与特殊句柄 RTLD_NEXT 配合使用,以获取原始符号的地址。