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 Coding Examples in
     Chapter 3 and Global Offset Table in Chapter 5 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
     Procedure Linkage Table in Chapter 5 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_DS  92     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.