4.5. Relocation

4.5.1. Relocation Types

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:

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)

NoteNote
 

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.

R_PPC64_GOT16*

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.

R_PPC64_PLTGOT16*

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.

R_PPC64_COPY

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.

R_PPC64_GLOB_DAT

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.

R_PPC64_JMP_SLOT

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).

R_PPC64_RELATIVE

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.

R_PPC64_UADDR*

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.