Relocation entries describe how to alter the instruction and data relocation fields shown below. Bit numbers appear in the lower box corners; little-endian byte numbers appear in the upper right box corners; big-endian numbers appear in the upper left box corners.
+-------+-------+-------+-------+-------+-------+-------+-------+ |0 7|1 6|2 5|3 4|4 3|5 2|6 1|7 0| | doubleword64 | |0 63| +---------------------------------------------------------------+ +-------+-------+-------+-------+ |0 3|1 2|2 1|3 0| | word32 | |0 31| +-------------------------------+ +-------+-------+-------+--+----+ |0 3|1 2|2 1|3 | 0| | word30 | | |0 29|3031| +--------------------------+----+ +----+--+-------+-------+--+----+ |0 | 3|1 2|2 1|3 | 0| | | low24 | | |0 5|6 29|3031| +----+---------------------+----+ +-------+-+--+--+-------+--+----+ |0 3|1| | 2|2 1|3 | 0| | | | | low14 | | |0 |10|15|16 29|3031| +---------+--+--+----------+----+ +-------+-------+ |0 1|1 0| | half16 | |0 15| +---------------+ +-------+------+--+ |0 1|1 | 0| | half16ds | | |0 13|15| +--------------+--+ doubleword64 This specifies a 64-bit field occupying 8 bytes, the alignment of which is 8 bytes unless otherwise specified. word32 This specifies a 32-bit field occupying 4 bytes, the alignment of which is 4 bytes unless otherwise specified. word30 This specifies a 30-bit field contained within bits 0-29 of a word with 4-byte alignment. The two least significant bits of the word are unchanged. low24 This specifies a 24-bit field contained within a word with 4-byte alignment. The six most significant and the two least significant bits of the word are ignored and unchanged (for example, "Branch" instruction). low14 This specifies a 14-bit field contained within a word with 4-byte alignment, comprising a conditional branch instruction. The 14-bit relative displacement in bits 16-29, and possibly the "branch prediction bit" (bit 10), are altered; all other bits remain unchanged. half16 This specifies a 16-bit field occupying 2 bytes with 2-byte alignment (for example, the immediate field of an "Add Immediate" instruction). half16ds Similar to half16, but really just 14 bits since the two least significant bits must be zero, and are not really part of the field. (Used by for example the ldu instruction.)
Calculations in the relocation table assume the actions are transforming a relocatable file into either an executable or a shared object file. Conceptually, the link editor merges one or more relocatable files to form the output. It first determines how to combine and locate the input files, next it updates the symbol values, and then it performs relocations.
Some relocations use high adjusted values. These are the most significant bits, adjusted so that adding the low 16 bits will perform the correct calculation of the address accounting for signed arithmetic. This is to support using the low 16 bits as a signed offset when loading the value. For example, a value could be loaded from an absolute 64 bit address SYM as follows:
lis r3,SYM@highesta ori r3,SYM@highera sldi r3,r3,32 oris r3,r3,SYM@ha ld r4,SYM@l(r3)
The adjusted forms mean that this will work correctly even if SYM@l is negative when interpreted as a signed 16 bit number. Compare this to building the same 64 bit address using ori, in which case the adjusted forms are not used:
lis r3,SYM@highest ori r3,SYM@higher sldi r3,r3,32 oris r3,r3,SYM@h ori r3,r3,SYM@l ld r4,0(r3)
These code samples are not meant to encourage people to write code which builds absolute 64 bit addresses in this manner. It is normally better to use position independent code. However, this ABI does make this usage possible when it is required.
Relocations applied to executable or shared object files are similar and accomplish the same result. The following notations are used in the relocation table:
A Represents the addend used to compute the value of the relocatable field. B Represents the base address at which a shared object has been loaded into memory during execution. Generally, a shared object file is built with a 0 base virtual address, but the execution address will be different. See Program Header in the System V ABI for more information about the base address. G Represents the offset into the global offset table, relative to the TOC base, at which the address of the relocation entry's symbol plus addend will reside during execution. See Section 3.5 and Section 5.2.2 for more information. L Represents the section offset or address of the procedure linkage table entry for the symbol plus addend. A procedure linkage table entry redirects a function call to the proper destination. The link editor builds the initial procedure linkage table, and the dynamic linker modifies the entries during execution. See Section 5.2.4 for more information. M Similar to G, except that the address which is stored may be the address of the procedure linkage table entry for the symbol. P Represents the place (section offset or address) of the storage unit being relocated (computed using r_offset). R Represents the offset of the symbol within the section in which the symbol is defined (its section-relative address). S Represents the value of the symbol whose index resides in the relocation entry.
The following notations are used for relocations used with thread-local symbols.
@dtpmod Computes the load module index of the load module that contains the definition of sym. The addend, if present, is ignored. @dtprel Computes a dtv-relative displacement, the difference between the value of S + A and the base address of the thread-local storage block that contains the definition of the symbol, minus 0x8000. @tprel Computes a tp-relative displacement, the difference between the value of S + A and the value of the thread pointer (r13). @got@tlsgd Allocates two contiguous entries in the GOT to hold a tls_index structure, with values @dtpmod and @dtprel, and computes the offset to the first entry relative to the TOC base (r2). @got@tlsld Allocates two contiguous entries in the GOT to hold a tls_index structure, with values @dtpmod and zero, and computes the offset to the first entry relative to the TOC base (r2). @got@dtprel Allocates an entry in the GOT with value @dtprel, and computes the offset to the entry relative to the TOC base (r2). @got@tprel Allocates an entry in the GOT with value @tprel, and computes the offset to the entry relative to the TOC base (r2).
Relocation entries apply to halfwords, words, or doublewords. In all cases, the r_offset value designates the offset or virtual address of the first byte of the affected storage unit. The relocation type specifies which bits to change and how to calculate their values. The 64-bit PowerPC family uses only the Elf32_Rela relocation entries with explicit addends. For the relocation entries, the r_addend member serves as the relocation addend. In all cases, the offset, addend, and the computed result use the byte order specified in the ELF header.
The following general rules apply to the interpretation of the relocation types in the relocation table:
"+" and "-" denote 64-bit modulus addition and subtraction, respectively. ">>" denotes arithmetic right-shifting (shifting with sign copying) of the value of the left operand by the number of bits given by the right operand.
For relocation types in which the names contain "32", the upper 32 bits of the value computed must be the same. For relocation types in which the names contain "14" or "16," the upper 49 bits of the value computed before shifting must all be the same. For relocation types whose names contain "24," the upper 39 bits of the value computed before shifting must all be the same. For relocation types whose names contain "14" or "24," the low 2 bits of the value computed before shifting must all be zero.
#lo(value) denotes the least significant 16 bits of the indicated value:
#lo(x) = (x & 0xffff).
#hi(value) denotes bits 16 through 31 of the indicated value:
#hi(x) = ((x >> 16) & 0xffff).
#ha(value) denotes the high adjusted value: bits 16 through 31 of the indicated value, compensating for #lo() being treated as a signed number:
#ha(x) = (((x >> 16) + ((x & 0x8000) ? 1 : 0)) & 0xffff)
#higher(value) denotes bits 32 through 47 of the indicated value:
#higher(x) = ((x >> 32) & 0xffff)
#highera(value) denotes bits 32 through 47 of the indicated value, compensating for #lo() being treated as a signed number:
#highera(x) = (((x >> 32) + (((x & 0xffff8000) == 0xffff8000) ? 1 : 0)) & 0xffff)
#highest(value) denotes bits 48 through 63 of the indicated value:
#highest(x) = ((x >> 48) & 0xffff)
#highesta(value) denotes bits 48 through 63 of the indicated value, compensating for #lo being treated as a signed number:
#highesta(value) = (((x >> 48) + (((x & 0xffffffff8000) == 0xffffffff8000) ? 1 : 0)) & 0xffff)
Reference in a calculation to the value G implicitly creates a GOT entry for the indicated symbol.
.TOC. refers to the TOC base of the TOC section for the object being relocated. See Section 4.3 for additional information. The dynamic linker does not have this information, and hence relocation types that refer to .TOC. may only appear in relocatable object files, not in executables or shared objects.
Figure 4-1. Relocation Table
Name Value Field Calculation R_PPC64_NONE 0 none none R_PPC64_ADDR32 1 word32* S + A R_PPC64_ADDR24 2 low24* (S + A) >> 2 R_PPC64_ADDR16 3 half16* S + A R_PPC64_ADDR16_LO 4 half16 #lo(S + A) R_PPC64_ADDR16_HI 5 half16 #hi(S + A) R_PPC64_ADDR16_HA 6 half16 #ha(S + A) R_PPC64_ADDR14 7 low14* (S + A) >> 2 R_PPC64_ADDR14_BRTAKEN 8 low14* (S + A) >> 2 R_PPC64_ADDR14_BRNTAKEN 9 low14* (S + A) >> 2 R_PPC64_REL24 10 low24* (S + A - P) >> 2 R_PPC64_REL14 11 low14* (S + A - P) >> 2 R_PPC64_REL14_BRTAKEN 12 low14* (S + A - P) >> 2 R_PPC64_REL14_BRNTAKEN 13 low14* (S + A - P) >> 2 R_PPC64_GOT16 14 half16* G R_PPC64_GOT16_LO 15 half16 #lo(G) R_PPC64_GOT16_HI 16 half16 #hi(G) R_PPC64_GOT16_HA 17 half16 #ha(G) R_PPC64_COPY 19 none none R_PPC64_GLOB_DAT 20 doubleword64 S + A R_PPC64_JMP_SLOT 21 none see below R_PPC64_RELATIVE 22 doubleword64 B + A R_PPC64_UADDR32 24 word32* S + A R_PPC64_UADDR16 25 half16* S + A R_PPC64_REL32 26 word32* S + A - P R_PPC64_PLT32 27 word32* L R_PPC64_PLTREL32 28 word32* L - P R_PPC64_PLT16_LO 29 half16 #lo(L) R_PPC64_PLT16_HI 30 half16 #hi(L) R_PPC64_PLT16_HA 31 half16 #ha(L) R_PPC64_SECTOFF 33 half16* R + A R_PPC64_SECTOFF_LO 34 half16 #lo(R + A) R_PPC64_SECTOFF_HI 35 half16 #hi(R + A) R_PPC64_SECTOFF_HA 36 half16 #ha(R + A) R_PPC64_ADDR30 37 word30 (S + A - P) >> 2 R_PPC64_ADDR64 38 doubleword64 S + A R_PPC64_ADDR16_HIGHER 39 half16 #higher(S + A) R_PPC64_ADDR16_HIGHERA 40 half16 #highera(S + A) R_PPC64_ADDR16_HIGHEST 41 half16 #highest(S + A) R_PPC64_ADDR16_HIGHESTA 42 half16 #highesta(S + A) R_PPC64_UADDR64 43 doubleword64 S + A R_PPC64_REL64 44 doubleword64 S + A - P R_PPC64_PLT64 45 doubleword64 L R_PPC64_PLTREL64 46 doubleword64 L - P R_PPC64_TOC16 47 half16* S + A - .TOC. R_PPC64_TOC16_LO 48 half16 #lo(S + A - .TOC.) R_PPC64_TOC16_HI 49 half16 #hi(S + A - .TOC.) R_PPC64_TOC16_HA 50 half16 #ha(S + A - .TOC.) R_PPC64_TOC 51 doubleword64 .TOC. R_PPC64_PLTGOT16 52 half16* M R_PPC64_PLTGOT16_LO 53 half16 #lo(M) R_PPC64_PLTGOT16_HI 54 half16 #hi(M) R_PPC64_PLTGOT16_HA 55 half16 #ha(M) R_PPC64_ADDR16_DS 56 half16ds* (S + A) >> 2 R_PPC64_ADDR16_LO_DS 57 half16ds #lo(S + A) >> 2 R_PPC64_GOT16_DS 58 half16ds* G >> 2 R_PPC64_GOT16_LO_DS 59 half16ds #lo(G) >> 2 R_PPC64_PLT16_LO_DS 60 half16ds #lo(L) >> 2 R_PPC64_SECTOFF_DS 61 half16ds* (R + A) >> 2 R_PPC64_SECTOFF_LO_DS 62 half16ds #lo(R + A) >> 2 R_PPC64_TOC16_DS 63 half16ds* (S + A - .TOC.) >> 2 R_PPC64_TOC16_LO_DS 64 half16ds #lo(S + A - .TOC.) >> 2 R_PPC64_PLTGOT16_DS 65 half16ds* M >> 2 R_PPC64_PLTGOT16_LO_DS 66 half16ds #lo(M) >> 2 R_PPC64_TLS 67 none none R_PPC64_DTPMOD64 68 doubleword64 @dtpmod R_PPC64_TPREL16 69 half16* @tprel R_PPC64_TPREL16_LO 60 half16 #lo(@tprel) R_PPC64_TPREL16_HI 71 half16 #hi(@tprel) R_PPC64_TPREL16_HA 72 half16 #ha(@tprel) R_PPC64_TPREL64 73 doubleword64 @tprel R_PPC64_DTPREL16 74 half16* @dtprel R_PPC64_DTPREL16_LO 75 half16 #lo(@dtprel) R_PPC64_DTPREL16_HI 76 half16 #hi(@dtprel) R_PPC64_DTPREL16_HA 77 half16 #ha(@dtprel) R_PPC64_DTPREL64 78 doubleword64 @dtprel R_PPC64_GOT_TLSGD16 79 half16* @got@tlsgd R_PPC64_GOT_TLSGD16_LO 80 half16 #lo(@got@tlsgd) R_PPC64_GOT_TLSGD16_HI 81 half16 #hi(@got@tlsgd) R_PPC64_GOT_TLSGD16_HA 82 half16 #ha(@got@tlsgd) R_PPC64_GOT_TLSLD16 83 half16* @got@tlsld R_PPC64_GOT_TLSLD16_LO 84 half16 #lo(@got@tlsld) R_PPC64_GOT_TLSLD16_HI 85 half16 #hi(@got@tlsld) R_PPC64_GOT_TLSLD16_HA 86 half16 #ha(@got@tlsld) R_PPC64_GOT_TPREL16_DS 87 half16ds* @got@tprel R_PPC64_GOT_TPREL16_LO_DS 88 half16ds #lo(@got@tprel) R_PPC64_GOT_TPREL16_HI 89 half16 #hi(@got@tprel) R_PPC64_GOT_TPREL16_HA 90 half16 #ha(@got@tprel) R_PPC64_GOT_DTPREL16_DS 91 half16ds* @got@dtprel R_PPC64_GOT_DTPREL16_LO_DS92 half16ds #lo(@got@dtprel) R_PPC64_GOT_DTPREL16_HI 93 half16 #hi(@got@dtprel) R_PPC64_GOT_DTPREL16_HA 94 half16 #ha(@got@dtprel) R_PPC64_TPREL16_DS 95 half16ds* @tprel R_PPC64_TPREL16_LO_DS 96 half16ds #lo(@tprel) R_PPC64_TPREL16_HIGHER 97 half16 #higher(@tprel) R_PPC64_TPREL16_HIGHERA 98 half16 #highera(@tprel) R_PPC64_TPREL16_HIGHEST 99 half16 #highest(@tprel) R_PPC64_TPREL16_HIGHESTA 100 half16 #highesta(@tprel) R_PPC64_DTPREL16_DS 101 half16ds* @dtprel R_PPC64_DTPREL16_LO_DS 102 half16ds #lo(@dtprel) R_PPC64_DTPREL16_HIGHER 103 half16 #higher(@dtprel) R_PPC64_DTPREL16_HIGHERA 104 half16 #highera(@dtprel) R_PPC64_DTPREL16_HIGHEST 105 half16 #highest(@dtprel) R_PPC64_DTPREL16_HIGHESTA 106 half16 #highesta(@dtprel)
![]() | Note |
---|---|
Relocation values 18, 23 and 32 are not used. This is to maintain a correspondence to the relocation values used by the 32-bit PowerPC ELF ABI. |
The relocation types whose Field column entry contains an asterisk (*) are subject to failure if the value computed does not fit in the allocated bits.
The relocation types in which the names include _BRTAKEN or _BRNTAKEN specify whether the branch prediction bit (bit 10) should indicate that the branch will be taken or not taken, respectively. For an unconditional branch, the branch prediction bit must be 0.
Relocations 56-66 are to be used for instructions with a DS offset field (ld, ldu, lwa, std, stdu). ABI conformant tools should give an error for attempts to relocate an address to a value that is not divisible by 4.
Relocation types with special semantics are described below.
These relocation types resemble the corresponding R_PPC64_ADDR16* types, except that they refer to the address of the symbol's global offset table entry and additionally instruct the link editor to build a global offset table.
These relocation types resemble the corresponding R_PPC64_GOT16* types, except that the address stored in the global offset table entry may be the address of an entry in the procedure linkage table. If the link editor can determine the actual value of the symbol, it may store that in the corresponding GOT entry. Otherwise, it may create an entry in the procedure linkage table, and store that address in the GOT entry; this permits lazy resolution of function symbols at run time. Otherwise, the link editor may generate a R_PPC64_GLOB_DAT relocation as usual.
The link editor creates this relocation type for dynamic linking. Its offset member refers to a location in a writable segment. The symbol table index specifies a symbol that should exist both in the current object file and in a shared object. During execution, the dynamic linker copies data associated with the shared object's symbol to the location specified by the offset.
This relocation type resembles R_PPC64_ADDR64, except that it sets a global offset table entry to the address of the specified symbol. This special relocation type allows one to determine the correspondence between symbols and global offset table entries.
The link editor creates this relocation type for dynamic linking. Its offset member gives the location of a procedure linkage table entry. The dynamic linker modifies the procedure linkage table entry to transfer control to the designated symbol's address (see Section 5.2.4).
The link editor creates this relocation type for dynamic linking. Its offset member gives a location within a shared object that contains a value representing a relative address. The dynamic linker computes the corresponding virtual address by adding the virtual address at which the shared object was loaded to the relative address. Relocation entries for this type must specify 0 for the symbol table index.
These relocation types are the same as the corresponding R_PPC64_ADDR* types, except that the datum to be relocated is allowed to be unaligned.