链接程序和库指南

32 位 SPARC: 过程链接表

对于 32 位 SPARC 动态库,过程链接表位于专用数据中。运行时链接程序可确定目标的绝对地址,并相应地修改过程链接表的内存映像。

过程链接表的前四项是保留项。尽管表 7–37 中显示了过程链接表的示例,但未指定这些项的原始内容。该表中的每一项都占用 3 个字(12 字节),并且表的最后一项后跟 nop 指令。

重定位表与过程链接表关联。_DYNAMIC 数组中的 DT_JMP_REL 项指定了第一个重定位项的位置。对于非保留的过程链接表的每一项,重定位表都包含相同顺序的对应项。所有这些项的重定位类型均为 R_SPARC_JMP_SLOT。重定位偏移可指定关联的过程链接表项的第一个字节的地址。符号表索引会指向相应的符号。

为说明过程链接表,表 7–37 显示了四项。其中,前两项是初始保留项。第三项是对 name101 的调用。第四项是对 name102 的调用。此示例假定对应 name102 的项是表的最后一项。在该最后一项的后面是 nop 指令。左列显示了进行动态链接之前目标文件中的指令。右列说明了运行时链接程序会用于修复过程链接表各项的可能的指令序列。

表 7–37 32 位 SPARC: 过程链接表示例

目标文件

内存段

.PLT0:

    unimp

    unimp

    unimp

.PLT1:

    unimp

    unimp

    unimp
.PLT0:

    save    %sp, -64, %sp

    call    runtime_linker

    nop

.PLT1:

    .word   identification

    unimp

    unimp
.PLT101:

    sethi   (.-.PLT0), %g1

    ba,a    .PLT0

    nop

.PLT102:

    sethi   (.-.PLT0), %g1

    ba,a    .PLT0

    nop



    nop
.PLT101:

    nop

    ba,a    name101

    nop

.PLT102:

    sethi   (.-.PLT0), %g1

    sethi   %hi(name102), %g1

    jmpl    %g1+%lo(name102), %g0

    

    nop

以下步骤介绍了运行时链接程序和程序如何通过过程链接表来共同解析符号引用。所介绍的这些步骤仅用于说明。没有指定运行时链接程序的准确执行时行为。

  1. 初始创建程序的内存映像时,运行时链接程序会更改初始过程链接表的各项。修改这些项是为了可将控制权转移给运行时链接程序自己的其中一个例程。运行时链接程序还会在第二项中存储一个字的标识信息。运行时链接程序获取控制权后,会检查该字以标识调用方。

  2. 过程链接表的其他所有项最初都会传输给第一项。因此,运行时链接程序会在首次执行表项时获取控制权。例如,该程序会调用 name101,以将控制权转移给标签 .PLT101

  3. sethi 指令可分别计算当前过程链接表各项和初始过程链接表各项(.PLT101.PLT0)之间的距离。该值会占用 %g1 寄存器最高有效的 22 位。

  4. 接下来,ba,a 指令会跳至 .PLT0 以建立栈帧,然后调用运行时链接程序。

  5. 通过标识值,运行时链接程序可获取其用于目标文件的数据结构,包括重定位表。

  6. 通过将 %g1 值移位并除以过程链接表各项的大小,运行时链接程序可计算对应 name101 的重定位项的索引。重定位项 101 的类型为 R_SPARC_JMP_SLOT。此重定位偏移可指定 .PLT101 的地址,并且其符号表索引会指向 name101。因此,运行时链接程序可获取符号的实际值、展开栈、修改过程链接表项并将控制权转移给所需目标。

运行时链接程序不必在内存段列下创建指令序列。如果运行时链接程序创建了指令序列,则某些点需要更多说明。


注 –

.PLT101.PLT102 显示的不同指令序列说明了如何优化关联目标的更新。


LD_BIND_NOW 环境变量可更改动态链接行为。如果其值不为空,则运行时链接程序会在将控制权转移给程序之前处理 R_SPARC_JMP_SLOT 重定位项。