链接程序和库指南

执行重定位的时间

根据重定位的执行时间,重定位可分为两种类型。产生这种区别是由对已重定位偏移进行的引用的类型所致。

即时引用指的是必须在装入目标文件后立即确定的重定位。这些引用通常是目标文件代码使用的数据项、函数指针,甚至是通过与位置相关的共享库进行的函数调用。这些重定位无法向运行时链接程序提供有关何时引用重定位项的信息。因此,必须在装入目标文件时,并在应用程序获取或重新获取控制权之前执行所有即时重定位。

延迟引用指的是在目标文件执行时可确定的重定位。这些引用通常是通过与位置无关的共享库进行的全局函数调用,或者是通过动态可执行文件进行的外部函数调用。在对提供这些引用的任何动态模块进行编译和链接编辑的过程中,关联的函数调用将成为对过程链接表项的调用。这些项构成 .plt 节。每个过程链接表项都成为包含关联重定位的延迟引用。

在首次调用过程链接表项时,控制权会移交给运行时链接程序。运行时链接程序将查找所需符号,并重写关联目标文件中的项信息。将来调用此过程链接表项时,将直接转至相应函数。使用此机制,可以推迟此类型的重定位,直到调用函数的第一个实例。此过程有时称为延迟绑定。

运行时链接程序的缺省模式是在每次提供过程链接表重定位时执行延迟绑定。通过将环境变量 LD_BIND_NOW 设置为任意非空值,可以覆盖此缺省模式。此环境变量设置将导致运行时链接程序在装入目标文件时,同时执行即时引用和延迟引用重定位。这些重定位在应用程序获取或重新获取控制权之前执行。例如,根据以下环境变量来处理文件 prog 及其依赖项中的所有重定位。在将控制权转交给应用程序之前处理这些重定位。


$ LD_BIND_NOW=1 prog

此外,也可使用 dlopen(3C) 来访问目标文件,并将模式定义为 RTLD_NOW。还可使用链接编辑器的 -z now 选项来生成目标文件,以指示该目标文件需要在装入时进行完整的重定位处理。此重定位要求还将在运行时传播至所标记目标文件的所有依赖项。


注 –

前面的即时引用和延迟引用示例都很典型。但是,过程链接表项的创建最终受用作链接编辑输入的可重定位目标文件提供的重定位信息控制。R_SPARC_WPLT30R_386_PLT32 等重定位记录指示链接编辑器创建过程链接表项。这些重定位由与位置无关的代码公用。

但是,通常会通过与位置相关的代码创建动态可执行文件,该代码可能不会指示需要过程链接表项。由于动态可执行文件具有固定位置,因此链接编辑器可在将引用绑定到外部函数定义时创建过程链接表项。无论原始重定位记录如何,都会创建此过程链接表项。