SPRAB89A September 2011 – March 2014
Relocation types are described in two tables. Table 13-5 gives numeric values for the relocation types and summarizes the computation of the relocated value. Following that table is a description of the relocation types and examples of their use. Table 13-6 describes, for each type, the exact computation, including extraction and insertion of the relocation field, overflow checking, and any scaling or other adjustments.
The following notations are used in Table 13-5.
S | The value of the symbol associated with the relocation, specified by the symbol table index contained in the r_info field in the relocation entry. |
A | The addend used to compute the value of the relocatable field. For Elf32_rel relocations, A is encoded into the relocatable field according to Table 13-6. For Elf32_Rela relocations, A is given by the r_addend field of the relocation entry. |
PC | The address of the container containing the field. |
FP(x) | The address of the fetch packet containing the instruction at address x; that is: FP(x) := x & 0xFFFFFFE0. |
P | The fetch packet address of the instruction being relocated; that is: P := FP(PC). |
B | The base address of the data segment for the current load module. This location is marked by the symbol _ _C6000_DSBT_BASE, and is the value of the DP register when the program is executing. |
GOT(S) | The address of the Global Offset Table (GOT) entry of the symbol (S) associated with the relocation. |
TBR(x) | The offset of x from the Thread-Local Storage (TLS) Block Base. See Chapter 7 for details about thread-local storage. |
TPR(x) | The offset of x from the thread-pointer (TP). |
TLS(x) | The TLS Descriptor for x, which contains the module-id and TBR offset of x. |
TLSMOD(x) | The TLS module identifier of the module that defines x. |
Name | Value | Operation | Constraints |
---|---|---|---|
R_C6000_NONE | 0 | ||
R_C6000_ABS32 | 1 | S + A | |
R_C6000_ABS16 | 2 | S + A | |
R_C6000_ABS8 | 3 | S + A | |
R_C6000_PCR_S21 | 4 | S + A – P | |
R_C6000_PCR_S12 | 5 | S + A – P | |
R_C6000_PCR_S10 | 6 | S + A – P | |
R_C6000_PCR_S7 | 7 | S + A – P | |
R_C6000_ABS_S16 | 8 | S + A | |
R_C6000_ABS_L16 | 9 | S + A | |
R_C6000_ABS_H16 | 10 | S + A | Rela only |
R_C6000_SBR_U15_B | 11 | S + A – B | |
R_C6000_SBR_U15_H | 12 | S + A – B | |
R_C6000_SBR_U15_W | 13 | S + A – B | |
R_C6000_SBR_S16 | 14 | S + A – B | |
R_C6000_SBR_L16_B | 15 | S + A – B | |
R_C6000_SBR_L16_H | 16 | S + A – B | |
R_C6000_SBR_L16_W | 17 | S + A – B | |
R_C6000_SBR_H16_B | 18 | S + A – B | Rela only |
R_C6000_SBR_H16_H | 19 | S + A – B | Rela only |
R_C6000_SBR_H16_W | 20 | S + A – B | Rela only |
R_C6000_SBR_GOT_U15_W | 21 | GOT(S) + A – B | |
R_C6000_SBR_GOT_L16_W | 22 | GOT(S) + A – B | |
R_C6000_SBR_GOT_H16_W | 23 | GOT(S) + A – B | Rela only |
R_C6000_DSBT_INDEX | 24 | DSBT Index of this static link unit | |
R_C6000_PREL31 | 25 | S + A – PC | |
R_C6000_COPY | 26 | Load-time copy of preempted symbol | ET_EXEC only |
R_C6000_JUMP_SLOT | 27 | S + A | ET_EXEC / ET_DYN |
R_C6000_EHTYPE | 28 | S + A - B | |
R_C6000_PCR_H16 | 29 | S - FP(P - A) | Rela only |
R_C6000_PCR_L16 | 30 | S - FP(P - A) | Rela only |
Reserved | 31 | ||
Reserved | 32 | ||
R_C6000_TBR_U15_B | 33 | TBR(S) | Static only |
R_C6000_TBR_U15_H | 34 | TBR(S) | Static only |
R_C6000_TBR_U15_W | 35 | TBR(S) | Static only |
R_C6000_TBR_U15_D | 36 | TBR(S) | Static only |
R_C6000_TPR_S16 | 37 | TBR(S) | |
R_C6000_TPR_U15_B | 38 | TPR(S) | |
R_C6000_TPR_U15_H | 39 | TPR(S) | |
R_C6000_TPR_U15_W | 40 | TPR(S) | |
R_C6000_TPR_U15_D | 41 | TPR(S) | |
R_C6000_TPR_U32_B | 42 | TPR(S) | Dynamic only |
R_C6000_TPR_U32_H | 43 | TPR(S) | Dynamic only |
R_C6000_TPR_U32_W | 44 | TPR(S) | Dynamic only |
R_C6000_TPR_U32_D | 45 | TPR(S) | Dynamic only |
R_C6000_SBR_GOT_U15_W_TLSMOD | 46 | GOT(TLSMOD(S)) + A – B | Static only |
R_C6000_SBR_GOT_U15_W_TBR | 47 | GOT(TBR(S)) + A - B | Static only |
R_C6000_SBR_GOT_U15_W_TPR_B | 48 | GOT(TPR(S))+A-B | Static only |
R_C6000_SBR_GOT_U15_W_TPR_H | 49 | GOT(TPR(S))+A-B | Static only |
R_C6000_SBR_GOT_U15_W_TPR_W | 50 | GOT(TPR(S))+A-B | Static only |
R_C6000_SBR_GOT_U15_W_TPR_D | 51 | GOT(TPR(S))+A-B | Static only |
R_C6000_SBR_GOT_L16_W_TLSMOD | 52 | GOT(TLSMOD(S)) + A - B | Static only |
R_C6000_SBR_GOT_L16_W_TBR | 53 | GOT(TBR(S)) + A - B | Static only |
R_C6000_SBR_GOT_L16_W_TPR_B | 54 | GOT(TPR(S))+A-B | Static only |
R_C6000_SBR_GOT_L16_W_TPR_H | 55 | GOT(TPR(S))+A-B | Static only |
R_C6000_SBR_GOT_L16_W_TPR_W | 56 | GOT(TPR(S))+A-B | Static only |
R_C6000_SBR_GOT_L16_W_TPR_D | 57 | GOT(TPR(S))+A-B | Static only |
R_C6000_SBR_GOT_H16_W_TLSMOD | 58 | GOT(TLSMOD(S)) + A - B | Static only |
R_C6000_SBR_GOT_H16_W_TBR | 59 | GOT(TBR(S)) + A - B | Static only |
R_C6000_SBR_GOT_H16_W_TPR_B | 60 | GOT(TPR(S))+A-B | Static only |
R_C6000_SBR_GOT_H16_W_TPR_H | 61 | GOT(TPR(S))+A-B | Static only |
R_C6000_SBR_GOT_H16_W_TPR_W | 62 | GOT(TPR(S))+A-B | Static only |
R_C6000_SBR_GOT_H16_W_TPR_D | 63 | GOT(TPR(S))+A-B | Static only |
R_C6000_TLSMOD | 64 | TLSMOD(S) | Dynamic only |
R_C6000_TBR_U32 | 65 | TBR(S) | Dynamic only |
R_C6000_ALIGN | 253 | None | ET_REL only |
R_C6000_FPHEAD | 254 | None | ET_REL only |
R_C6000_NOCMP | 255 | None | ET_REL only |
The R_NONE relocation performs no operation. It is used to create a reference from one section to another, to ensure that if the referring section is linked in, so is the referee.
The R_C6000_ABS8/16/32 relocations directly encode the relocated address of a symbol into 8-, 16-, or 32-bit fields. They are commonly used for initialized data, not for instructions. The signedness of the field is unspecified; that is, they are used for both signed and unsigned values.
.field X,32 ; R_C6000_ABS32
.field X,16 ; R_C6000_ABS16
.field X,8 ; R_C6000_ABS8
The PCR relocations encode signed PC-relative branch displacements. They are scaled to 32-bit (word) units. Displacements are computed relative to the fetch packet of the source instruction.
B func ; R_C6000_PCR_S21
CALLP func,B3 ; R_C6000_PCR_S21
BNOP func ; R_C6000_PCR_S12
BPOS func,A10 ; R_C6000_PCR_S10
BDEC func,A1 ; R_C6000_PCR_S10
ADDKPC func,B3,4 ; R_C6000_PCR_S7
Relocations with L16 in their names encode the lower 16 bits of a 32-bit address or offset. Those containing H16 encode the upper 16 bits, and are always Rela. Relocations with S16 encode a signed 16-bit value (generally not part of an address). Those with U15 encode an unsigned 15-bit DP-relative displacement.
MVHL sym,A0 ; R_C6000_ABS_L16
MVKH sym,A0 ; R_C6000_ABS_H16
MVK const16,A0 ; R_C6000_ABS_S16 sign extend const16 into A0
MVKLH const16,A0 ; R_C6000_ABS_L16 move const16 into A0[16:31]
The PCR_L16 and PCR_H16 relocations encode the lower and upper bits, respectively, of a PC-relative offset between a target address and the fetch packet address of a reference PC (the “base PC”). The offset from the fetch packet of the current instruction to the base PC is encoded in the addend field; that is A := (P-base). The relocation then computes S-FP(P-A), resulting in the offset between S and FP(base). These relocations are used to address objects in different sections using PC-relative addressing, as described in Section 5.2.
MVK $PCR_OFFSET(sym,base),A0 ; R_C6000_PCR_L16
MVKH $PCR_OFFSET(sym,base),A0 ; R_C6000_PCR_H16
The SBR_U15 relocations encode 15-bit unsigned DP-relative offsets for near-DP data addressing. They are scaled according to the access width: 32-bit word (_W), 16-bit halfword (_H), or byte (_B).
LDB *+DP(sym),A1 ; R_C6000_SBR_U15_B
ADDAB DP,sym,A2 ; R_C6000_SBR_U15_B
LDH *+DP(sym),A1 ; R_C6000_SBR_U15_H
ADDAH DP,sym,A2 ; R_C6000_SBR_U15_H
LDW *+DP(sym),A1 ; R_C6000_SBR_U15_W
ADDAW DP,sym,A2 ; R_C6000_SBR_U15_W
The other SBR relocations are used to encode the high and low parts of 32-bit DP-relative offsets, for far DP-relative addressing. In the examples that follow:
MVK (sym - $bss),A0 ; R_C6000_SBR_S16
MVKL $DPR_byte(sym),A0 ; R_C6000_SBR_L16_B
MVKH $DPR_byte(sym),A0 ; R_C6000_SBR_H16_B
MVKL $DPR_hword(sym),A0 ; R_C6000_SBR_L16_H
MVKH $DPR_hword(sym),A0 ; R_C6000_SBR_H16_H
MVKL $DPR_word(sym),A0 ; R_C6000_SBR_L16_W
MVKH $DPR_word(sym),A0 ; R_C6000_SBR_H16_W
The SBR_GOT relocations correspond to the same instructions and encodings as the SBR relocations, but refer to the DP-relative GOT address of the referenced symbol instead of the symbol itself. Typically the GOT is accessed with near DP-relative addressing, so R_C6000_DBR_GOT_U15_W is used. When the GOT is far the offset is generated with MVKL/MVKH with the other two relocations (see Section 6.7). In the examples that follow,
LDW *+DP[GOT(sym)],A0 ; R_C6000_SBR_GOT_U15_W
MVKL $DPR_GOT(sym), A0 ; R_C6000_SBR_GOT_L16_W
MVKH $DPR_GOT(sym), A0 ; R_C6000_SBR_GOT_H16_W
The R_C6000_DSBT_INDEX encodes the index into the Data Segment Base Table of the current load module. It is present only in files that use the DSBT model for position independence. See Section 6.8.
LDW *+DP($DSBT_INDEX(__C6000_DSBT_BASE)),DP ; R_C6000_DSBT_INDEX
R_C6000_COPY is used to mark a duplicate symbol defined in an executable that preempts a library definition, under the import-as-own convention described in Section 15.10. When the executable is loaded, the dynamic loader must copy any initial value from the library's definition to that of the executable. This relocation type is present only in the dynamic relocation table of an executable file (ET_EXEC).
R_6000_JUMP_SLOT is used to mark GOT entries that refer to imported functions and are referred to only from PLT entries, and are therefore subject to lazy binding as described in Section 15.7. R_C6000_JUMP_SLOT relocations occur only in executables and shared objects, and only in the DT_JMPREL section of the dynamic relocation table.
R_C6000_PREL31 is used to encode code addresses in exception handling tables. R_C6000_EHTYPE is used to encode typeinfo addresses in exception handling tables. See Section 11.3.
Relocations with values from 33 to 65 are for use with Thread-Local Storage (TLS). These relocations include the R_C6000_TBR_*, R_C6000_TPR_*, R_C6000_SBR_GOT_*_W_T*, R_C6000_TLSMOD, and R_C6000_TBR_U32 relocations. See Chapter 7 for details about thread-local storage. Examples that use these TLS relocations are provided in Section 7.6.
R_C6000_ALIGN and R_C6000_FPHEAD are used as markers for the C64+ compressor. They have no effect under the ABI. A downstream tool that combines relocatable files (ET_REL) into other relocatable files, such as partial link, should either preserve them or mark the sections in which they occur with R_C6000_NOCMP.
R_C6000_NOCMP marks a section as being uncompressable.