SPRAB89A September 2011 – March 2014
If the function can be preempted, the function's address cannot be encoded in the PLT entry, even in a position independent way. The address must be addressed indirectly through the GOT.
$sym$plt:
LDW *+DP($GOT(sym)),tmp ;reloc R_C6000_SBR_GOT_U15
B tmp
Certain compiler helper functions have non-standard register preservation conventions (Section 8.4), affecting the choice of which register is used for tmp. Furthermore, lazy binding (Section 15.7) may affect additional registers beyond those directly mentioned in the PLT entry. For this reason the ABI specifies that functions with non-standard conventions cannot be imported; that is, they cannot be called via a PLT entry. With this stipulation the linker is free to modify any caller-save register not involved in the function-call interface in the PLT entry.
A compiler may choose to inline the PLT entry for calls to functions that it knows or suspects are imported. This has the advantage of reducing the latency for the additional branch, at the expense of code size.
If the dynamic loader uses lazy binding as described in Section 15.7, inlined PLT entries must follow the conventions described there. Alternately, inlined PLTs can generate GOT relocations that are excluded from the DT_JMPREL part of the dynamic relocation table (see Dynamic Section in Chapter 5 of the System V ABI) so that they are not subject to lazy binding.