You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ELFv2-ABI/specification/ch_3.xml

7125 lines
227 KiB
XML

<!--
Copyright (c) 2016 OpenPOWER Foundation
Licensed under the GNU Free Documentation License, Version 1.3;
with no Invariants Sections, with no Front-Cover Texts,
and with no Back-Cover Texts (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.gnu.org/licenses/fdl-1.3.txt
-->
<chapter xmlns="http://docbook.org/ns/docbook"
xmlns:xl="http://www.w3.org/1999/xlink" version="5.0" xml:lang="en">
<title>Object Files</title>
<section xml:id="dbdoclet.50655241_97607">
<title>ELF Header</title>
<para>The file class member of the ELF header identification array,
e_ident[EI_CLASS], identifies the ELF file as 64-bit encoded by holding the
value ELFCLASS64.</para>
<para>For a big-endian encoded ELF file, the data encoding member of the
ELF header identification array, e_ident[EI_DATA], holds the value 2,
defined as data encoding ELFDATA2MSB. For a little-endian encoded ELF file,
it holds the value 1, defined as data encoding ELFDATA2LSB.</para>
<programlisting>e_ident[EI_CLASS] ELFCLASS64 For all 64-bit implementations.
e_ident[EI_DATA] ELFDATA2MSB For all big-endian implementations.
e_ident[EI_DATA] ELFDATA2LSB For all little-endian implementations.</programlisting>
<para>The ELF header's e_flags member holds bit flags associated with the
file. The 64-bit PowerPC processor family defines the following
flags.</para>
<para>E_flags defining the ABI level:</para>
<informaltable frame="none" colsep="0" rowsep="0">
<tgroup cols="2">
<colspec colname="c1" colwidth="10*" />
<colspec colname="c2" colwidth="90*" />
<tbody>
<row>
<entry>
<para>0</para>
</entry>
<entry>
<para>For ELF object files of an unspecified nature.</para>
</entry>
</row>
<row>
<entry>
<para>1</para>
</entry>
<entry>
<para>For the Power ELF V1 ABI using function descriptors. This
ABI is currently only used for big-endian PowerPC
implementations.</para>
</entry>
</row>
<row>
<entry>
<para>2</para>
</entry>
<entry>
<para>For the OpenPOWER ELF V2 ABI using the facilities described
here and including function pointers to directly reference
functions.</para>
</entry>
</row>
</tbody>
</tgroup>
</informaltable>
<para>The ABI version to be used for the ELF header file is specified with
the .abiversion pseudo-op:</para>
<programlisting>.abiversion 2</programlisting>
<para>Processor identification resides in the ELF header's e_machine
member, and must have the value EM_PPC64, defined as the value 21.</para>
</section>
<section>
<title>Special Sections</title>
<para>
<xref linkend="dbdoclet.50655241_64556" /> lists the sections that are used
in the Power Architecture to hold program and control information. It also
shows their types and attributes.</para>
<para> </para>
<table frame="all" pgwide="1" xml:id="dbdoclet.50655241_64556">
<title>Special Sections</title>
<tgroup cols="3">
<colspec colname="c1" colwidth="15*" />
<colspec colname="c2" colwidth="35*" />
<colspec colname="c3" colwidth="50*" />
<thead>
<row>
<entry>
<para>
<emphasis role="bold">Section Name</emphasis>
</para>
</entry>
<entry>
<para>
<emphasis role="bold">Type</emphasis>
</para>
</entry>
<entry>
<para>
<emphasis role="bold">Attributes</emphasis>
</para>
</entry>
</row>
</thead>
<tbody>
<row>
<entry>
<para>.got</para>
</entry>
<entry>
<para>SHT_PROGBITS</para>
</entry>
<entry>
<para>SHF_ALLOC + SHF_WRITE</para>
</entry>
</row>
<row>
<entry>
<para>.toc</para>
</entry>
<entry>
<para>SHT_PROGBITS</para>
</entry>
<entry>
<para>SHF_ALLOC + SHF_WRITE</para>
</entry>
</row>
<row>
<entry>
<para>.plt<footnote>
<para>The type of the OpenPOWER ABI .plt section is
SHT_NOBITS, not SHT_PROGBITS as on most other processors.</para>
</footnote></para>
</entry>
<entry>
<para>SHT_NOBITS</para>
</entry>
<entry>
<para>SHF_ALLOC + SHF_WRITE</para>
</entry>
</row>
<row>
<entry>
<para>.sdata</para>
</entry>
<entry>
<para>SHT_PROGBITS</para>
</entry>
<entry>
<para>SHF_ALLOC + SHF_WRITE</para>
</entry>
</row>
<row>
<entry>
<para>.sbss</para>
</entry>
<entry>
<para>SHT_NOBITS</para>
</entry>
<entry>
<para>SHF_ALLOC + SHF_WRITE</para>
</entry>
</row>
<row>
<entry>
<para>.data1</para>
</entry>
<entry>
<para>SHT_PROGBITS</para>
</entry>
<entry>
<para>SHF_ALLOC + SHF_WRITE</para>
</entry>
</row>
<row>
<entry>
<para>.bss1</para>
</entry>
<entry>
<para>SHT_NOBITS</para>
</entry>
<entry>
<para>SHF_ALLOC + SHF_WRITE</para>
</entry>
</row>
</tbody>
</tgroup>
</table>
<para>Suggested uses of these special sections follow:</para>
<itemizedlist>
<listitem>
<para>The .got section may hold the Global Offset Table (GOT). This
section is not normally present in a relocatable object file because it
is linker generated. The linker must ensure that .got is aligned to an
8-byte boundary. In an executable or shared library, it may contain
part or all of the TOC. For more information, see
<xref linkend="dbdoclet.50655240___RefHeading___Toc377640591" /> and
<xref linkend="dbdoclet.50655242_47739" />.</para>
</listitem>
<listitem>
<para>The .toc section may hold the initialized TOC. The .toc section
must be aligned to an 8-byte boundary. Address elements within .toc
must be aligned to 8-byte boundaries to support linker optimization of
the .toc section. In a relocatable object file, .toc may contain
addresses of objects and functions; in this respect it may be thought
of as a compiler-managed GOT. It may also contain other constants or
variables; in this respect it is like .sdata. In an executable or
shared library, it may contain part or the entirety of the TOC. For
more information, see
<xref linkend="dbdoclet.50655241_66700" />,
<xref linkend="dbdoclet.50655240___RefHeading___Toc377640591" />, and
<xref linkend="dbdoclet.50655242_47739" />.</para>
</listitem>
<listitem>
<para>The .plt section may hold the procedure linkage table. This
section is not normally present in a relocatable object file because it
is linker generated. Each entry within the .plt section is an 8-byte
address. The linker must ensure that .plt is aligned to an 8-byte
boundary. For more information, see
<xref linkend="dbdoclet.50655242_20388" />.</para>
</listitem>
<listitem>
<para>The .sdata section may hold initialized small-sized data. For
more information, see
<xref linkend="dbdoclet.50655241_81959" />.</para>
</listitem>
<listitem>
<para>The .sbss section may hold uninitialized small-sized data.</para>
</listitem>
<listitem>
<para>The .data1 section may hold initialized medium-sized data.</para>
</listitem>
<listitem>
<para>The .bss1 section may hold uninitialized medium-sized
data.</para>
</listitem>
</itemizedlist>
<para>Tools that support this ABI are not required to use these sections.
However, if a tool uses these sections, it must assign the types and
attributes specified in
<xref linkend="dbdoclet.50655241_64556" />. Tools are not required to use
the sections precisely as suggested. Relocation information and the code
that refers to it define the actual use of a section.</para>
</section>
<section xml:id="dbdoclet.50655241_66700">
<title>TOC</title>
<para>The TOC is part of the data segment of an executable program.</para>
<para>This section describes a common layout of the TOC in an executable
file or shared object. Particular tools are not required to follow the
layout specified here.</para>
<para>The TOC region commonly includes data items within the .got, .toc,
.sdata, and .sbss sections. In the medium code model, they can be addressed
with 32-bit signed offsets from the TOC pointer register. The TOC pointer
register typically points to the beginning of the .got section + 0x8000,
which permits a 2 GB TOC with the medium and large code models. The .got
section is typically created by the link editor based on @got relocations.
The .toc section is typically included from relocatable object files
referenced during the link phase.</para>
<para>The TOC may straddle the boundary between initialized and
uninitialized data in the data segment. The common order of sections in the
data segment, some of which may be empty, follows:</para>
<programlisting>.rodata
.data
.data1
.got
.toc
.sdata
.sbss
.plt
.bss1
.bss</programlisting>
<para>The medium code model is expected to provide a sufficiently large TOC
to provide all data addressing needs of a module with a single TOC.</para>
<para>Compilers may generate two-instruction medium code model references
(or, if selected, short displacement one-instruction references) for all
data items that are in the TOC for the object file being compiled. Such
references are relative to the TOC pointer register, r2. (The linker may
optimize two-instruction forms to one instruction forms, replacing a first
instruction of the two instruction form with a nop and rewriting the second
instruction. Consequently, the TOC pointer must be live during the first
and second instruction of a two-instruction reference.)</para>
<para>&#160;</para>
<bridgehead>Modules Containing Multiple TOCs</bridgehead>
<para>The link editor may create multiple TOCs. In such a case, the
constituent .got, .toc, .sdata, and .sbss sections are conceptually
repeated as necessary, with each TOC typically using a TOC pointer value
of its base plus 0x8000. Any constituent section of type SHT_NOBITS in
any TOC but the last is converted to type SHT_PROGBITS filled with
zeros.</para>
<para>When multiple TOCs are present, linking must take care to save,
initialize, and restore TOC pointers within a single module when calling
from one function to a second function using a different TOC pointer
value. Many of the same issues associated with a cross-module call apply
also to calls within a module but using different TOC pointers.</para>
</section>
<section xml:id="dbdoclet.50655241_73385">
<title>Symbol Table</title>
<section xml:id="dbdoclet.50655241_95185">
<title>Symbol Values</title>
<para>An executable file that contains a symbol reference that is to be
resolved dynamically by an associated shared object will have a symbol
table entry for that symbol. This entry will identify the symbol as
undefined by setting the st_shndx member to SHN_UNDEF.</para>
<para>The OpenPOWER ABI uses the three most-significant bits in the
symbol st_other field to specify the number of instructions between a
function's global entry point and local entry point. The global entry
point is used when it is necessary to set up the TOC pointer (r2) for the
function. The local entry point is used when r2 is known to already be
valid for the function. A value of zero in these bits asserts that the
function does not use r2.</para>
<para>The values of these three most significant bits of the st_other
field have the following meanings:</para>
<informaltable frame="none" colsep="0" rowsep="0">
<tgroup cols="2">
<colspec colname="c1" colwidth="10*" />
<colspec colname="c2" colwidth="90*" />
<tbody>
<row>
<entry>
<para>0</para>
</entry>
<entry>
<para>The local and global entry points are the same, and the
function has a single entry point with no requirement on r12 or
r2. On return, r2 will contain the same value as at
entry.</para>
<para>This value should be used for functions that do not
require the use of a TOC register to access external data. In
particular, functions that do not access data through the TOC
pointer can use a common entry point for the local and global
entry points.</para>
<note>
<para>If the function is not a leaf function, it must
call subroutines using the R_PPC64_REL24_NOTOC relocation
to indicate that the TOC register is not initialized. In
turn, this may lead to more expensive procedure linkage
table (PLT) stub code than would be necessary if a TOC
register were initialized.</para>
</note>
</entry>
</row>
<row>
<entry>
<para>1</para>
</entry>
<entry>
<para>The local and global entry points are the same, and r2
should be treated as caller-saved for local and global
callers.</para>
</entry>
</row>
<row>
<entry>
<para>2</para>
</entry>
<entry>
<para>The local entry point is at one instruction past the
global entry point.</para>
<para>When called at the global entry point, r12 must be set to
the function entry address. r2 will be set to the TOC base that
this function needs, so it must be preserved and restored by
the caller.</para>
<para>When called at the local entry point, r12 is not used and
r2 must already point to the TOC base that this function needs,
and it will be preserved.</para>
</entry>
</row>
<row>
<entry>
<para>3</para>
</entry>
<entry>
<para>The local entry point is at two instructions past the
global entry point.</para>
<para>When called at the global entry point, r12 must be set to
the function entry address. r2 will be set to the TOC base that
this function needs, so it must be preserved and restored by
the caller.</para>
<para>When called at the local entry point, r12 is not used and
r2 must already point to the TOC base that this function needs,
and it will be preserved.</para>
</entry>
</row>
<row>
<entry>
<para>4</para>
</entry>
<entry>
<para>The local entry point is at four instructions past the
global entry point.</para>
<para>When called at the global entry point, r12 must be set to
the function entry address. r2 will be set to the TOC base that
this function needs, so it must be preserved and restored by
the caller.</para>
<para>When called at the local entry point, r12 is not used and
r2 must already point to the TOC base that this function needs,
and it will be preserved.</para>
</entry>
</row>
<row>
<entry>
<para>5</para>
</entry>
<entry>
<para>The local entry point is at eight instructions past the
global entry point.</para>
<para>When called at the global entry point, r12 must be set to
the function entry address. r2 will be set to the TOC base that
this function needs, so it must be preserved and restored by
the caller.</para>
<para>When called at the local entry point, r12 is not used and
r2 must already point to the TOC base that this function needs,
and it will be preserved.</para>
</entry>
</row>
<row>
<entry>
<para>6</para>
</entry>
<entry>
<para>The local entry point is at 16 instructions past the
global entry point.</para>
<para>When called at the global entry point, r12 must be set to
the function entry address. r2 will be set to the TOC base that
this function needs, so it must be preserved and restored by
the caller.</para>
<para>When called at the local entry point, r12 is not used and
r2 must already point to the TOC base that this function needs,
and it will be preserved.</para>
</entry>
</row>
<row>
<entry>
<para>7</para>
</entry>
<entry>
<para>Reserved</para>
</entry>
</row>
</tbody>
</tgroup>
</informaltable>
<para>The local-entry-point handling field of st_other is generated with
the .localentry pseudo op:</para>
<programlisting revisionflag="changed"> .globl my_func
.type my_func, @function
my_func:
addis r2, r12, my_sym@ha(.TOC.-my_func)
addi r2, r2, my_sym@l(.TOC.-my_func)
.localentry my_func, .-my_func
... ; function definition
blr</programlisting>
<para>Functions called via symbols with an st_other value of 0 may be
called without a valid TOC pointer in r2. Symbols of functions that
require a local entry with a valid TOC pointer should generate a symbol
with an st_other field value of 2 - 6 and both local and global entry
points, even if the global entry point will not be used. (In such a case,
the instructions of the global entry setup sequence may optionally be
initialized with TRAP instructions.)</para>
</section>
<section xml:id="dbdoclet.50655241_81959">
<title>Use of the Small Data Area</title>
<para>For a data item in the .sdata or .sbss sections, a compiler may
generate short-form one-instruction references. In an executable file or
shared library, such a reference is relative to the address of the TOC
base symbol (which can be obtained from r2 if a TOC pointer is
initialized). A compiler that generates code using the small data area
should provide an option to select the maximum size of objects placed in
the small data area, and a means of disabling any use of the small data
area. When generating code for ELF shared libraries, the small data area
should not be used for default-visibility global objects. This is to
satisfy ELF shared-library symbol interposition rules. That is, an
ordinary global symbol in a shared library may be overridden by a symbol
of the same name defined in the executable or another shared library.
Supporting interposition when using TOC-pointer relative addressing would
require text relocations.</para>
</section>
</section>
<section xml:id="dbdoclet.50655241_18894">
<title>Relocation Types</title>
<para>The relocation entries in a relocatable file are used by the link
editor to transform the contents of that file into an executable file or a
shared object file. The application and result of a relocation are similar
for both. Several relocatable files may be combined into one output file.
The link editor merges the content of the files, sets the value of all
function symbols, and performs relocations.</para>
<para>The 64-bit OpenPOWER Architecture uses Elf64_Rela relocation entries
exclusively. A relocation entry may operate upon a halfword, word, or
doubleword. The r_offset member of the relocation entry designates the
first byte of the address affected by the relocation. The subfield of
r_offset affected by a relocation is implicit in the definition of the
applied relocation type. The r_addend member of the relocation entry serves
as the relocation addend, which is described in
<xref linkend="dbdoclet.50655241_45722" /> for each relocation type.</para>
<para>A relocation type defines a set of instructions and calculations
necessary to alter the subfield data of a particular relocation
field.</para>
<section xml:id="dbdoclet.50655241_45722">
<title>Relocation Fields</title>
<para>The following relocation fields identify a subfield of an address
affected by a relocation.</para>
<para>Bit numbers are shown at the bottom of the boxes. (Only big-endian
bit numbers are shown for space considerations.) Byte numbers are shown
in the top of the boxes; big-endian byte numbers are displayed in the
upper left corners and little-endian in the upper right corners. The byte
order specified in a relocatable files ELF header applies to all the
elements of a relocation entry, the relocation field definitions, and
relocation type calculations.</para>
<para>In the following figure, doubleword64 specifies a 64-bit field
occupying 8 bytes, the alignment of which is 8 bytes unless otherwise
specified.</para>
<informaltable frame="all" rowsep="0" colsep="0">
<tgroup cols="8">
<colspec colname="c1" colwidth="12*" />
<colspec colname="c2" colwidth="12*" />
<colspec colname="c3" colwidth="12*" />
<colspec colname="c4" colwidth="12*" />
<colspec colname="c5" colwidth="12*" />
<colspec colname="c6" colwidth="12*" />
<colspec colname="c7" colwidth="12*" />
<colspec colname="c8" colwidth="12*" />
<tbody>
<row>
<entry align="left">
<para>0</para>
</entry>
<entry align="right" colsep="1">
<para>7</para>
</entry>
<entry align="left">
<para>1</para>
</entry>
<entry align="right" colsep="1">
<para>6</para>
</entry>
<entry align="left">
<para>2</para>
</entry>
<entry align="right" colsep="1">
<para>5</para>
</entry>
<entry align="left">
<para>3</para>
</entry>
<entry align="right" colsep="1">
<para>4</para>
</entry>
</row>
<row>
<entry nameend="c8" namest="c1" align="center">
<para>doubleword64</para>
</entry>
</row>
<row rowsep="1">
<entry align="left">
<para>0</para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
</row>
<row>
<entry align="left">
<para>4</para>
</entry>
<entry align="right" colsep="1">
<para>3</para>
</entry>
<entry align="left">
<para>5</para>
</entry>
<entry align="right" colsep="1">
<para>2</para>
</entry>
<entry align="left">
<para>6</para>
</entry>
<entry align="right" colsep="1">
<para>1</para>
</entry>
<entry align="left">
<para>7</para>
</entry>
<entry align="right" colsep="1">
<para>0</para>
</entry>
</row>
<row>
<entry nameend="c8" namest="c1" align="center">
<para>doubleword64 (continued)</para>
</entry>
</row>
<row>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry align="right">
<para>63</para>
</entry>
</row>
</tbody>
</tgroup>
</informaltable>
<para> </para>
<para> </para>
<para>In the following figure, word32 specifies a 32-bit field taking up
4 bytes and maintaining 4-byte alignment unless otherwise
indicated.</para>
<para> </para>
<informaltable frame="all" rowsep="0" colsep="0">
<tgroup cols="8">
<colspec colname="c1" colwidth="12*" />
<colspec colname="c2" colwidth="12*" />
<colspec colname="c3" colwidth="12*" />
<colspec colname="c4" colwidth="12*" />
<colspec colname="c5" colwidth="12*" />
<colspec colname="c6" colwidth="12*" />
<colspec colname="c7" colwidth="12*" />
<colspec colname="c8" colwidth="12*" />
<tbody>
<row>
<entry align="left">
<para>0</para>
</entry>
<entry align="right" colsep="1">
<para>3</para>
</entry>
<entry align="left">
<para>1</para>
</entry>
<entry align="right" colsep="1">
<para>2</para>
</entry>
<entry align="left">
<para>2</para>
</entry>
<entry align="right" colsep="1">
<para>1</para>
</entry>
<entry align="left">
<para>3</para>
</entry>
<entry align="right" colsep="1">
<para>0</para>
</entry>
</row>
<row>
<entry nameend="c8" namest="c1" align="center">
<para>word32</para>
</entry>
</row>
<row>
<entry align="left">
<para>0</para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry align="right">
<para>31</para>
</entry>
</row>
</tbody>
</tgroup>
</informaltable>
<para>In the following figure, word30 specifies a 30-bit field taking up
bits 0 - 29 of a word and maintaining 4-byte alignment unless otherwise
indicated.</para>
<para> </para>
<informaltable frame="all" rowsep="0" colsep="0">
<tgroup cols="32">
<colspec colname="c1" colwidth="3*" />
<colspec colname="c2" colwidth="3*" />
<colspec colname="c3" colwidth="3*" />
<colspec colname="c4" colwidth="3*" />
<colspec colname="c5" colwidth="3*" />
<colspec colname="c6" colwidth="3*" />
<colspec colname="c7" colwidth="3*" />
<colspec colname="c8" colwidth="3*" />
<colspec colname="c9" colwidth="3*" />
<colspec colname="c10" colwidth="3*" />
<colspec colname="c11" colwidth="3*" />
<colspec colname="c12" colwidth="3*" />
<colspec colname="c13" colwidth="3*" />
<colspec colname="c14" colwidth="3*" />
<colspec colname="c15" colwidth="3*" />
<colspec colname="c16" colwidth="3*" />
<colspec colname="c17" colwidth="3*" />
<colspec colname="c18" colwidth="3*" />
<colspec colname="c19" colwidth="3*" />
<colspec colname="c20" colwidth="3*" />
<colspec colname="c21" colwidth="3*" />
<colspec colname="c22" colwidth="3*" />
<colspec colname="c23" colwidth="3*" />
<colspec colname="c24" colwidth="3*" />
<colspec colname="c25" colwidth="3*" />
<colspec colname="c26" colwidth="3*" />
<colspec colname="c27" colwidth="3*" />
<colspec colname="c28" colwidth="3*" />
<colspec colname="c29" colwidth="3*" />
<colspec colname="c30" colwidth="3*" colsep="1"/>
<colspec colname="c31" colwidth="3*" />
<colspec colname="c32" colwidth="3*" />
<tbody>
<row>
<entry align="left">
<para>0</para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry align="right" colsep="1">
<para>3</para>
</entry>
<entry align="left">
<para>1</para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry align="right" colsep="1">
<para>2</para>
</entry>
<entry align="left">
<para>2</para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry align="right" colsep="1">
<para>1</para>
</entry>
<entry align="left">
<para>3</para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry align="right" colsep="1">
<para>0</para>
</entry>
</row>
<row>
<entry nameend="c30" namest="c1" align="center" colsep="1">
<para>word30</para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
</row>
<row>
<entry align="right">
<para>0</para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry align="right">
<para>29</para>
</entry>
<entry align="left">
<para>30</para>
</entry>
<entry align="right">
<para>31</para>
</entry>
</row>
</tbody>
</tgroup>
</informaltable>
<para>In the following figure, low24 specifies a 24-bit field taking up
bits 6 - 29 of a word and maintaining 4-byte alignment. The other bits
remain unchanged. A call or unconditional branch instruction is an
example of this field.</para>
<para> </para>
<informaltable frame="all" rowsep="0" colsep="0">
<tgroup cols="32">
<colspec colname="c1" colwidth="3*" />
<colspec colname="c2" colwidth="3*" />
<colspec colname="c3" colwidth="3*" />
<colspec colname="c4" colwidth="3*" />
<colspec colname="c5" colwidth="3*" />
<colspec colname="c6" colwidth="3*" colsep="1"/>
<colspec colname="c7" colwidth="3*" />
<colspec colname="c8" colwidth="3*" />
<colspec colname="c9" colwidth="3*" />
<colspec colname="c10" colwidth="3*" />
<colspec colname="c11" colwidth="3*" />
<colspec colname="c12" colwidth="3*" />
<colspec colname="c13" colwidth="3*" />
<colspec colname="c14" colwidth="3*" />
<colspec colname="c15" colwidth="3*" />
<colspec colname="c16" colwidth="3*" />
<colspec colname="c17" colwidth="3*" />
<colspec colname="c18" colwidth="3*" />
<colspec colname="c19" colwidth="3*" />
<colspec colname="c20" colwidth="3*" />
<colspec colname="c21" colwidth="3*" />
<colspec colname="c22" colwidth="3*" />
<colspec colname="c23" colwidth="3*" />
<colspec colname="c24" colwidth="3*" />
<colspec colname="c25" colwidth="3*" />
<colspec colname="c26" colwidth="3*" />
<colspec colname="c27" colwidth="3*" />
<colspec colname="c28" colwidth="3*" />
<colspec colname="c29" colwidth="3*" />
<colspec colname="c30" colwidth="3*" colsep="1"/>
<colspec colname="c31" colwidth="3*" />
<colspec colname="c32" colwidth="3*" />
<tbody>
<row>
<entry align="left">
<para>0</para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry align="right" colsep="1">
<para>3</para>
</entry>
<entry align="left">
<para>1</para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry align="right" colsep="1">
<para>2</para>
</entry>
<entry align="left">
<para>2</para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry align="right" colsep="1">
<para>1</para>
</entry>
<entry align="left">
<para>3</para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry align="right" colsep="1">
<para>0</para>
</entry>
</row>
<row>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry colsep="1">
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry nameend="c30" namest="c10" colsep="1" align="center">
<para>low24</para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
</row>
<row>
<entry align="left">
<para>0</para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry align="right">
<para>5</para>
</entry>
<entry align="left">
<para>6</para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry align="right" colsep="1">
<para>29</para>
</entry>
<entry align="left">
<para>30</para>
</entry>
<entry align="left">
<para>31</para>
</entry>
</row>
</tbody>
</tgroup>
</informaltable>
<para>In the following figure, low21 specifies a 21-bit field occupying
the least-significant bits of a word with 4-byte alignment.</para>
<para> </para>
<informaltable frame="all" rowsep="0" colsep="0">
<tgroup cols="32">
<colspec colname="c1" colwidth="3*" />
<colspec colname="c2" colwidth="3*" />
<colspec colname="c3" colwidth="3*" />
<colspec colname="c4" colwidth="3*" />
<colspec colname="c5" colwidth="3*" />
<colspec colname="c6" colwidth="3*" />
<colspec colname="c7" colwidth="3*" />
<colspec colname="c8" colwidth="3*" />
<colspec colname="c9" colwidth="3*" />
<colspec colname="c10" colwidth="3*" />
<colspec colname="c11" colwidth="3*" colsep="1"/>
<colspec colname="c12" colwidth="3*" />
<colspec colname="c13" colwidth="3*" />
<colspec colname="c14" colwidth="3*" />
<colspec colname="c15" colwidth="3*" />
<colspec colname="c16" colwidth="3*" />
<colspec colname="c17" colwidth="3*" />
<colspec colname="c18" colwidth="3*" />
<colspec colname="c19" colwidth="3*" />
<colspec colname="c20" colwidth="3*" />
<colspec colname="c21" colwidth="3*" />
<colspec colname="c22" colwidth="3*" />
<colspec colname="c23" colwidth="3*" />
<colspec colname="c24" colwidth="3*" />
<colspec colname="c25" colwidth="3*" />
<colspec colname="c26" colwidth="3*" />
<colspec colname="c27" colwidth="3*" />
<colspec colname="c28" colwidth="3*" />
<colspec colname="c29" colwidth="3*" />
<colspec colname="c30" colwidth="3*" />
<colspec colname="c31" colwidth="3*" />
<colspec colname="c32" colwidth="3*" />
<tbody>
<row>
<entry align="left">
<para>0</para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry align="right" colsep="1">
<para>3</para>
</entry>
<entry align="left">
<para>1</para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry align="right" colsep="1">
<para>2</para>
</entry>
<entry align="left">
<para>2</para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry align="right" colsep="1">
<para>1</para>
</entry>
<entry align="left">
<para>3</para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry align="right">
<para>0</para>
</entry>
</row>
<row>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry nameend="c32" namest="c12" colsep="1" align="center">
<para>low21</para>
</entry>
</row>
<row>
<entry align="left">
<para>0</para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry align="right">
<para>10</para>
</entry>
<entry align="left">
<para>11</para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry align="right">
<para>31</para>
</entry>
</row>
</tbody>
</tgroup>
</informaltable>
<para>In the following figure, low14 specifies a 14-bit field taking up
bits 16 - 29 and possibly bit 10 (the branch prediction bit) of a word
and maintaining 4-byte alignment. The other bits remain unchanged. A
conditional branch instruction is an example usage.</para>
<para> </para>
<informaltable frame="all" rowsep="0" colsep="0">
<tgroup cols="32">
<colspec colname="c1" colwidth="3*" />
<colspec colname="c2" colwidth="3*" />
<colspec colname="c3" colwidth="3*" />
<colspec colname="c4" colwidth="3*" />
<colspec colname="c5" colwidth="3*" />
<colspec colname="c6" colwidth="3*" />
<colspec colname="c7" colwidth="3*" />
<colspec colname="c8" colwidth="3*" />
<colspec colname="c9" colwidth="3*" />
<colspec colname="c10" colwidth="3*" colsep="1" />
<colspec colname="c11" colwidth="3*" colsep="1" />
<colspec colname="c12" colwidth="3*" />
<colspec colname="c13" colwidth="3*" />
<colspec colname="c14" colwidth="3*" />
<colspec colname="c15" colwidth="3*" />
<colspec colname="c16" colwidth="3*" colsep="1" />
<colspec colname="c17" colwidth="3*" />
<colspec colname="c18" colwidth="3*" />
<colspec colname="c19" colwidth="3*" />
<colspec colname="c20" colwidth="3*" />
<colspec colname="c21" colwidth="3*" />
<colspec colname="c22" colwidth="3*" />
<colspec colname="c23" colwidth="3*" />
<colspec colname="c24" colwidth="3*" />
<colspec colname="c25" colwidth="3*" />
<colspec colname="c26" colwidth="3*" />
<colspec colname="c27" colwidth="3*" />
<colspec colname="c28" colwidth="3*" />
<colspec colname="c29" colwidth="3*" />
<colspec colname="c30" colwidth="3*" colsep="1" />
<colspec colname="c31" colwidth="3*" />
<colspec colname="c32" colwidth="3*" />
<tbody>
<row>
<entry align="left">
<para>0</para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry align="right" colsep="1">
<para>3</para>
</entry>
<entry align="left">
<para>1</para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry align="right" colsep="1">
<para>2</para>
</entry>
<entry align="left">
<para>2</para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry align="right" colsep="1">
<para>1</para>
</entry>
<entry align="left">
<para>3</para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry align="right">
<para>0</para>
</entry>
</row>
<row>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry nameend="c30" namest="c17" align="center">
<para>low14</para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
</row>
<row>
<entry>
<para>0</para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para>10</para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para>15</para>
</entry>
<entry>
<para>16</para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para>29</para>
</entry>
<entry>
<para>30</para>
</entry>
<entry>
<para>31</para>
</entry>
</row>
</tbody>
</tgroup>
</informaltable>
<para>In the following figure, half16 specifies a 16-bit field taking up
two bytes and maintaining 2-byte alignment. The immediate field of an Add
Immediate instruction is an example of this field.</para>
<para> </para>
<informaltable frame="all" rowsep="0" colsep="0">
<?dbhtml table-width="50%" ?>
<?dbfo table-width="50%" ?>
<tgroup cols="16">
<colspec colname="c1" colwidth="6*" />
<colspec colname="c2" colwidth="6*" />
<colspec colname="c3" colwidth="6*" />
<colspec colname="c4" colwidth="6*" />
<colspec colname="c5" colwidth="6*" />
<colspec colname="c6" colwidth="6*" />
<colspec colname="c7" colwidth="6*" />
<colspec colname="c8" colwidth="6*" />
<colspec colname="c9" colwidth="6*" />
<colspec colname="c10" colwidth="6*" />
<colspec colname="c11" colwidth="6*" />
<colspec colname="c12" colwidth="6*" />
<colspec colname="c13" colwidth="6*" />
<colspec colname="c14" colwidth="6*" />
<colspec colname="c15" colwidth="6*" />
<colspec colname="c16" colwidth="6*" />
<tbody>
<row>
<entry align="left">
<para>0</para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry align="right" colsep="1">
<para>1</para>
</entry>
<entry align="left">
<para>1</para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry align="right">
<para>0</para>
</entry>
</row>
<row>
<entry nameend="c16" namest="c1" align="center">
<para>half16</para>
</entry>
</row>
<row>
<entry align="left">
<para>0</para>
</entry>
<entry>
<para>1</para>
</entry>
<entry>
<para>2</para>
</entry>
<entry>
<para>3</para>
</entry>
<entry>
<para>4</para>
</entry>
<entry>
<para>5</para>
</entry>
<entry>
<para>6</para>
</entry>
<entry>
<para>7</para>
</entry>
<entry>
<para>8</para>
</entry>
<entry>
<para>9</para>
</entry>
<entry>
<para>10</para>
</entry>
<entry>
<para>11</para>
</entry>
<entry>
<para>12</para>
</entry>
<entry>
<para>13</para>
</entry>
<entry>
<para>14</para>
</entry>
<entry align="right">
<para>15</para>
</entry>
</row>
</tbody>
</tgroup>
</informaltable>
<para>In the following figure, half16ds is similar to half16, but is
really just 14 bits because the two least-significant bits must be zero
and are not really part of the field. (Used by, for example, the ldu
instruction.) In addition to the use of this relocation field with the DS
forms, half16ds relocations are also used in conjunction with DQ forms.
In those instances, the linker and assembler collaborate to create valid
DQ forms. They raise an error if the specified offset does not meet the
constraints of a valid DQ instruction form displacement.</para>
<informaltable frame="all" rowsep="0" colsep="0">
<?dbhtml table-width="50%" ?>
<?dbfo table-width="50%" ?>
<tgroup cols="16">
<colspec colname="c1" colwidth="6*" />
<colspec colname="c2" colwidth="6*" />
<colspec colname="c3" colwidth="6*" />
<colspec colname="c4" colwidth="6*" />
<colspec colname="c5" colwidth="6*" />
<colspec colname="c6" colwidth="6*" />
<colspec colname="c7" colwidth="6*" />
<colspec colname="c8" colwidth="6*" />
<colspec colname="c9" colwidth="6*" />
<colspec colname="c10" colwidth="6*" />
<colspec colname="c11" colwidth="6*" />
<colspec colname="c12" colwidth="6*" />
<colspec colname="c13" colwidth="6*" />
<colspec colname="c14" colwidth="6*" colsep="1"/>
<colspec colname="c15" colwidth="6*" />
<colspec colname="c16" colwidth="6*" />
<tbody>
<row>
<entry align="left">
<para>0</para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry align="right" colsep="1">
<para>1</para>
</entry>
<entry align="left">
<para>1</para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
<entry align="right">
<para>0</para>
</entry>
</row>
<row>
<entry nameend="c14" namest="c1" align="center">
<para>half16ds</para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
</row>
<row>
<entry align="left">
<para>0</para>
</entry>
<entry>
<para>1</para>
</entry>
<entry>
<para>2</para>
</entry>
<entry>
<para>3</para>
</entry>
<entry>
<para>4</para>
</entry>
<entry>
<para>5</para>
</entry>
<entry>
<para>6</para>
</entry>
<entry>
<para>7</para>
</entry>
<entry>
<para>8</para>
</entry>
<entry>
<para>9</para>
</entry>
<entry>
<para>10</para>
</entry>
<entry>
<para>11</para>
</entry>
<entry>
<para>12</para>
</entry>
<entry>
<para>13</para>
</entry>
<entry>
<para>14</para>
</entry>
<entry align="right">
<para>15</para>
</entry>
</row>
</tbody>
</tgroup>
</informaltable>
</section>
<section xml:id="dbdoclet.50655241_51269">
<title>Relocation Notations</title>
<para>The following notations are used in the relocation table.</para>
<para> </para>
<informaltable frame="none" rowsep="0" colsep="0">
<tgroup cols="2">
<colspec colname="c1" colwidth="20*" />
<colspec colname="c2" colwidth="80*" />
<tbody>
<row>
<entry>
<para>A</para>
</entry>
<entry>
<para>Represents the addend used to compute the value of the
relocatable field.</para>
</entry>
</row>
<row>
<entry>
<para>B</para>
</entry>
<entry>
<para>Represents the base address at which a shared object file
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.</para>
</entry>
</row>
<row>
<entry>
<para>G</para>
</entry>
<entry>
<para>Represents the offset from .TOC. at which the address of
the relocation entrys symbol resides during execution. This
implies the creation of a .got section. For more information,
see
<xref linkend="dbdoclet.50655240___RefHeading___Toc377640591" /> and
<xref linkend="dbdoclet.50655242_47739" />.</para>
<para>Reference in a calculation to the value G implicitly
creates a GOT entry for the indicated symbol.</para>
</entry>
</row>
<row>
<entry>
<para>L</para>
</entry>
<entry>
<para>Represents the section offset or address of the procedure
linkage table entry for the symbol. This implies the creation
of a .plt section if one does not already exist. It also
implies the creation of a procedure linkage table (PLT) entry
for resolving the symbol. For an unresolved symbol, the PLT
entry points to a PLT resolver stub. For a resolved symbol, a
procedure linkage table entry holds the final effective address
of a dynamically resolved symbol (see
<xref linkend="dbdoclet.50655242_20388" />).</para>
</entry>
</row>
<row>
<entry>
<para>M</para>
</entry>
<entry>
<para>Similar to G, except that the address that is stored may
be the address of the procedure linkage table entry for the
symbol.</para>
</entry>
</row>
<row>
<entry>
<para>P</para>
</entry>
<entry>
<para>Represents the place (section offset or address) of the
storage unit being relocated (computed using r_offset).</para>
</entry>
</row>
<row>
<entry>
<para>R</para>
</entry>
<entry>
<para>Represents the offset of the symbol within the section in
which the symbol is defined (its section-relative
address).</para>
</entry>
</row>
<row>
<entry>
<para>S</para>
</entry>
<entry>
<para>Represents the value of the symbol whose index resides in
the relocation entry.</para>
</entry>
</row>
<row>
<entry>
<para>+</para>
</entry>
<entry>
<para>Denotes 64-bit modulus addition.</para>
</entry>
</row>
<row>
<entry>
<para>-</para>
</entry>
<entry>
<para>Denotes 64-bit modulus subtraction.</para>
</entry>
</row>
<row>
<entry>
<para>&gt;&gt;</para>
</entry>
<entry>
<para>Denotes arithmetic right-shifting.</para>
</entry>
</row>
<row>
<entry>
<para>#lo(value)</para>
</entry>
<entry>
<para>Denotes the least-significant 16 bits of the indicated
value. That is:</para>
<para>#lo(x) = (x &amp; 0xffff).</para>
</entry>
</row>
<row>
<entry>
<para>#hi(value)</para>
</entry>
<entry>
<para>Denotes bits 16 - 63 of the indicated value. That
is:</para>
<para>#hi(x) = x &gt;&gt; 16</para>
</entry>
</row>
<row>
<entry>
<para>#ha(value)</para>
</entry>
<entry>
<para>Denotes the high adjusted value: bits 16 - 63 of the
indicated value, compensating for #lo( ) being treated as a
signed number. That is:</para>
<para>#ha(x) = (x + 0x8000) &gt;&gt; 16</para>
</entry>
</row>
<row>
<entry>
<para>TP</para>
</entry>
<entry>
<para>The value of the thread pointer in general-purpose
register r13.</para>
</entry>
</row>
<row>
<entry>
<para>TLS_TP_OFFSET</para>
</entry>
<entry>
<para>The constant value 0x7000, representing the offset (in
bytes) of the location that the thread pointer is initialized
to point to, relative to the start of the thread local storage
for the first initially available module.</para>
</entry>
</row>
<row>
<entry>
<para>TCB_LENGTH</para>
</entry>
<entry>
<para>The constant value 0x8, representing the length of the
thread control block (TCB) in bytes.</para>
</entry>
</row>
<row>
<entry>
<para>tcb</para>
</entry>
<entry>
<para>Represents the base address of the TCB.</para>
<para>tcb = (tp - (TLS_TP_OFFSET + TCB_LENGTH))</para>
</entry>
</row>
<row>
<entry>
<para>dtv</para>
</entry>
<entry>
<para>Represents the base address of the dynamic thread vector
(DTV).</para>
<para>dtv = tcb[0]</para>
</entry>
</row>
<row>
<entry>
<para>dtpmod</para>
</entry>
<entry>
<para>Represents the load module index of the load module that
contains the definition of the symbol being relocated and is
used to index the DTV.</para>
</entry>
</row>
<row>
<entry>
<para>dtprel</para>
</entry>
<entry>
<para>Represents the offset of the symbol being relocated
relative to the value of dtv[dtpmod].</para>
<para>dtv[dtpmod] + dtprel = (S + A)</para>
</entry>
</row>
<row>
<entry>
<para>tprel</para>
</entry>
<entry>
<para>Represents the offset of the symbol being relocated
relative to the TP.</para>
<para>tp + tprel = (S + A)</para>
</entry>
</row>
<row>
<entry>
<para>tlsgd</para>
</entry>
<entry>
<para>Allocates two contiguous entries in the GOT to hold a
tls_index structure, with values dtpmod and dtprel, and
computes the offset from .TOC. of the first entry.</para>
<para>If n is the offset computed:</para>
<para>GOT[n] = dtpmod</para>
<para>GOT[n + 1] = dtprel</para>
<para>The call to __tls_get_addr ( ) happens as:</para>
<para>__tls_get_addr ((tls_index *) &amp;GOT[n])</para>
</entry>
</row>
<row>
<entry>
<para>tlsld</para>
</entry>
<entry>
<para>Allocates two contiguous entries in the GOT to hold a
tls_index structure, with values dtpmod and zero, and computes
the offset from .TOC. of the first entry.</para>
<para>If n is the offset computed:</para>
<para>GOT[n] = dtpmod</para>
<para>GOT[n + 1] = 0</para>
<para>The call to __tls_get_addr ( ) happens as:</para>
<para>__tls_get_addr ((tls_index *) &amp;GOT[n])</para>
</entry>
</row>
<row>
<entry>
<para>tprelg</para>
</entry>
<entry>
<para>Allocates an entry in the GOT with value tprel, and
computes the offset from .TOC. of the entry.</para>
<para>If n is the offset computed:</para>
<para>GOT[n] = tprel</para>
<para>The value of tprel is loaded into a register from the
location (GOT + n) to be used in an r2 form instruction.</para>
</entry>
</row>
</tbody>
</tgroup>
</informaltable>
<note>
<para>Relocations flagged with an asterisk(*) will
trigger a relocation failure if the value computed does
not fit in the field specified.</para>
</note>
</section>
<section>
<title>Relocation Types Table</title>
<para>The following rules apply to the relocation types defined in
<xref linkend="dbdoclet.50655241_47572" />:</para>
<itemizedlist>
<listitem>
<para>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 in which the names contain 24, the upper
39 bits of the value computed before shifting must all be the same.
For relocation types in which the names contain 14 or 24, the low 2
bits of the value computed before shifting must all be zero.</para>
</listitem>
<listitem>
<para>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.</para>
</listitem>
<listitem>
<para>Relocations that refer to half16ds (56 - 66, 87 - 88, 91 - 92,
95 - 96, and 101 - 102) are to be used to direct the linker to look
at the underlying instruction and treat the field as a DS or DQ
field. ABI-compliant tools should give an error for attempts to
relocate an address to a value that is not divisible by 4.</para>
</listitem>
</itemizedlist>
<para> </para>
<table frame="all" pgwide="1" xml:id="dbdoclet.50655241_47572">
<title>Relocation Table</title>
<tgroup cols="4">
<colspec colname="c1" colwidth="30*" align="center" />
<colspec colname="c2" colwidth="15*" align="center" />
<colspec colname="c3" colwidth="15*" align="center" />
<colspec colname="c4" colwidth="40*" align="center" />
<thead>
<row>
<entry>
<para>
<emphasis role="bold">Relocation Name</emphasis>
</para>
</entry>
<entry>
<para>
<emphasis role="bold">Value</emphasis>
</para>
</entry>
<entry>
<para>
<emphasis role="bold">Field</emphasis>
</para>
</entry>
<entry>
<para>
<emphasis role="bold">Expression</emphasis>
</para>
</entry>
</row>
</thead>
<tfoot>
<row>
<entry nameend="c4" namest="c1" align="left">
<note>
<para>Relocation values 8, 9, 12, 13, 18, 23, 32,
and 247 are not used. This is to maintain a
correspondence to the relocation values used by the
32-bit PowerPC ELF ABI.
</para></note>
</entry>
</row>
</tfoot>
<tbody>
<row>
<entry>
<para>R_PPC64_NONE</para>
</entry>
<entry>
<para>0</para>
</entry>
<entry>
<para>none</para>
</entry>
<entry>
<para>none</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_ADDR32</para>
</entry>
<entry>
<para>1</para>
</entry>
<entry>
<para>word32*</para>
</entry>
<entry>
<para>S + A</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_ADDR24</para>
</entry>
<entry>
<para>2</para>
</entry>
<entry>
<para>low24*</para>
</entry>
<entry>
<para>(S + A) &gt;&gt; 2</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_ADDR16</para>
</entry>
<entry>
<para>3</para>
</entry>
<entry>
<para>half16*</para>
</entry>
<entry>
<para>S + A</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_ADDR16_LO</para>
</entry>
<entry>
<para>4</para>
</entry>
<entry>
<para>half16</para>
</entry>
<entry>
<para>#lo(S + A)</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_ADDR16_HI</para>
</entry>
<entry>
<para>5</para>
</entry>
<entry>
<para>half16*</para>
</entry>
<entry>
<para>#hi(S + A)</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_ADDR16_HA</para>
</entry>
<entry>
<para>6</para>
</entry>
<entry>
<para>half16*</para>
</entry>
<entry>
<para>#ha(S + A)</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_ADDR14</para>
</entry>
<entry>
<para>7</para>
</entry>
<entry>
<para>low14*</para>
</entry>
<entry>
<para>(S + A) &gt;&gt; 2</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_REL24</para>
</entry>
<entry>
<para>10</para>
</entry>
<entry>
<para>low24*</para>
</entry>
<entry>
<para>(S + A - P) &gt;&gt; 2</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_REL14</para>
</entry>
<entry>
<para>11</para>
</entry>
<entry>
<para>low14*</para>
</entry>
<entry>
<para>(S + A - P) &gt;&gt; 2</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_GOT16</para>
</entry>
<entry>
<para>14</para>
</entry>
<entry>
<para>half16*</para>
</entry>
<entry>
<para>G</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_GOT16_LO</para>
</entry>
<entry>
<para>15</para>
</entry>
<entry>
<para>half16</para>
</entry>
<entry>
<para>#lo(G)</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_GOT16_HI</para>
</entry>
<entry>
<para>16</para>
</entry>
<entry>
<para>half16*</para>
</entry>
<entry>
<para>#hi(G)</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_GOT16_HA</para>
</entry>
<entry>
<para>17</para>
</entry>
<entry>
<para>half16*</para>
</entry>
<entry>
<para>#ha(G)</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_COPY</para>
</entry>
<entry>
<para>19</para>
</entry>
<entry>
<para>varies</para>
</entry>
<entry>
<para>See
<xref linkend="dbdoclet.50655241_90220" />.</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_GLOB_DAT</para>
</entry>
<entry>
<para>20</para>
</entry>
<entry>
<para>doubleword64</para>
</entry>
<entry>
<para>S + A</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_JMP_SLOT</para>
</entry>
<entry>
<para>21</para>
</entry>
<entry>
<para>doubleword64</para>
</entry>
<entry>
<para>See
<xref linkend="dbdoclet.50655241_90220" />.</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_RELATIVE</para>
</entry>
<entry>
<para>22</para>
</entry>
<entry>
<para>doubleword64</para>
</entry>
<entry>
<para>B + A</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_UADDR32</para>
</entry>
<entry>
<para>24</para>
</entry>
<entry>
<para>word32*</para>
</entry>
<entry>
<para>S + A</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_UADDR16</para>
</entry>
<entry>
<para>25</para>
</entry>
<entry>
<para>half16*</para>
</entry>
<entry>
<para>S + A</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_REL32</para>
</entry>
<entry>
<para>26</para>
</entry>
<entry>
<para>word32*</para>
</entry>
<entry>
<para>S + A - P</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_PLT32</para>
</entry>
<entry>
<para>27</para>
</entry>
<entry>
<para>word32*</para>
</entry>
<entry>
<para>L</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_PLTREL32</para>
</entry>
<entry>
<para>28</para>
</entry>
<entry>
<para>word32*</para>
</entry>
<entry>
<para>L - P</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_PLT16_LO</para>
</entry>
<entry>
<para>29</para>
</entry>
<entry>
<para>half16</para>
</entry>
<entry>
<para>#lo(L)</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_PLT16_HI</para>
</entry>
<entry>
<para>30</para>
</entry>
<entry>
<para>half16*</para>
</entry>
<entry>
<para>#hi(L)</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_PLT16_HA</para>
</entry>
<entry>
<para>31</para>
</entry>
<entry>
<para>half16*</para>
</entry>
<entry>
<para>#ha(L)</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_SECTOFF</para>
</entry>
<entry>
<para>33</para>
</entry>
<entry>
<para>half16*</para>
</entry>
<entry>
<para>R + A</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_SECTOFF_LO</para>
</entry>
<entry>
<para>34</para>
</entry>
<entry>
<para>half16</para>
</entry>
<entry>
<para>#lo(R + A)</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_SECTOFF_HI</para>
</entry>
<entry>
<para>35</para>
</entry>
<entry>
<para>half16*</para>
</entry>
<entry>
<para>#hi(R + A)</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_SECTOFF_HA</para>
</entry>
<entry>
<para>36</para>
</entry>
<entry>
<para>half16*</para>
</entry>
<entry>
<para>#ha(R + A)</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_REL30</para>
</entry>
<entry>
<para>37</para>
</entry>
<entry>
<para>word30</para>
</entry>
<entry>
<para>(S + A - P) &gt;&gt; 2</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_ADDR64</para>
</entry>
<entry>
<para>38</para>
</entry>
<entry>
<para>doubleword64</para>
</entry>
<entry>
<para>S + A</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_ADDR16_HIGHER</para>
</entry>
<entry>
<para>39</para>
</entry>
<entry>
<para>half16</para>
</entry>
<entry>
<para>#higher(S + A)</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_ADDR16_HIGHERA</para>
</entry>
<entry>
<para>40</para>
</entry>
<entry>
<para>half16</para>
</entry>
<entry>
<para>#highera(S + A)</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_ADDR16_HIGHEST</para>
</entry>
<entry>
<para>41</para>
</entry>
<entry>
<para>half16</para>
</entry>
<entry>
<para>#highest(S + A)</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_ADDR16_HIGHESTA</para>
</entry>
<entry>
<para>42</para>
</entry>
<entry>
<para>half16</para>
</entry>
<entry>
<para>#highesta(S + A)</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_UADDR64</para>
</entry>
<entry>
<para>43</para>
</entry>
<entry>
<para>doubleword64</para>
</entry>
<entry>
<para>S + A</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_REL64</para>
</entry>
<entry>
<para>44</para>
</entry>
<entry>
<para>doubleword64</para>
</entry>
<entry>
<para>S + A - P</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_PLT64</para>
</entry>
<entry>
<para>45</para>
</entry>
<entry>
<para>doubleword64</para>
</entry>
<entry>
<para>L</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_PLTREL64</para>
</entry>
<entry>
<para>46</para>
</entry>
<entry>
<para>doubleword64</para>
</entry>
<entry>
<para>L - P</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_TOC16</para>
</entry>
<entry>
<para>47</para>
</entry>
<entry>
<para>half16*</para>
</entry>
<entry>
<para>S + A - .TOC.</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_TOC16_LO</para>
</entry>
<entry>
<para>48</para>
</entry>
<entry>
<para>half16</para>
</entry>
<entry>
<para>#lo(S + A - .TOC.)</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_TOC16_HI</para>
</entry>
<entry>
<para>49</para>
</entry>
<entry>
<para>half16*</para>
</entry>
<entry>
<para>#hi(S + A - .TOC.)</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_TOC16_HA</para>
</entry>
<entry>
<para>50</para>
</entry>
<entry>
<para>half16*</para>
</entry>
<entry>
<para>#ha(S + A - .TOC.)</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_TOC</para>
</entry>
<entry>
<para>51</para>
</entry>
<entry>
<para>doubleword64</para>
</entry>
<entry>
<para>.TOC.</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_PLTGOT16</para>
</entry>
<entry>
<para>52</para>
</entry>
<entry>
<para>half16*</para>
</entry>
<entry>
<para>M</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_PLTGOT16_LO</para>
</entry>
<entry>
<para>53</para>
</entry>
<entry>
<para>half16</para>
</entry>
<entry>
<para>#lo(M)</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_PLTGOT16_HI</para>
</entry>
<entry>
<para>54</para>
</entry>
<entry>
<para>half16*</para>
</entry>
<entry>
<para>#hi(M)</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_PLTGOT16_HA</para>
</entry>
<entry>
<para>55</para>
</entry>
<entry>
<para>half16*</para>
</entry>
<entry>
<para>#ha(M)</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_ADDR16_DS</para>
</entry>
<entry>
<para>56</para>
</entry>
<entry>
<para>half16ds*</para>
</entry>
<entry>
<para>(S + A) &gt;&gt; 2</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_ADDR16_LO_DS</para>
</entry>
<entry>
<para>57</para>
</entry>
<entry>
<para>half16ds</para>
</entry>
<entry>
<para>#lo(S + A) &gt;&gt; 2</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_GOT16_DS</para>
</entry>
<entry>
<para>58</para>
</entry>
<entry>
<para>half16ds*</para>
</entry>
<entry>
<para>G &gt;&gt; 2</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_GOT16_LO_DS</para>
</entry>
<entry>
<para>59</para>
</entry>
<entry>
<para>half16ds</para>
</entry>
<entry>
<para>#lo(G) &gt;&gt; 2</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_PLT16_LO_DS</para>
</entry>
<entry>
<para>60</para>
</entry>
<entry>
<para>half16ds</para>
</entry>
<entry>
<para>#lo(L) &gt;&gt; 2</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_SECTOFF_DS</para>
</entry>
<entry>
<para>61</para>
</entry>
<entry>
<para>half16ds*</para>
</entry>
<entry>
<para>(R + A) &gt;&gt; 2</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_SECTOFF_LO_DS</para>
</entry>
<entry>
<para>62</para>
</entry>
<entry>
<para>half16ds</para>
</entry>
<entry>
<para>#lo(R + A) &gt;&gt; 2</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_TOC16_DS</para>
</entry>
<entry>
<para>63</para>
</entry>
<entry>
<para>half16ds*</para>
</entry>
<entry>
<para>(S + A - .TOC.) &gt;&gt; 2</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_TOC16_LO_DS</para>
</entry>
<entry>
<para>64</para>
</entry>
<entry>
<para>half16ds</para>
</entry>
<entry>
<para>#lo(S + A - .TOC.) &gt;&gt; 2</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_PLTGOT16_DS</para>
</entry>
<entry>
<para>65</para>
</entry>
<entry>
<para>half16ds*</para>
</entry>
<entry>
<para>M &gt;&gt; 2</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_PLTGOT16_LO_DS</para>
</entry>
<entry>
<para>66</para>
</entry>
<entry>
<para>half16ds</para>
</entry>
<entry>
<para>#lo(M) &gt;&gt; 2</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_TLS</para>
</entry>
<entry>
<para>67</para>
</entry>
<entry>
<para>none</para>
</entry>
<entry>
<para>none</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_DTPMOD64</para>
</entry>
<entry>
<para>68</para>
</entry>
<entry>
<para>doubleword64</para>
</entry>
<entry>
<para>@dtpmod</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_TPREL16</para>
</entry>
<entry>
<para>69</para>
</entry>
<entry>
<para>half16*</para>
</entry>
<entry>
<para>@tprel</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_TPREL16_LO</para>
</entry>
<entry>
<para>70</para>
</entry>
<entry>
<para>half16</para>
</entry>
<entry>
<para>#lo(@tprel)</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_TPREL16_HI</para>
</entry>
<entry>
<para>71</para>
</entry>
<entry>
<para>half16*</para>
</entry>
<entry>
<para>#hi(@tprel)</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_TPREL16_HA</para>
</entry>
<entry>
<para>72</para>
</entry>
<entry>
<para>half16*</para>
</entry>
<entry>
<para>#ha(@tprel)</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_TPREL64</para>
</entry>
<entry>
<para>73</para>
</entry>
<entry>
<para>doubleword64</para>
</entry>
<entry>
<para>@tprel</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_DTPREL16</para>
</entry>
<entry>
<para>74</para>
</entry>
<entry>
<para>half16*</para>
</entry>
<entry>
<para>@dtprel</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_DTPREL16_LO</para>
</entry>
<entry>
<para>75</para>
</entry>
<entry>
<para>half16</para>
</entry>
<entry>
<para>#lo(@dtprel)</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_DTPREL16_HI</para>
</entry>
<entry>
<para>76</para>
</entry>
<entry>
<para>half16*</para>
</entry>
<entry>
<para>#hi(@dtprel)</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_DTPREL16_HA</para>
</entry>
<entry>
<para>77</para>
</entry>
<entry>
<para>half16*</para>
</entry>
<entry>
<para>#ha(@dtprel)</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_DTPREL64</para>
</entry>
<entry>
<para>78</para>
</entry>
<entry>
<para>doubleword64</para>
</entry>
<entry>
<para>@dtprel</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_GOT_TLSGD16</para>
</entry>
<entry>
<para>79</para>
</entry>
<entry>
<para>half16*</para>
</entry>
<entry>
<para>@got@tlsgd</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_GOT_TLSGD16_LO</para>
</entry>
<entry>
<para>80</para>
</entry>
<entry>
<para>half16</para>
</entry>
<entry>
<para>#lo(@got@tlsgd)</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_GOT_TLSGD16_HI</para>
</entry>
<entry>
<para>81</para>
</entry>
<entry>
<para>half16*</para>
</entry>
<entry>
<para>#hi(@got@tlsgd)</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_GOT_TLSGD16_HA</para>
</entry>
<entry>
<para>82</para>
</entry>
<entry>
<para>half16*</para>
</entry>
<entry>
<para>#ha(@got@tlsgd)</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_GOT_TLSLD16</para>
</entry>
<entry>
<para>83</para>
</entry>
<entry>
<para>half16*</para>
</entry>
<entry>
<para>@got@tlsld</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_GOT_TLSLD16_LO</para>
</entry>
<entry>
<para>84</para>
</entry>
<entry>
<para>half16</para>
</entry>
<entry>
<para>#lo(@got@tlsld)</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_GOT_TLSLD16_HI</para>
</entry>
<entry>
<para>85</para>
</entry>
<entry>
<para>half16*</para>
</entry>
<entry>
<para>#hi(@got@tlsld)</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_GOT_TLSLD16_HA</para>
</entry>
<entry>
<para>86</para>
</entry>
<entry>
<para>half16*</para>
</entry>
<entry>
<para>#ha(@got@tlsld)</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_GOT_TPREL16_DS</para>
</entry>
<entry>
<para>87</para>
</entry>
<entry>
<para>half16ds*</para>
</entry>
<entry>
<para>@got@tprel</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_GOT_TPREL16_LO_DS</para>
</entry>
<entry>
<para>88</para>
</entry>
<entry>
<para>half16ds</para>
</entry>
<entry>
<para>#lo(@got@tprel)</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_GOT_TPREL16_HI</para>
</entry>
<entry>
<para>89</para>
</entry>
<entry>
<para>half16*</para>
</entry>
<entry>
<para>#hi(@got@tprel)</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_GOT_TPREL16_HA</para>
</entry>
<entry>
<para>90</para>
</entry>
<entry>
<para>half16*</para>
</entry>
<entry>
<para>#ha(@got@tprel)</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_GOT_DTPREL16_DS</para>
</entry>
<entry>
<para>91</para>
</entry>
<entry>
<para>half16ds*</para>
</entry>
<entry>
<para>@got@dtprel</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_GOT_DTPREL16_LO_DS</para>
</entry>
<entry>
<para>92</para>
</entry>
<entry>
<para>half16ds</para>
</entry>
<entry>
<para>#lo(@got@dtprel)</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_GOT_DTPREL16_HI</para>
</entry>
<entry>
<para>93</para>
</entry>
<entry>
<para>half16*</para>
</entry>
<entry>
<para>#hi(@got@dtprel)</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_GOT_DTPREL16_HA</para>
</entry>
<entry>
<para>94</para>
</entry>
<entry>
<para>half16*</para>
</entry>
<entry>
<para>#ha(@got@dtprel)</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_TPREL16_DS</para>
</entry>
<entry>
<para>95</para>
</entry>
<entry>
<para>half16ds*</para>
</entry>
<entry>
<para>@tprel</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_TPREL16_LO_DS</para>
</entry>
<entry>
<para>96</para>
</entry>
<entry>
<para>half16ds</para>
</entry>
<entry>
<para>#lo(@tprel)</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_TPREL16_HIGHER</para>
</entry>
<entry>
<para>97</para>
</entry>
<entry>
<para>half16</para>
</entry>
<entry>
<para>#higher(@tprel)</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_TPREL16_HIGHERA</para>
</entry>
<entry>
<para>98</para>
</entry>
<entry>
<para>half16</para>
</entry>
<entry>
<para>#highera(@tprel)</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_TPREL16_HIGHEST</para>
</entry>
<entry>
<para>99</para>
</entry>
<entry>
<para>half16</para>
</entry>
<entry>
<para>#highest(@tprel)</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_TPREL16_HIGHESTA</para>
</entry>
<entry>
<para>100</para>
</entry>
<entry>
<para>half16</para>
</entry>
<entry>
<para>#highesta(@tprel)</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_DTPREL16_DS</para>
</entry>
<entry>
<para>101</para>
</entry>
<entry>
<para>half16ds*</para>
</entry>
<entry>
<para>@dtprel</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_DTPREL16_LO_DS</para>
</entry>
<entry>
<para>102</para>
</entry>
<entry>
<para>half16ds</para>
</entry>
<entry>
<para>#lo(@dtprel)</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_DTPREL16_HIGHER</para>
</entry>
<entry>
<para>103</para>
</entry>
<entry>
<para>half16</para>
</entry>
<entry>
<para>#higher(@dtprel)</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_DTPREL16_HIGHERA</para>
</entry>
<entry>
<para>104</para>
</entry>
<entry>
<para>half16</para>
</entry>
<entry>
<para>#highera(@dtprel)</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_DTPREL16_HIGHEST</para>
</entry>
<entry>
<para>105</para>
</entry>
<entry>
<para>half16</para>
</entry>
<entry>
<para>#highest(@dtprel)</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_DTPREL16_HIGHESTA</para>
</entry>
<entry>
<para>106</para>
</entry>
<entry>
<para>half16</para>
</entry>
<entry>
<para>#highesta(@dtprel)</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_TLSGD</para>
</entry>
<entry>
<para>107</para>
</entry>
<entry>
<para>none</para>
</entry>
<entry>
<para>none</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_TLSLD</para>
</entry>
<entry>
<para>108</para>
</entry>
<entry>
<para>none</para>
</entry>
<entry>
<para>none</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_TOCSAVE</para>
</entry>
<entry>
<para>109</para>
</entry>
<entry>
<para>none</para>
</entry>
<entry>
<para>none</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_ADDR16_HIGH</para>
</entry>
<entry>
<para>110</para>
</entry>
<entry>
<para>half16</para>
</entry>
<entry>
<para>#high(S + A)</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_ADDR16_HIGHA</para>
</entry>
<entry>
<para>111</para>
</entry>
<entry>
<para>half16</para>
</entry>
<entry>
<para>#higha(S + A)</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_TPREL16_HIGH</para>
</entry>
<entry>
<para>112</para>
</entry>
<entry>
<para>half16</para>
</entry>
<entry>
<para>#high(@tprel)</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_TPREL16_HIGHA</para>
</entry>
<entry>
<para>113</para>
</entry>
<entry>
<para>half16</para>
</entry>
<entry>
<para>#higha(@tprel)</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_DTPREL16_HIGH</para>
</entry>
<entry>
<para>114</para>
</entry>
<entry>
<para>half16</para>
</entry>
<entry>
<para>#high(@dtprel)</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_DTPREL16_HIGHA</para>
</entry>
<entry>
<para>115</para>
</entry>
<entry>
<para>half16</para>
</entry>
<entry>
<para>#higha(@dtprel)</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_REL24_NOTOC</para>
</entry>
<entry>
<para>116</para>
</entry>
<entry>
<para>low24*</para>
</entry>
<entry>
<para>(S + A - P) &gt;&gt; 2</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_ADDR64_LOCAL</para>
</entry>
<entry>
<para>117</para>
</entry>
<entry>
<para>doubleword64</para>
</entry>
<entry>
<para>S + A (See
<xref linkend="dbdoclet.50655241_90220" />.)</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_IRELATIVE</para>
</entry>
<entry>
<para>248</para>
</entry>
<entry>
<para>doubleword64</para>
</entry>
<entry>
<para>See
<xref linkend="dbdoclet.50655241_90220" />.</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_REL16</para>
</entry>
<entry>
<para>249</para>
</entry>
<entry>
<para>half16*</para>
</entry>
<entry>
<para>S + A - P</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_REL16_LO</para>
</entry>
<entry>
<para>250</para>
</entry>
<entry>
<para>half16</para>
</entry>
<entry>
<para>#lo(S + A - P)</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_REL16_HI</para>
</entry>
<entry>
<para>251</para>
</entry>
<entry>
<para>half16*</para>
</entry>
<entry>
<para>#hi(S + A - P)</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_REL16_HA</para>
</entry>
<entry>
<para>252</para>
</entry>
<entry>
<para>half16*</para>
</entry>
<entry>
<para>#ha(S + A - P)</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_GNU_VTINHERIT</para>
</entry>
<entry>
<para>253</para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_GNU_VTENTRY</para>
</entry>
<entry>
<para>254</para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
</row>
</tbody>
</tgroup>
</table>
</section>
<section xml:id="dbdoclet.50655241_90220">
<title>Relocation Descriptions</title>
<para>The following list describes relocations that can require special
handling or description.</para>
<para>R_PPC64_GOT16*</para>
<para>These relocation types are similar to the corresponding
R_PPC64_ADDR16* types. However, they refer to the address of the symbols
GOT entry and instruct the link editor to build a GOT.</para>
<para>R_PPC64_PLTGOT16*</para>
<para>These relocation types are similar to the corresponding
R_PPC64_GOT16* types. However, if the link editor
<emphasis>cannot</emphasis> determine the actual value of the symbol, the
GOT entry may contain the address of an entry in the procedure linkage
table. The link editor creates that entry in the procedure linkage table
and stores that address in the GOT entry. This permits lazy resolution of
function symbols at run time. If the link editor
<emphasis>can</emphasis> determine the value of the symbol, it stores that
value in the corresponding GOT entry. The link editor may generate an
R_PPC64_GLOB_DAT relocation as usual.</para>
<para>R_PPC64_PLTREL32, R_PPC64_PLTREL64</para>
<para>These relocations indicate that reference to a symbol should be
resolved through a call to the symbols procedure linkage table entry.
Additionally, it instructs the link editor to build a procedure linkage
table for the executable or shared object if one is not created.</para>
<para><anchor xml:id="dbdoclet.50655241_R_PPC_COPY" xreflabel="" />R_PPC64_COPY</para>
<para>This relocation type is created by the link editor 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 relocatable file and in a shared object file. During execution,
the dynamic linker copies data associated with the shared objects symbol
to the location specified by the offset.</para>
<para>R_PPC64_GLOB_DAT</para>
<para>This relocation type allows determination of the correspondence
between symbols and GOT entries. It is similar to R_PPC64_ADDR64.
However, it sets a GOT entry to the address of the specified
symbol.</para>
<para>R_PPC64_JMP_SLOT</para>
<para>This relocation type is created by the link editor for dynamic
linking. Its offset member gives the location of a procedure linkage
table (PLT) entry. The dynamic linker modifies the PLT entry to transfer
control to the designated symbols address (see
<xref linkend="dbdoclet.50655242_20388" />).</para>
<para>R_PPC64_RELATIVE</para>
<para>This relocation type is created by the link editor for dynamic
linking. Its offset member gives a location within a shared object that
contains a value representing a relative address. The corresponding
virtual address is computed by the dynamic linker. It adds 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.</para>
<para>R_PPC64_IRELATIVE</para>
<para>The link editor creates this relocation type for dynamic linking.
Its addend member specifies the global entry-point location of a resolver
function returning a function pointer. It is used to implement the
STT_GNU_IFUNC framework. The resolver is called, and the returned pointer
copied into the location specified by the relocation offset
member.</para>
<para>R_PPC64_TLS, R_PPC64_TLSGD, R_PPC64_TLSLD</para>
<para>Used as markers on thread local storage (TLS) code sequences, these
relocations tie the entire sequence with a particular TLS symbol. For
more information, see
<xref linkend="dbdoclet.50655241_90241" />.</para>
<para>R_PPC64_TOCSAVE</para>
<para>This relocation type indicates a position where a TOC save may be
inserted in the function to avoid a TOC save as part of the PLT stub
code. A nop can be emitted by a compiler in a function's prologue code. A
link editor can change it to a TOC pointer save instruction. This marker
relocation is placed on the prologue nop and on nops after bl
instructions, with the symbol plus addend pointing to the prologue nop.
If the link editor uses the prologue to save r2, it may omit r2 saves in
the PLT call stub code emitted for calls marked by
R_PPC64_TOCSAVE.</para>
<para>R_PPC64_UADDR*</para>
<para>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.</para>
<para>R_PPC64_ADDR64_LOCAL</para>
<para>When a separate local entry point exists, this relocation type is
used to initialize a memory location with the address of that local entry
point.</para>
<para>R_PPC64_REL24_NOTOC</para>
<para>This relocation type is used to specify a function call where the
TOC pointer is not initialized. It is similar to R_PPC64_REL24 in that it
specifies a symbol to be resolved. However, if the symbol is resolved by
inserting a call to a PLT stub code, the PLT stub code must not rely on
the presence of a valid TOC base address in TOC register r2 to reference
the PLT function table.</para>
</section>
<section>
<title>Assembler Syntax</title>
<para>The offset from .TOC. in the GOT where the value of the symbol is
stored is given by the assembly syntax symbol@got. The value of the
symbol alone is the address of the variable named symbol.</para>
<para>For example:</para>
<programlisting>addis r3, r2,x@got@ha
ld r3,x@got@l(r3)</programlisting>
<para>Although the Power ISA only defines 16-bit displacements, many TOCs
(and hence a GOT) are larger then 64 KB but fit within 2 GB, which can be
addressed with 32-bit offsets from r2. Therefore, this ABI defines a
simple syntax for 32-bit offsets to the GOT.</para>
<para>The syntaxes SYMBOL@got@ha, SYMBOL@got@h, and SYMBOL@got@l refer to
the high adjusted, high, and low parts of the GOT offset. (For an
explanation of the meaning of “high adjusted,” see
<xref linkend="dbdoclet.50655241_18894" />). SYMBOL@got@ha corresponds to
bits 32 - 63 of the offset within the global offset table with adjustment
for the sign extension of the low-order offset bits. SYMBOL@got@l
corresponds to the 16 low-order bits of the offset within the global
offset table.</para>
<para>The syntax SYMBOL@toc refers to the value (SYMBOL - .TOC.), where
.TOC. represents the TOC base for the current object file. This provides
the address of the variable whose name is SYMBOL as an offset from the
TOC base.</para>
<para>As with the GOT, the syntaxes SYMBOL@toc@ha, SYMBOL@toc@h, and
SYMBOL@toc@l refer to the high adjusted, high, and low parts of the TOC
offset.</para>
<para>The syntax SYMBOL@got@plt may be used to refer to the offset in the
TOC of a procedure linkage table entry stored in the global offset table.
The corresponding syntaxes SYMBOL@got@plt@ha, SYMBOL@got@plt@h, and
SYMBOL@got@plt@l are also defined.</para>
<para> </para>
<note>
<para>
If X is a variable stored in the TOC,
then X@got is the offset within the TOC of a doubleword whose
value is X@toc.</para>
</note>
<para>The special symbol .TOC. is used to represent the TOC base for the
current object file.</para>
<para>The following code might appear in a PIC code setup sequence to
compute the distance from a function entry point to the TOC base:</para>
<programlisting>addis 2,12,.TOC.-func@ha
addi 2,2,.TOC.-func@l</programlisting>
<para>The syntax
<literal>SYMBOL@localentry</literal> refers to the value of the local
entry point associated with a function symbol. It can be used to
initialize a memory word with the address of the local entry point as
follows:</para>
<programlisting>.quad func@localentry</programlisting>
</section>
</section>
<section>
<title>Assembler- and Linker-Mediated Executable Optimization</title>
<para>To optimize object code, the assembler and linker may rewrite object
code to implement the function call and return conventions and access to
global and thread-local data. It is the responsibility of compilers and
programmers to generate assembly programs and objects that conform to the
requirements as indicated in this section.</para>
<section xml:id="dbdoclet.50655241_69294">
<title>Function Call</title>
<para>The static linker must modify a nop instruction after a bl function
call to restore the TOC pointer in r2 from 24(r1) when an external symbol
that may use the TOC may be called, as in
<xref linkend="dbdoclet.50655240_88555" />. Object files must contain a
nop slot after a bl instruction to an external symbol.</para>
</section>
<section>
<title>Reference Optimization</title>
<para>References to the GOT may be optimized by rewriting indirect
reference code to replace the reference by an address computation. This
transformation is only performed by the linker when the symbol is known
to be local to the module.</para>
</section>
<section>
<title>Displacement Optimization for TOC Pointer Relative
Accesses</title>
<para>Assemblers and linkers
<emphasis>may</emphasis> optimize TOC reference code that consists of two
instructions with equivalent code when offset@ha is 0.</para>
<para>TOC reference code:</para>
<programlisting>addis rt, r2, offset@ha
lwz rt, offset@l(rt)</programlisting>
<para>Equivalent code:</para>
<programlisting>NOP
lwz rt, offset(r2)</programlisting>
<para>Compilers and programmers
<emphasis>must</emphasis> ensure that r2 is live at the actual data access
point associated with extended displacement addressing.</para>
<section xml:id="dbdoclet.50655241_19147">
<title>TOC Pointer Usage</title>
<para>To enable linker-based optimizations when global data is accessed,
the TOC pointer needs to be available for dereference at the point of all
uses of values derived from the TOC pointer in conjunction with the @l
operator. This property is used by the linker to optimize TOC pointer
accesses. In addition, all reaching definitions for a TOC-pointer-derived
access must compute the same definition.</para>
<para>In some implementations, non-ABI-compliant code may be processed by
providing additional linker options; for example, linker options
disabling linker optimization. However, this behavior in support of
non-ABI-compliant code is not guaranteed to be portable and supported in
all systems.</para>
<para>&#160;</para>
<bridgehead>Compliant example</bridgehead>
<programlisting> addis r4, r2, mysym@toc@ha
b target
...
addis r4, r2, mysym@toc@ha
target:
addi r4, r4, mysym@toc@l
...</programlisting>
<para>&#160;</para>
<bridgehead>Non-compliant example</bridgehead>
<programlisting> li r4, 0 ; #d1
b target
...
addis r4, r2, mysym@toc@ha ; #d2
target:
addi r4, r4, mysym@toc@l ; incompatible definitions #d1 and #d2 reach this
...</programlisting>
</section>
<section>
<title>Table Jump Sequences</title>
<para>Some linkers may rewrite jump table sequences, as described in
<xref linkend="dbdoclet.50655240_47036" />. For example, linkers may
rewrite address references created using GOT-indirect loads and bl+4
sequences to use TOC-relative address computation.</para>
</section>
</section>
<section>
<title>Fusion</title>
<para>Code generation in compilers, linkers, and by programmers should
use a destructive sequence of two sequential instructions consisting of
first an addis followed by a second instruction using a D form
instruction to create or load from a 32-bit offset from a register to
enable hardware fusion whenever possible:</para>
<programlisting>addis r4, r3, upper
&lt;lbz,lhz,lwz,ld&gt; r4, lower(r4)
addis r4, r3, upper
addi r4, r4, lower</programlisting>
<para>It is encouraged that assemblers provide pseudo-ops to facilitate
such code generation with a single assembler mnemonic.</para>
</section>
<section>
<title>Thread-Local Linker Optimizations</title>
<para>Additional code rewriting is performed by the linker in conjunction
with the use of thread-local storage described in
<xref linkend="dbdoclet.50655241_61284" />.</para>
</section>
</section>
<section xml:id="dbdoclet.50655241_90241">
<title>Thread Local Storage ABI</title>
<para>The
<citetitle>ELF Handling for Thread-Local Storage</citetitle> document is the
authoritative TLS ABI specification that defines the context in which
information in the TLS section of this Power Architecture 64-bit ELF V2 ABI
must be viewed. For information about how to access this document, see
<xref linkend="dbdoclet.50655239___RefHeading___Toc377640569" />. To
maintain congruence with that document, in this section the term module
refers to an executable or shared object since both are treated
similarly.</para>
<section>
<title>TLS Background</title>
<para>Most C/C++ implementations support (as an extension to earlier
versions of the language) the keyword __thread to be used as a
storage-class specifier in variable declarations and definitions of data
objects with thread storage duration. (The 2011 ISO C Standard uses
_Thread_local as the keyword, while the 2011 ISO C++ Standard uses
thread_local.) A variable declared in this manner is automatically
allocated local to each thread. Its lifetime is defined to be the entire
execution of the thread. Any initialization value is assigned once before
thread startup.</para>
</section>
<section xml:id="dbdoclet.50655241_50444">
<title>TLS Runtime Handling</title>
<para>A thread-local variable is completely identified by the module in
which it is defined, along with the offset of the variable relative to
the start of the TLS block for the module. A module is referenced by its
index (an integer starting with 1, which is assigned by the run-time
environment) into the dynamic thread vector (DTV). The offset of the
variable is kept in the st_value field of the TLS variables symbol table
entry.</para>
<para>The TLS data structures follow variant I of the ELF TLS ABI. For
the 64-bit PowerPC Architecture, the specific organization of the data
structures is as follows.</para>
<para>The thread control block (TCB) consists of the DTV, which is an
8-byte pointer. An extended TCB may have additional
implementation-specific fields; these fields are located
<emphasis>before</emphasis> the DTV pointer because the addresses are
computed as negative offsets from the TCB address. The fields must never
be rearranged for any reason.</para>
<para>The current glibc extended TCB is:</para>
<programlisting>typedef struct {
/* Reservation for HWCAP data. */
unsigned int hwcap2;
unsigned int hwcap; /* not used in LE ABI */
/* Indicate if HTM capable (ISA 2.07). */
int tm_capable;
int tm_pad;
/* Reservation for dynamic system optimizer ABI. */
uintptr_t dso_slot2;
uintptr_t dso_slot1;
/* Reservation for tar register (ISA 2.07). */
uintptr_t tar_save;
/* GCC split stack support. */
void *__private_ss;
/* Reservation for the event-based branching ABI. */
uintptr_t ebb_handler;
uintptr_t ebb_ctx_pointer;
uintptr_t ebb_reserved1;
uintptr_t ebb_reserved2;
uintptr_t pointer_guard;
/* Reservation for stack guard */
uintptr_t stack_guard;
/* DTV pointer */
dtv_t *dtv;
} tcbhead_t;</programlisting>
<para>Modules that will not be unloaded will be present at startup time;
the TLS blocks for these are created consecutively and immediately follow
the TCB. The offset of the TLS block of an initially available module
from the TCB remains fixed after program start.</para>
<para>The tlsoffset(m) values for a module with index m, where m ranges 1
- M, M being the total number of modules, are computed as follows:</para>
<programlisting>tlsoffset(1) = round(16, align(1))
tlsoffset(m + 1) = round(tlsoffset(m) + tlssize(m), align(m + 1))</programlisting>
<itemizedlist>
<listitem>
<para>The function round( ) returns its first argument rounded up to
the next multiple of its second argument:</para>
</listitem>
</itemizedlist>
<programlisting>round(x, y) = y × ceiling(x / y)</programlisting>
<itemizedlist>
<listitem>
<para>The function ceiling( ) returns the smallest integer greater
than or equal to its argument, where n is an integer satisfying: n -
1 &lt; x ≤ n:</para>
</listitem>
</itemizedlist>
<programlisting>ceiling(x) = n</programlisting>
<para>In the case of dynamic shared objects (DSO), TLS blocks are
allocated on an as-needed basis, with the details of allocation
abstracted away by the __tls_get_addr( ) function, which is used to
retrieve the address of any TLS variable.</para>
<para>The prototype for the __tls_get_addr( ) function, is defined as
follows.</para>
<programlisting>typedef struct
{
unsigned long int ti_module;
unsigned long int ti_offset;
} tls_index;
extern void *__tls_get_addr (tls_index *ti);</programlisting>
<para>The thread pointer (TP) is held in r13 and is used to access the
TCB. The TP is initialized to point 0x7000 bytes past the end of the TCB.
The TP offset allows for efficient addressing of the TCB and up to 4 KB -
8 B of other thread library information (placed before the TCB).</para>
<para>
<xref linkend="dbdoclet.50655241_11666" /> shows the region of memory
before and after the TCB that can be efficiently addressed by the
TP.</para>
<figure pgwide="1" xml:id="dbdoclet.50655241_11666">
<title>Thread Pointer Addressable Memory</title>
<mediaobject>
<imageobject>
<imagedata fileref="figures/fig3-1.png" format="PNG"
scalefit="1" width="100%" />
</imageobject>
</mediaobject>
</figure>
<para>Each DTV pointer points 0x8000 bytes past the start of each TLS
block. (For implementation reasons, the actual value stored in the DTV
may point to the start of a TLS block. However, values returned by
accessor functions will be offset by 0x8000 bytes.) This offset allows
the first 64 KB of each block to be addressed from a DTV pointer using
fewer machine instructions.</para>
<para> </para>
<figure pgwide="1" xml:id="dbdoclet.50655241_25002">
<title>TLS Block Diagram</title>
<mediaobject>
<imageobject>
<imagedata fileref="figures/fig3-2.png" format="PNG"
scalefit="1" width="100%" />
</imageobject>
</mediaobject>
</figure>
<para>TLS[m] denotes the TLS block for the module with index m. DTV[m]
denotes the DTV pointer for the module with index m.</para>
</section>
<section>
<title>TLS Access Models</title>
<para>TLS data access is categorized into the following models:</para>
<itemizedlist>
<listitem>
<para>General Dynamic TLS Model</para>
</listitem>
<listitem>
<para>Local Dynamic TLS Model</para>
</listitem>
<listitem>
<para>Initial Exec TLS Model</para>
</listitem>
<listitem>
<para>Local Exec TLS Model</para>
</listitem>
</itemizedlist>
<para>Examples for each access model are provided in the following TLS
Model subsections.</para>
<section>
<title>General Dynamic TLS Model</title>
<note>
<para>This specification provides examples based on the medium
code model, which is the default for the ELF V2 ABI.</para>
</note>
<para>Given the following code fragment, to determine the address of a
thread-local variable x, the __tls_get_addr( ) function is called with one
parameter. That parameter is a pointer to a data object of type
tls_index.</para>
<programlisting>extern __thread unsigned int x;
&amp;x;</programlisting>
<table frame="all" pgwide="1">
<title>General Dynamic Initial Relocations</title>
<tgroup cols="3">
<colspec colname="c1" colwidth="33*" />
<colspec colname="c2" colwidth="33*" />
<colspec colname="c3" colwidth="33*" />
<thead>
<row>
<entry>
<para>
<emphasis role="bold">Code Sequence</emphasis>
</para>
</entry>
<entry>
<para>
<emphasis role="bold">Relocation</emphasis>
</para>
</entry>
<entry>
<para>
<emphasis role="bold">Symbol</emphasis>
</para>
</entry>
</row>
</thead>
<tbody>
<row>
<entry>
<para>addis r3, r2, x@got@tlsgd@ha</para>
</entry>
<entry>
<para>R_PPC64_GOT_TLSGD16_HA</para>
</entry>
<entry>
<para>x</para>
</entry>
</row>
<row>
<entry>
<para>addi r3, r3, x@got@tlsgd@l</para>
</entry>
<entry>
<para>R_PPC64_GOT_TLSGD16_LO</para>
</entry>
<entry>
<para>x</para>
</entry>
</row>
<row>
<entry morerows="1">
<para>bl __tls_get_addr(x@tlsgd)</para>
</entry>
<entry>
<para>R_PPC64_TLSGD</para>
</entry>
<entry>
<para>x</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_REL24</para>
</entry>
<entry>
<para>__tls_get_addr</para>
</entry>
</row>
<row>
<entry>
<para>nop</para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
</row>
</tbody>
</tgroup>
</table>
<para> </para>
<table frame="all" pgwide="1">
<title>General Dynamic GOT Entry Relocations</title>
<tgroup cols="3">
<colspec colname="c1" colwidth="33*" />
<colspec colname="c2" colwidth="33*" />
<colspec colname="c3" colwidth="33*" />
<thead>
<row>
<entry>
<para>
<emphasis role="bold">Code Sequence</emphasis>
</para>
</entry>
<entry>
<para>
<emphasis role="bold">Relocation</emphasis>
</para>
</entry>
<entry>
<para>
<emphasis role="bold">Symbol</emphasis>
</para>
</entry>
</row>
</thead>
<tbody>
<row>
<entry>
<para>GOT[n]</para>
</entry>
<entry>
<para>R_PPC64_DTPMOD64</para>
</entry>
<entry>
<para>x</para>
</entry>
</row>
<row>
<entry>
<para>GOT[n+1]</para>
</entry>
<entry>
<para>R_PPC64_DTPREL64</para>
</entry>
<entry>
<para>x</para>
</entry>
</row>
</tbody>
</tgroup>
</table>
<para>The relocation specifier @got@tlsgd causes the link editor to
create a data object of type tls_index in the GOT. The address of this
data object is loaded into the first argument register with the addis and
addi instruction, and a standard function call is made. Notice that the
bl instruction has two relocations: the R_PPC64_TLSGD tying it to the
argument setup instructions and the R_PPC64_REL24 specifying the call
destination.</para>
</section>
<section>
<title>Local Dynamic TLS Model</title>
<para>For the Local Dynamic TLS Model, three different relocation
sequences may be used, depending on the size of the thread storage block
offset to the variable. For the following code sequence, a different
relocation sequence is used for each variable.</para>
<programlisting>static __thread unsigned int x1;
static __thread unsigned int x2;
static __thread unsigned int x3;
&amp;x1;
&amp;x2;
&amp;x3;</programlisting>
<table frame="all" pgwide="1" xml:id="dbdoclet.50655241_45768">
<title>Local Dynamic Initial Relocations</title>
<tgroup cols="3">
<colspec colname="c1" colwidth="33*" />
<colspec colname="c2" colwidth="33*" />
<colspec colname="c3" colwidth="33*" />
<thead>
<row>
<entry>
<para>
<emphasis role="bold">Code Sequence</emphasis>
</para>
</entry>
<entry>
<para>
<emphasis role="bold">Relocation</emphasis>
</para>
</entry>
<entry>
<para>
<emphasis role="bold">Symbol</emphasis>
</para>
</entry>
</row>
</thead>
<tbody>
<row>
<entry>
<para>addis r3, r2, x1@got@tlsld@ha</para>
</entry>
<entry>
<para>R_PPC64_GOT_TLSLD16_HA</para>
</entry>
<entry>
<para>x1</para>
</entry>
</row>
<row>
<entry>
<para>addi r3, r3, x1@got@tlsld@l</para>
</entry>
<entry>
<para>R_PPC64_GOT_TLSLD16_LO</para>
</entry>
<entry>
<para>x1</para>
</entry>
</row>
<row>
<entry>
<para>bl __tls_get_addr(x1@tlsld)</para>
</entry>
<entry>
<para>R_PPC64_TLSLD</para>
</entry>
<entry>
<para>x1</para>
</entry>
</row>
<row>
<entry>
<para> </para>
</entry>
<entry>
<para>R_PPC64_REL24</para>
</entry>
<entry>
<para>__tls_get_addr</para>
</entry>
</row>
<row>
<entry>
<para>nop</para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
</row>
<row>
<entry>
<para>...</para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
</row>
<row>
<entry>
<para>addi r9, r3, x1@dtprel</para>
</entry>
<entry>
<para>R_PPC64_DTPREL16</para>
</entry>
<entry>
<para>x1</para>
</entry>
</row>
<row>
<entry>
<para>...</para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
</row>
<row>
<entry>
<para>addis r9, r3, x2@dtprel@ha</para>
</entry>
<entry>
<para>R_PPC64_DTPREL16_HA</para>
</entry>
<entry>
<para>x2</para>
</entry>
</row>
<row>
<entry>
<para>addi r9, r9, x2@dtprel@l</para>
</entry>
<entry>
<para>R_PPC64_DTPREL16_LO</para>
</entry>
<entry>
<para>x2</para>
</entry>
</row>
<row>
<entry>
<para>...</para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
</row>
<row>
<entry>
<para>addis r9, r2, x3@got@dtprel@ha</para>
</entry>
<entry>
<para>R_PPC64_GOT_DTPREL16_HA</para>
</entry>
<entry>
<para>x3</para>
</entry>
</row>
<row>
<entry>
<para>ld r9, x3@got@dtprel@l(r9)</para>
</entry>
<entry>
<para>R_PPC64_GOT_DTPREL16_LO_DS</para>
</entry>
<entry>
<para>x3</para>
</entry>
</row>
<row>
<entry>
<para>add r9, r9, r3</para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
</row>
</tbody>
</tgroup>
</table>
<para> </para>
<table frame="all" pgwide="1">
<title>Local Dynamic GOT Entry Relocations</title>
<tgroup cols="3">
<colspec colname="c1" colwidth="33*" />
<colspec colname="c2" colwidth="33*" />
<colspec colname="c3" colwidth="33*" />
<thead>
<row>
<entry>
<para>
<emphasis role="bold">Code Sequence</emphasis>
</para>
</entry>
<entry>
<para>
<emphasis role="bold">Relocation</emphasis>
</para>
</entry>
<entry>
<para>
<emphasis role="bold">Symbol</emphasis>
</para>
</entry>
</row>
</thead>
<tbody>
<row>
<entry>
<para>GOT[n]</para>
</entry>
<entry>
<para>R_PPC64_DTPMOD64</para>
</entry>
<entry>
<para>x1</para>
</entry>
</row>
<row>
<entry>
<para>GOT[n+1]</para>
</entry>
<entry>
<para>0</para>
</entry>
<entry>
<para> </para>
</entry>
</row>
<row>
<entry>
<para>GOT[m]</para>
</entry>
<entry>
<para>R_PPC64_DTPREL64</para>
</entry>
<entry>
<para>x3</para>
</entry>
</row>
</tbody>
</tgroup>
</table>
<para>The relocation specifier @got@tlsld in the first instruction causes
the link editor to generate a tls_index data object in the GOT with a
fixed 0 offset. The following code assumes that x1 is in the first 64 KB
of the thread storage block. The x2 symbol is not within the first 64 KB
but is within the first 2 GB, and x3 is outside the 2 GB area. To load
the values of x1, x2, and x3 instead of their addresses, replace the
latter part of
<xref linkend="dbdoclet.50655241_45768" /> with the following code
sequence.</para>
<para> </para>
<table frame="all" pgwide="1" xml:id="dbdoclet.50655241_48794">
<title>Local Dynamic Relocations with Values Loaded</title>
<tgroup cols="3">
<colspec colname="c1" colwidth="33*" />
<colspec colname="c2" colwidth="33*" />
<colspec colname="c3" colwidth="33*" />
<thead>
<row>
<entry>
<para>
<emphasis role="bold">Code Sequence</emphasis>
</para>
</entry>
<entry>
<para>
<emphasis role="bold">Relocation</emphasis>
</para>
</entry>
<entry>
<para>
<emphasis role="bold">Symbol</emphasis>
</para>
</entry>
</row>
</thead>
<tbody>
<row>
<entry>
<para>...</para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
</row>
<row>
<entry>
<para>lwz r0, x1@dtprel(r3)</para>
</entry>
<entry>
<para>R_PPC64_DTPREL16</para>
</entry>
<entry>
<para>x1</para>
</entry>
</row>
<row>
<entry>
<para>...</para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
</row>
<row>
<entry>
<para>addis r9, r3, x2@dtprel@ha</para>
</entry>
<entry>
<para>R_PPC64_DTPREL16_HA</para>
</entry>
<entry>
<para>x2</para>
</entry>
</row>
<row>
<entry>
<para>lwz r0, x2@dtprel@l(r9)</para>
</entry>
<entry>
<para>R_PPC64_DTPREL16_LO</para>
</entry>
<entry>
<para>x2</para>
</entry>
</row>
<row>
<entry>
<para>...</para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
</row>
<row>
<entry>
<para>addis r9, r2, x3@got@dtprel@ha</para>
</entry>
<entry>
<para>R_PPC64_GOT_DTPREL16_HA</para>
</entry>
<entry>
<para>x3</para>
</entry>
</row>
<row>
<entry>
<para>ld r9, x3@got@dtprel@l(r9)</para>
</entry>
<entry>
<para>R_PPC64_GOT_DTPREL16_LO_DS</para>
</entry>
<entry>
<para>x3</para>
</entry>
</row>
<row>
<entry>
<para>lwzx r0, r3, r9</para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
</row>
</tbody>
</tgroup>
</table>
</section>
<section>
<title>Initial Exec TLS Model</title>
<para>Given the following code fragment, the relocation sequence in
<xref linkend="dbdoclet.50655241_17435" /> is used for the Initial Exec
TLS Model:</para>
<programlisting>extern __thread unsigned int x;
&amp;x;</programlisting>
<table frame="all" pgwide="1" xml:id="dbdoclet.50655241_17435">
<title>Initial Exec Initial Relocations</title>
<tgroup cols="3">
<colspec colname="c1" colwidth="33*" />
<colspec colname="c2" colwidth="33*" />
<colspec colname="c3" colwidth="33*" />
<thead>
<row>
<entry>
<para>
<emphasis role="bold">Code Sequence</emphasis>
</para>
</entry>
<entry>
<para>
<emphasis role="bold">Relocation</emphasis>
</para>
</entry>
<entry>
<para>
<emphasis role="bold">Symbol</emphasis>
</para>
</entry>
</row>
</thead>
<tbody>
<row>
<entry>
<para>addis r9, r2, x@got@tprel@ha</para>
</entry>
<entry>
<para>R_PPC64_GOT_TPREL16_HA</para>
</entry>
<entry>
<para>x</para>
</entry>
</row>
<row>
<entry>
<para>ld r9, x@got@tprel@l(r9)</para>
</entry>
<entry>
<para>R_PPC64_GOT_TPREL16_LO_DS</para>
</entry>
<entry>
<para>x</para>
</entry>
</row>
<row>
<entry>
<para>add r9, r9, x@tls</para>
</entry>
<entry>
<para>R_PPC64_TLS</para>
</entry>
<entry>
<para>x</para>
</entry>
</row>
</tbody>
</tgroup>
</table>
<para> </para>
<table frame="all" pgwide="1">
<title>Initial Exec GOT Entry Relocations</title>
<tgroup cols="3">
<colspec colname="c1" colwidth="33*" />
<colspec colname="c2" colwidth="33*" />
<colspec colname="c3" colwidth="33*" />
<thead>
<row>
<entry>
<para>
<emphasis role="bold">Code Sequence</emphasis>
</para>
</entry>
<entry>
<para>
<emphasis role="bold">Relocation</emphasis>
</para>
</entry>
<entry>
<para>
<emphasis role="bold">Symbol</emphasis>
</para>
</entry>
</row>
</thead>
<tbody>
<row>
<entry>
<para>GOT[n]</para>
</entry>
<entry>
<para>R_PPC64_TPREL64</para>
</entry>
<entry>
<para>x</para>
</entry>
</row>
</tbody>
</tgroup>
</table>
<para>The relocation specifier @got@tprel in the first instruction causes
the link editor to generate a GOT entry with a relocation that the
dynamic linker will replace with the offset for x relative to the thread
pointer. The relocation specifier x@tls tells the assembler to use an r13
form of the instruction. That is, add r9,r9,r13 in this case, and tag the
instruction with a relocation that indicates it belongs to a TLS
sequence. This relocation specifier can be used later by the link editor
when optimizing TLS code.</para>
<para>To read the contents of the variable instead of calculating its
address, the add r9, r9, x@tls instruction might be replaced with lwzx
r0, r9, x@tls.</para>
</section>
<section>
<title>Local Exec TLS Model</title>
<para>Given the following code fragment, three different relocation
sequences may be used, depending on the size of the offset to the
variable. The sequence in
<xref linkend="dbdoclet.50655241_45954" /> handles offsets within 60 KB
relative to the end of the TCB (where r13 points 28 KB past the end of
the TCB, which is immediately before the first TLS block). The sequence
in
<xref linkend="dbdoclet.50655241_47421" /> handles offsets past 60 KB and
less than 2 GB + 28 KB relative to the end of the TCB. The third sequence
is identical to the Initial Exec sequence shown in
<xref linkend="dbdoclet.50655241_17435" />.</para>
<programlisting>static __thread unsigned int x;
&amp;x;</programlisting>
<para><xref linkend="dbdoclet.50655241_51121" /> illustrates which sequence is
used.</para>
<para> </para>
<figure pgwide="1" xml:id="dbdoclet.50655241_51121">
<title>Local Exec TLS Model Sequences</title>
<mediaobject>
<imageobject>
<imagedata fileref="figures/fig3-3.png" format="PNG"
scalefit="1" width="100%" />
</imageobject>
</mediaobject>
</figure>
<table frame="all" pgwide="1" xml:id="dbdoclet.50655241_45954">
<title>Local Exec Initial Relocations (Sequence 1)</title>
<tgroup cols="3">
<colspec colname="c1" colwidth="33*" />
<colspec colname="c2" colwidth="33*" />
<colspec colname="c3" colwidth="33*" />
<thead>
<row>
<entry>
<para>
<emphasis role="bold">Code Sequence</emphasis>
</para>
</entry>
<entry>
<para>
<emphasis role="bold">Relocation</emphasis>
</para>
</entry>
<entry>
<para>
<emphasis role="bold">Symbol</emphasis>
</para>
</entry>
</row>
</thead>
<tbody>
<row>
<entry>
<para>addi r9, r13, x1@tprel</para>
</entry>
<entry>
<para>R_PPC_TPREL16</para>
</entry>
<entry>
<para>x</para>
</entry>
</row>
</tbody>
</tgroup>
</table>
<para> </para>
<table frame="all" pgwide="1" xml:id="dbdoclet.50655241_47421">
<title>Local Exec Initial Relocations (Sequence 2)</title>
<tgroup cols="3">
<colspec colname="c1" colwidth="33*" />
<colspec colname="c2" colwidth="33*" />
<colspec colname="c3" colwidth="33*" />
<thead>
<row>
<entry>
<para>
<emphasis role="bold">Code Sequence</emphasis>
</para>
</entry>
<entry>
<para>
<emphasis role="bold">Relocation</emphasis>
</para>
</entry>
<entry>
<para>
<emphasis role="bold">Symbol</emphasis>
</para>
</entry>
</row>
</thead>
<tbody>
<row>
<entry>
<para>addis r9, r13, x2@tprel@ha</para>
</entry>
<entry>
<para>R_PPC64_TPREL16_HA</para>
</entry>
<entry>
<para>x</para>
</entry>
</row>
<row>
<entry>
<para>addi r9, r9, x2@tprel@l</para>
</entry>
<entry>
<para>R_PPC64_TPREL16_LO</para>
</entry>
<entry>
<para>x</para>
</entry>
</row>
</tbody>
</tgroup>
</table>
</section>
</section>
<section xml:id="dbdoclet.50655241_61284">
<title>TLS Link Editor Optimizations</title>
<para>In some cases, the link editor may be able to optimize TLS code
sequences, provided the compiler emits code sequences as
described.</para>
<para>The following TLS link editor transformations are provided as
optimizations to convert between specific TLS access models:</para>
<itemizedlist>
<listitem>
<para>General Dynamic to Initial Exec</para>
</listitem>
<listitem>
<para>General Dynamic to Local Exec</para>
</listitem>
<listitem>
<para>Local Dynamic to Local Exec</para>
</listitem>
<listitem>
<para>Initial Exec to Local Exec</para>
</listitem>
</itemizedlist>
<section>
<title>General Dynamic to Initial Exec</title>
<para> </para>
<table frame="all" pgwide="1">
<title>General-Dynamic-to-Initial-Exec Initial Relocations</title>
<tgroup cols="3">
<colspec colname="c1" colwidth="33*" />
<colspec colname="c2" colwidth="33*" />
<colspec colname="c3" colwidth="33*" />
<thead>
<row>
<entry>
<para>
<emphasis role="bold">Code Sequence</emphasis>
</para>
</entry>
<entry>
<para>
<emphasis role="bold">Relocation</emphasis>
</para>
</entry>
<entry>
<para>
<emphasis role="bold">Symbol</emphasis>
</para>
</entry>
</row>
</thead>
<tbody>
<row>
<entry>
<para>addis r3, r2, x@got@tlsgd@ha</para>
</entry>
<entry>
<para>R_PPC64_GOT_TLSGD16_HA</para>
</entry>
<entry>
<para>x</para>
</entry>
</row>
<row>
<entry>
<para>addi r3, r3, x@got@tlsgd@l</para>
</entry>
<entry>
<para>R_PPC64_GOT_TLSGD16_LO</para>
</entry>
<entry>
<para>x</para>
</entry>
</row>
<row>
<entry morerows="1">
<para>bl __tls_get_addr(x@tlsgd)</para>
</entry>
<entry>
<para>R_PPC64_TLSGD</para>
</entry>
<entry>
<para>x</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_REL24</para>
</entry>
<entry>
<para>__tls_get_addr</para>
</entry>
</row>
<row>
<entry>
<para>nop</para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
</row>
</tbody>
</tgroup>
</table>
<para> </para>
<table frame="all" pgwide="1">
<title>General-Dynamic-to-Initial-Exec GOT Entry Relocations</title>
<tgroup cols="3">
<colspec colname="c1" colwidth="33*" />
<colspec colname="c2" colwidth="33*" />
<colspec colname="c3" colwidth="33*" />
<thead>
<row>
<entry>
<para>
<emphasis role="bold">Code Sequence</emphasis>
</para>
</entry>
<entry>
<para>
<emphasis role="bold">Relocation</emphasis>
</para>
</entry>
<entry>
<para>
<emphasis role="bold">Symbol</emphasis>
</para>
</entry>
</row>
</thead>
<tbody>
<row>
<entry>
<para>GOT[n]</para>
</entry>
<entry>
<para>R_PPC64_DTPMOD64</para>
</entry>
<entry>
<para>x</para>
</entry>
</row>
<row>
<entry>
<para>GOT[n+1]</para>
</entry>
<entry>
<para>R_PPC64_DTPREL64</para>
</entry>
<entry>
<para>x</para>
</entry>
</row>
</tbody>
</tgroup>
</table>
<para>The preceding code and global offset table entries are replaced by
the following code and global offset table entries.</para>
<para> </para>
<table frame="all" pgwide="1">
<title>General-Dynamic-to-Initial-Exec Replacement Initial
Relocations</title>
<tgroup cols="3">
<colspec colname="c1" colwidth="33*" />
<colspec colname="c2" colwidth="33*" />
<colspec colname="c3" colwidth="33*" />
<thead>
<row>
<entry>
<para>
<emphasis role="bold">Code Sequence</emphasis>
</para>
</entry>
<entry>
<para>
<emphasis role="bold">Relocation</emphasis>
</para>
</entry>
<entry>
<para>
<emphasis role="bold">Symbol</emphasis>
</para>
</entry>
</row>
</thead>
<tbody>
<row>
<entry>
<para>addis r3, r2, x@got@tprel@ha</para>
</entry>
<entry>
<para>R_PPC64_GOT_TPREL16_HA</para>
</entry>
<entry>
<para>x</para>
</entry>
</row>
<row>
<entry>
<para>ld r3, x@got@tprel@l(r3)</para>
</entry>
<entry>
<para>R_PPC64_GOT_TPREL16_LO_DS</para>
</entry>
<entry>
<para>x</para>
</entry>
</row>
<row>
<entry>
<para>nop</para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
</row>
<row>
<entry>
<para>add r3, r3, r13</para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
</row>
</tbody>
</tgroup>
</table>
<para> </para>
<table frame="all" pgwide="1">
<title>General-Dynamic-to-Initial-Exec Replacement GOT Entry
Relocations</title>
<tgroup cols="3">
<colspec colname="c1" colwidth="33*" />
<colspec colname="c2" colwidth="33*" />
<colspec colname="c3" colwidth="33*" />
<thead>
<row>
<entry>
<para>
<emphasis role="bold">Code Sequence</emphasis>
</para>
</entry>
<entry>
<para>
<emphasis role="bold">Relocation</emphasis>
</para>
</entry>
<entry>
<para>
<emphasis role="bold">Symbol</emphasis>
</para>
</entry>
</row>
</thead>
<tbody>
<row>
<entry>
<para>GOT[n]</para>
</entry>
<entry>
<para>R_PPC64_TPREL64</para>
</entry>
<entry>
<para>x</para>
</entry>
</row>
</tbody>
</tgroup>
</table>
</section>
<section>
<title>General Dynamic to Local Exec</title>
<para> </para>
<table frame="all" pgwide="1">
<title>General-Dynamic-to-Local-Exec Initial Relocations</title>
<tgroup cols="3">
<colspec colname="c1" colwidth="33*" />
<colspec colname="c2" colwidth="33*" />
<colspec colname="c3" colwidth="33*" />
<thead>
<row>
<entry>
<para>
<emphasis role="bold">Code Sequence</emphasis>
</para>
</entry>
<entry>
<para>
<emphasis role="bold">Relocation</emphasis>
</para>
</entry>
<entry>
<para>
<emphasis role="bold">Symbol</emphasis>
</para>
</entry>
</row>
</thead>
<tbody>
<row>
<entry>
<para>addis r3, r2, x@got@tlsgd@ha</para>
</entry>
<entry>
<para>R_PPC64_GOT_TLSGD16_HA</para>
</entry>
<entry>
<para>x</para>
</entry>
</row>
<row>
<entry>
<para>addi r3, r3, x@got@tlsgd@l</para>
</entry>
<entry>
<para>R_PPC64_GOT_TLSGD16_LO</para>
</entry>
<entry>
<para>x</para>
</entry>
</row>
<row>
<entry morerows="1">
<para>bl __tls_get_addr(x@tlsgd)</para>
</entry>
<entry>
<para>R_PPC64_TLSGD</para>
</entry>
<entry>
<para>x</para>
</entry>
</row>
<row>
<entry>
<para>R_PPC64_REL24</para>
</entry>
<entry>
<para>__tls_get_addr</para>
</entry>
</row>
<row>
<entry>
<para>nop</para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
</row>
</tbody>
</tgroup>
</table>
<para> </para>
<table frame="all" pgwide="1" xml:id="dbdoclet.50655241_16273">
<title>General-Dynamic-to-Local-Exec GOT Entry Relocations</title>
<tgroup cols="3">
<colspec colname="c1" colwidth="33*" />
<colspec colname="c2" colwidth="33*" />
<colspec colname="c3" colwidth="33*" />
<thead>
<row>
<entry>
<para>
<emphasis role="bold">Code Sequence</emphasis>
</para>
</entry>
<entry>
<para>
<emphasis role="bold">Relocation</emphasis>
</para>
</entry>
<entry>
<para>
<emphasis role="bold">Symbol</emphasis>
</para>
</entry>
</row>
</thead>
<tbody>
<row>
<entry>
<para>GOT[n]</para>
</entry>
<entry>
<para>R_PPC64_DTPMOD64</para>
</entry>
<entry>
<para>x</para>
</entry>
</row>
<row>
<entry>
<para>GOT[n+1]</para>
</entry>
<entry>
<para>R_PPC64_DTPREL64</para>
</entry>
<entry>
<para>x</para>
</entry>
</row>
</tbody>
</tgroup>
</table>
<para>The preceding code and global offset table entries are replaced by
the following code, which makes no reference to GOT entries. The GOT
entries in
<xref linkend="dbdoclet.50655241_16273" /> can be removed from the GOT by
the linker when performing this code transformation.<footnote xml:id="pgfId-1134055">
<para>To further optimize the code in
<xref linkend="dbdoclet.50655241_16273" />, a linker may reschedule the
sequence to exploit fusion by generating a sequence that may be fused
by Power processors:</para>
<programlisting>nop
addis r3, r13, x@tprel@ha
addi r3, r3, x@tprel@l
nop</programlisting>
</footnote></para>
<para> </para>
<table frame="all" pgwide="1">
<title>General-Dynamic-to-Local-Exec Replacement Initial
Relocations</title>
<tgroup cols="3">
<colspec colname="c1" colwidth="33*" />
<colspec colname="c2" colwidth="33*" />
<colspec colname="c3" colwidth="33*" />
<thead>
<row>
<entry>
<para>
<emphasis role="bold">Code Sequence</emphasis>
</para>
</entry>
<entry>
<para>
<emphasis role="bold">Relocation</emphasis>
</para>
</entry>
<entry>
<para>
<emphasis role="bold">Symbol</emphasis>
</para>
</entry>
</row>
</thead>
<tbody>
<row>
<entry>
<para>nop</para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
</row>
<row>
<entry>
<para>addis r3, r13, x@tprel@ha</para>
</entry>
<entry>
<para>R_PPC64_TPREL16_HA</para>
</entry>
<entry>
<para>x</para>
</entry>
</row>
<row>
<entry>
<para>nop</para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
</row>
<row>
<entry>
<para>addi r3, r3, x@tprel@l</para>
</entry>
<entry>
<para>R_PPC64_TPREL16_LO</para>
</entry>
<entry>
<para>x</para>
</entry>
</row>
</tbody>
</tgroup>
</table>
</section>
<section>
<title>Local Dynamic to Local Exec</title>
<para>Under this TLS linker optimization, the function call is replaced
with an equivalent code sequence. However, as shown in the following code
examples, the dtprel sequences are left unchanged.</para>
<para> </para>
<table frame="all" pgwide="1" xml:id="dbdoclet.50655241_56118">
<title>Local-Dynamic-to-Local-Exec Initial Relocations</title>
<tgroup cols="3">
<colspec colname="c1" colwidth="33*" />
<colspec colname="c2" colwidth="33*" />
<colspec colname="c3" colwidth="33*" />
<thead>
<row>
<entry>
<para>
<emphasis role="bold">Code Sequence</emphasis>
</para>
</entry>
<entry>
<para>
<emphasis role="bold">Relocation</emphasis>
</para>
</entry>
<entry>
<para>
<emphasis role="bold">Symbol</emphasis>
</para>
</entry>
</row>
</thead>
<tbody>
<row>
<entry>
<para>addis r3, r2, x1@got@tlsld@ha</para>
</entry>
<entry>
<para>R_PPC64_GOT_TLSLD16_HA</para>
</entry>
<entry>
<para>x1</para>
</entry>
</row>
<row>
<entry>
<para>addi r3, r3, x1@got@tlsld@l</para>
</entry>
<entry>
<para>R_PPC64_GOT_TLSLD16_LO</para>
</entry>
<entry>
<para>x1</para>
</entry>
</row>
<row>
<entry>
<para>bl __tls_get_addr(x1@tlsld)</para>
</entry>
<entry>
<para>R_PPC64_TLSLD</para>
</entry>
<entry>
<para>x1</para>
</entry>
</row>
<row>
<entry>
<para> </para>
</entry>
<entry>
<para>R_PPC64_REL24</para>
</entry>
<entry>
<para>__tls_get_addr</para>
</entry>
</row>
<row>
<entry>
<para>nop</para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
</row>
<row>
<entry>
<para>...</para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
</row>
<row>
<entry>
<para>addi r9, r3, x1@dtprel</para>
</entry>
<entry>
<para>R_PPC64_DTPREL16</para>
</entry>
<entry>
<para>x1</para>
</entry>
</row>
<row>
<entry>
<para>...</para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
</row>
<row>
<entry>
<para>addis r9, r3, x2@dtprel@ha</para>
</entry>
<entry>
<para>R_PPC64_DTPREL16_HA</para>
</entry>
<entry>
<para>x2</para>
</entry>
</row>
<row>
<entry>
<para>addi r9, r9, x2@dtprel@l</para>
</entry>
<entry>
<para>R_PPC64_DTPREL16_LO</para>
</entry>
<entry>
<para>x2</para>
</entry>
</row>
<row>
<entry>
<para>...</para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
</row>
<row>
<entry>
<para>addis r9, r2, x3@got@dtprel@ha</para>
</entry>
<entry>
<para>R_PPC64_GOT_DTPREL16_HA</para>
</entry>
<entry>
<para>x3</para>
</entry>
</row>
<row>
<entry>
<para>ld r9, x3@got@dtprel@l(r9)</para>
</entry>
<entry>
<para>R_PPC64_GOT_DTPREL16_LO_DS</para>
</entry>
<entry>
<para>x3</para>
</entry>
</row>
<row>
<entry>
<para>add r9, r9, r3</para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
</row>
</tbody>
</tgroup>
</table>
<para> </para>
<para> </para>
<table frame="all" pgwide="1">
<title>Local-Dynamic-to-Local-Exec GOT Entry Relocations</title>
<tgroup cols="3">
<colspec colname="c1" colwidth="33*" />
<colspec colname="c2" colwidth="33*" />
<colspec colname="c3" colwidth="33*" />
<thead>
<row>
<entry>
<para>
<emphasis role="bold">Code Sequence</emphasis>
</para>
</entry>
<entry>
<para>
<emphasis role="bold">Relocation</emphasis>
</para>
</entry>
<entry>
<para>
<emphasis role="bold">Symbol</emphasis>
</para>
</entry>
</row>
</thead>
<tbody>
<row>
<entry>
<para>GOT[n]</para>
</entry>
<entry>
<para>R_PPC64_DTPMOD64</para>
</entry>
<entry>
<para>x1</para>
</entry>
</row>
<row>
<entry>
<para>GOT[n+1]</para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
</row>
<row>
<entry>
<para>...</para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
</row>
<row>
<entry>
<para>GOT[m]</para>
</entry>
<entry>
<para>R_PPC64_DTPREL64</para>
</entry>
<entry>
<para>x3</para>
</entry>
</row>
</tbody>
</tgroup>
</table>
<para> </para>
<para>The preceding code and global offset table entries are replaced by
the following code and global offset table entries.</para>
<para> </para>
<table frame="all" pgwide="1">
<title>Local-Dynamic-to-Local-Exec Replacement Initial
Relocations</title>
<tgroup cols="3">
<colspec colname="c1" colwidth="33*" />
<colspec colname="c2" colwidth="33*" />
<colspec colname="c3" colwidth="33*" />
<thead>
<row>
<entry>
<para>
<emphasis role="bold">Code Sequence</emphasis>
</para>
</entry>
<entry>
<para>
<emphasis role="bold">Relocation</emphasis>
</para>
</entry>
<entry>
<para>
<emphasis role="bold">Symbol</emphasis>
</para>
</entry>
</row>
</thead>
<tbody>
<row>
<entry>
<para>nop</para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
</row>
<row>
<entry>
<para>addis r3, r13, L@tprel@ha</para>
</entry>
<entry>
<para>R_PPC64_TPREL16_HA</para>
</entry>
<entry>
<para>link editor generated local symbol</para>
</entry>
</row>
<row>
<entry>
<para>nop</para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
</row>
<row>
<entry>
<para>addi r3, r3, L@tprel@l</para>
</entry>
<entry>
<para>R_PPC64_TPREL16_LO</para>
</entry>
<entry>
<para>link editor generated local symbol
<emphasis>
<xref linkend="dbdoclet.50655241_21152"
xrefstyle="select: nopage" />
</emphasis></para>
</entry>
</row>
<row>
<entry>
<para>..</para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
</row>
<row>
<entry>
<para>addi r9, r3, x1@dtprel</para>
</entry>
<entry>
<para>R_PPC64_DTPREL16</para>
</entry>
<entry>
<para>x1</para>
</entry>
</row>
<row>
<entry>
<para>..</para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
</row>
<row>
<entry>
<para>addis r9, r3, x2@dtprel@ha</para>
</entry>
<entry>
<para>R_PPC64_DTPREL16_HA</para>
</entry>
<entry>
<para>x2</para>
</entry>
</row>
<row>
<entry>
<para>addi r9, r9, x2@dtprel@l</para>
</entry>
<entry>
<para>R_PPC64_DTPREL16_LO</para>
</entry>
<entry>
<para>x2</para>
</entry>
</row>
<row>
<entry>
<para>...</para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
</row>
<row>
<entry>
<para>addis r9, r2, x3@got@dtprel@ha</para>
</entry>
<entry>
<para>R_PPC64_GOT_DTPREL16_HA</para>
</entry>
<entry>
<para>x3</para>
</entry>
</row>
<row>
<entry>
<para>ld r9, x3@got@dtprel@l(r9)</para>
</entry>
<entry>
<para>R_PPC64_GOT_DTPREL16_LO_DS</para>
</entry>
<entry>
<para>x3</para>
</entry>
</row>
<row>
<entry>
<para>add r9, r9, r3</para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
</row>
<row>
<entry nameend="c3" namest="c1">
<para>
<orderedlist>
<listitem xml:id="dbdoclet.50655241_21152">
<para>The linker may prefer to schedule the addis and
addi to be adjacent to take advantage of fusion as a
microarchitecture optimization opportunity.</para>
</listitem>
</orderedlist>
</para>
</entry>
</row>
</tbody>
</tgroup>
</table>
<para>The GOT[n] and GOT[n+1] entries can be removed by the linker after
the code transformation as shown in
<xref linkend="dbdoclet.50655241_90771" />.</para>
<table frame="all" pgwide="1" xml:id="dbdoclet.50655241_90771">
<title>Local-Dynamic-to-Local-Exec Replacement GOT Entry
Relocations</title>
<tgroup cols="3">
<colspec colname="c1" colwidth="33*" />
<colspec colname="c2" colwidth="33*" />
<colspec colname="c3" colwidth="33*" />
<thead>
<row>
<entry>
<para>
<emphasis role="bold">Code Sequence</emphasis>
</para>
</entry>
<entry>
<para>
<emphasis role="bold">Relocation</emphasis>
</para>
</entry>
<entry>
<para>
<emphasis role="bold">Symbol</emphasis>
</para>
</entry>
</row>
</thead>
<tbody>
<row>
<entry>
<para>GOT[m]</para>
</entry>
<entry>
<para>R_PPC64_DTPREL64</para>
</entry>
<entry>
<para>x3</para>
</entry>
</row>
</tbody>
</tgroup>
</table>
<para>The local symbol generated by the link editor points to the start
of the thread storage block plus 0x7000 bytes. In practice, a section
symbol with a suitable offset will be used.</para>
</section>
<section>
<title>Initial Exec to Local Exec</title>
<para>This transformation is only performed by the linker when the symbol
is within 2 GB + 28 KB of the thread pointer.</para>
<para> </para>
<table frame="all" pgwide="1">
<title>Initial-Exec-to-Local-Exec Initial Relocations</title>
<tgroup cols="3">
<colspec colname="c1" colwidth="33*" />
<colspec colname="c2" colwidth="33*" />
<colspec colname="c3" colwidth="33*" />
<thead>
<row>
<entry>
<para>
<emphasis role="bold">Code Sequence</emphasis>
</para>
</entry>
<entry>
<para>
<emphasis role="bold">Relocation</emphasis>
</para>
</entry>
<entry>
<para>
<emphasis role="bold">Symbol</emphasis>
</para>
</entry>
</row>
</thead>
<tbody>
<row>
<entry>
<para>addis r9, r2, x@got@tprel@ha</para>
</entry>
<entry>
<para>R_PPC64_GOT_TPREL16_HA</para>
</entry>
<entry>
<para>x</para>
</entry>
</row>
<row>
<entry>
<para>ld r9, x@got@tprel@l(r9)</para>
</entry>
<entry>
<para>R_PPC64_GOT_TPREL16_LO_DS</para>
</entry>
<entry>
<para>x</para>
</entry>
</row>
<row>
<entry>
<para>add r9, r9, x@tls</para>
</entry>
<entry>
<para>R_PPC64_TLS</para>
</entry>
<entry>
<para>x</para>
</entry>
</row>
</tbody>
</tgroup>
</table>
<para> </para>
<table frame="all" pgwide="1">
<title>Initial-Exec-to-Local-Exec GOT Entry Relocations</title>
<tgroup cols="3">
<colspec colname="c1" colwidth="33*" />
<colspec colname="c2" colwidth="33*" />
<colspec colname="c3" colwidth="33*" />
<thead>
<row>
<entry>
<para>
<emphasis role="bold">Code Sequence</emphasis>
</para>
</entry>
<entry>
<para>
<emphasis role="bold">Relocation</emphasis>
</para>
</entry>
<entry>
<para>
<emphasis role="bold">Symbol</emphasis>
</para>
</entry>
</row>
</thead>
<tbody>
<row>
<entry>
<para>GOT[n]</para>
</entry>
<entry>
<para>R_PPC64_TPREL64</para>
</entry>
<entry>
<para>x</para>
</entry>
</row>
</tbody>
</tgroup>
</table>
<para>The preceding code and global offset table entries are replaced by
the following code and global offset table entries.</para>
<para> </para>
<table frame="all" pgwide="1">
<title>Initial-Exec-to-Local-Exec Replacement Initial
Relocations</title>
<tgroup cols="3">
<colspec colname="c1" colwidth="33*" />
<colspec colname="c2" colwidth="33*" />
<colspec colname="c3" colwidth="33*" />
<tbody>
<row>
<entry>
<para>Code Sequence</para>
</entry>
<entry>
<para>Relocation</para>
</entry>
<entry>
<para>Symbol</para>
</entry>
</row>
<row>
<entry>
<para>nop</para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
</row>
<row>
<entry>
<para>addis r9, r13, x@tprel@ha</para>
</entry>
<entry>
<para>R_PPC64_TPREL16_HA</para>
</entry>
<entry>
<para>x</para>
</entry>
</row>
<row>
<entry>
<para>addi r9, r9, x@tprel@l</para>
</entry>
<entry>
<para>R_PPC64_TPREL16_LO</para>
</entry>
<entry>
<para>x</para>
</entry>
</row>
</tbody>
</tgroup>
</table>
<para>Other sizes and types of thread-local variables may use any of the
X-form indexed load or store instructions.</para>
<para>
<xref linkend="dbdoclet.50655241_81882" /> shows how to access the
contents of a variable using the X-form indexed load and store
instructions.</para>
<para> </para>
<table frame="all" pgwide="1" xml:id="dbdoclet.50655241_81882">
<title>Initial-Exec-to-Local-Exec X-form Initial Relocations</title>
<tgroup cols="3">
<colspec colname="c1" colwidth="33*" />
<colspec colname="c2" colwidth="33*" />
<colspec colname="c3" colwidth="33*" />
<thead>
<row>
<entry>
<para>
<emphasis role="bold">Code Sequence</emphasis>
</para>
</entry>
<entry>
<para>
<emphasis role="bold">Relocation</emphasis>
</para>
</entry>
<entry>
<para>
<emphasis role="bold">Symbol</emphasis>
</para>
</entry>
</row>
</thead>
<tbody>
<row>
<entry>
<para>addis r9, r2, x@got@tprel@ha</para>
</entry>
<entry>
<para>R_PPC64_GOT_TPREL16_HA</para>
</entry>
<entry>
<para>x</para>
</entry>
</row>
<row>
<entry>
<para>ld r9, x@got@tprel@l(r9)</para>
</entry>
<entry>
<para>R_PPC64_GOT_TPREL16_LO_DS</para>
</entry>
<entry>
<para>x</para>
</entry>
</row>
<row>
<entry>
<para>lbzx r10, r9, x@tls</para>
</entry>
<entry>
<para>R_PPC64_TLS</para>
</entry>
<entry>
<para>x</para>
</entry>
</row>
<row>
<entry>
<para>addi r10, r10, 1</para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
</row>
<row>
<entry>
<para>stbx r10, r9, x@tls</para>
</entry>
<entry>
<para>R_PPC64_TLS</para>
</entry>
<entry>
<para>x</para>
</entry>
</row>
</tbody>
</tgroup>
</table>
<para> </para>
<table frame="all" pgwide="1">
<title>Initial-Exec-to-Local-Exec X-form GOT Entry Relocations</title>
<tgroup cols="3">
<colspec colname="c1" colwidth="33*" />
<colspec colname="c2" colwidth="33*" />
<colspec colname="c3" colwidth="33*" />
<thead>
<row>
<entry>
<para>
<emphasis role="bold">Code Sequence</emphasis>
</para>
</entry>
<entry>
<para>
<emphasis role="bold">Relocation</emphasis>
</para>
</entry>
<entry>
<para>
<emphasis role="bold">Symbol</emphasis>
</para>
</entry>
</row>
</thead>
<tbody>
<row>
<entry>
<para>GOT[n]</para>
</entry>
<entry>
<para>R_PPC64_TPREL64</para>
</entry>
<entry>
<para>x</para>
</entry>
</row>
</tbody>
</tgroup>
</table>
<para>The preceding code and global offset table entries are replaced by
the following code and global offset table entries.</para>
<para> </para>
<table frame="all" pgwide="1">
<title>Initial-Exec-to-Local-Exec X-form Replacement Initial
Relocations</title>
<tgroup cols="3">
<colspec colname="c1" colwidth="33*" />
<colspec colname="c2" colwidth="33*" />
<colspec colname="c3" colwidth="33*" />
<thead>
<row>
<entry>
<para>
<emphasis role="bold">Code Sequence</emphasis>
</para>
</entry>
<entry>
<para>
<emphasis role="bold">Relocation</emphasis>
</para>
</entry>
<entry>
<para>
<emphasis role="bold">Symbol</emphasis>
</para>
</entry>
</row>
</thead>
<tbody>
<row>
<entry>
<para>nop</para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
</row>
<row>
<entry>
<para>addis r9, r13, x@tprel@ha</para>
</entry>
<entry>
<para>R_PPC64_TPREL16_HA</para>
</entry>
<entry>
<para>x</para>
</entry>
</row>
<row>
<entry>
<para>lbz r10, x@tprel@l(r9)</para>
</entry>
<entry>
<para>R_PPC64_TPREL16_LO</para>
</entry>
<entry>
<para>x</para>
</entry>
</row>
<row>
<entry>
<para>addi r10, r10, 1</para>
</entry>
<entry>
<para> </para>
</entry>
<entry>
<para> </para>
</entry>
</row>
<row>
<entry>
<para>stb r10, x@tprel@l(r9)</para>
</entry>
<entry>
<para>R_PPC64_TPREL16_LO</para>
</entry>
<entry>
<para>x</para>
</entry>
</row>
</tbody>
</tgroup>
</table>
</section>
</section>
<section>
<title>ELF TLS Definitions</title>
<para>The result of performing a relocation for a TLS symbol is the
module ID and its offset within the TLS block. These are then stored in
the GOT. Later, they are obtained by the dynamic linker at run-time and
passed to __tls_get_addr( ), which returns the address for the variable
for the current thread.</para>
<para>For more information, see
<xref linkend="dbdoclet.50655241_18894" />. For TLS relocations, see
<xref linkend="dbdoclet.50655241_47572" />.</para>
<para>&#160;</para>
<bridgehead>TLS Relocation Descriptions</bridgehead>
<para>The following marker relocations tie together instructions in TLS
code sequences. They allow the link editor to reliably optimize TLS code.
R_PPC64_TLSGD and R_PPC64_TLSLD shall be emitted immediately before their
associated __tls_get_addr call relocation.</para>
<para>R_PPC64_TLS</para>
<para>R_PPC64_TLSGD</para>
<para>R_PPC64_TLSLD</para>
</section>
</section>
<section>
<title>System Support Functions and Extensions</title>
<section>
<title>Back Chain</title>
<para>Systems must provide a back chain by default, and they must include
compilers allocating a back chain and system libraries allocating a back
chain. Alternate libraries may be supplied in addition to, and beyond,
but never instead of those providing a back chain. Code generating and
using a back chain shall be the default for compilers, linkers, and
library selection.</para>
</section>
<section>
<title>Nested Functions</title>
<para>Nested functions that access their ancestors stack frames are
entered with r11 initialized to an environment pointer. The environment
pointer is typically a copy of the stack pointer for the most recent
instance of the nested function's parent's stack frame. When a function
pointer to a nested function referencing its outer context is created, an
implementation may create a trampoline to load the present environment
pointer to r11, followed by an unconditional branch to the function code
of the nested function contained in the text segment.</para>
<para>When a trampoline is used, a pointer to a nested function is
represented by the code address of the trampoline.</para>
<para>In some environments, the trampoline code may be created by
allocating memory on the data stack, making at least pages containing
trampolines executable. In other environments, executable pages may be
prohibited in the stack area for security reasons.</para>
<para>Alternate implementations, such as creating code stacks for
allocating nested function trampolines, may be used. In garbage-collected
environments, yet other ways for managing trampolines are
available.</para>
</section>
<section>
<title>Traceback Tables</title>
<para>To support debuggers and exception handlers, the 64-bit
<citetitle>OpenPOWER ELF V2 ABI</citetitle> defines the use of descriptive
debug and unwind information that enables flexible debugging and
unwinding of optimized code (such as, for example, DWARF).</para>
<para>To support legacy tooling, the
<citetitle>OpenPOWER ELF V2 ABI</citetitle> also specifies the use of a
traceback table that may provide additional information about
functions.</para>
<para>
<xref linkend="dbdoclet.50655241_18645" /> describes a minimal set of
fields that may, optionally, specify information about a function.
Additional fields may be present in a traceback table in accordance with
commonly used PowerPC traceback conventions in other environments, but
they are not specified in the current ABI definition.</para>
</section>
<section xml:id="dbdoclet.50655241_18645">
<title>Traceback Table Fields</title>
<para>If a traceback table is present, the following fields are
mandatory:</para>
<para> </para>
<informaltable frame="none" rowsep="0" colsep="0">
<tgroup cols="2">
<colspec colname="c1" colwidth="15*" />
<colspec colname="c2" colwidth="85*" />
<tbody>
<row>
<entry>
<para>version</para>
</entry>
<entry>
<para>Eight-bit field. This defines the type code for the
table. The only currently defined value is zero.</para>
</entry>
</row>
<row>
<entry>
<para>lang</para>
</entry>
<entry>
<para>Eight-bit field. This defines the source language for the
compiler that generated the code to which this traceback table
applies. The default values are as follows:</para>
<informaltable frame="none" colsep="0" rowsep="0">
<tgroup cols="2">
<colspec colname="c1" colwidth="15*" />
<colspec colname="c2" colwidth="85*" />
<tbody>
<row>
<entry><para>C</para></entry>
<entry><para>0</para></entry>
</row>
<row>
<entry><para>Fortran</para></entry>
<entry><para>1</para></entry>
</row>
<row>
<entry><para>Pascal</para></entry>
<entry><para>2</para></entry>
</row>
<row>
<entry><para>Ada</para></entry>
<entry><para>3</para></entry>
</row>
<row>
<entry><para>PL/1</para></entry>
<entry><para>4</para></entry>
</row>
<row>
<entry><para>Basic</para></entry>
<entry><para>5</para></entry>
</row>
<row>
<entry><para>LISP</para></entry>
<entry><para>6</para></entry>
</row>
<row>
<entry><para>COBOL</para></entry>
<entry><para>7</para></entry>
</row>
<row>
<entry><para>Modula2</para></entry>
<entry><para>8</para></entry>
</row>
<row>
<entry><para>C++</para></entry>
<entry><para>9</para></entry>
</row>
<row>
<entry><para>RPG</para></entry>
<entry><para>10</para></entry>
</row>
<row>
<entry><para>PL.8, PLIX</para></entry>
<entry><para>11</para></entry>
</row>
<row>
<entry><para>Assembly</para></entry>
<entry><para>12</para></entry>
</row>
<row>
<entry><para>Java</para></entry>
<entry><para>13</para></entry>
</row>
<row>
<entry><para>Objective C</para></entry>
<entry><para>14</para></entry>
</row>
<row>
<entry nameend="c2" namest="c1">
<para>The codes 0xf - 0xfa are reserved. The codes
0xfb - 0xff are reserved for IBM.</para></entry>
</row>
</tbody>
</tgroup>
</informaltable>
</entry>
</row>
<row>
<entry>
<para>globalink</para>
</entry>
<entry>
<para>One-bit field. This field is set to 1 if this routine is
a special routine used to support the linkage convention: a
linkage function including a procedure linkage table function,
pointer glue code, a trampoline, or other compiler- or
linker-generated functions that stack traceback functions
should skip, other than is_eprol functions. For more
information, see
<xref linkend="dbdoclet.50655240_88555" />. These routines have
an unusual register usage and stack format.</para>
</entry>
</row>
<row>
<entry>
<para>is_eprol</para>
</entry>
<entry>
<para>One-bit field. This field is set to 1 if this routine is
an out-of-line prologue or epilogue function, including a
register save or restore function. Stack traceback functions
should skip these. For more information, see
<xref linkend="dbdoclet.50655240_12107" />. These routines have
an unusual register usage and stack format.</para>
</entry>
</row>
<row>
<entry>
<para>has_tboff</para>
</entry>
<entry>
<para>One-bit field. This field is set to 1 if the offset of
the traceback table from the start of the function is stored in
the tb_offset field.</para>
</entry>
</row>
<row>
<entry>
<para>int_proc</para>
</entry>
<entry>
<para>One-bit field. This field is set to 1 if this function is
a stackless leaf function that does not have a separate stack
frame.</para>
</entry>
</row>
<row>
<entry>
<para>has_ctl</para>
</entry>
<entry>
<para>One-bit field. This field is set to 1 if ctl_info is
provided.</para>
</entry>
</row>
<row>
<entry>
<para>tocless</para>
</entry>
<entry>
<para>One-bit field. This field is set to 1 if this function
does not have a TOC. For example, a stackless leaf assembly
language routine with no references to external objects.</para>
</entry>
</row>
<row>
<entry>
<para>fp_present</para>
</entry>
<entry>
<para>One-bit field. This field is set to 1 if the function
uses floating-point processor instructions.</para>
</entry>
</row>
<row>
<entry>
<para>log_abort</para>
</entry>
<entry>
<para>One-bit field. Reserved.</para>
</entry>
</row>
<row>
<entry>
<para>int_handl</para>
</entry>
<entry>
<para>One-bit field. Reserved.</para>
</entry>
</row>
<row>
<entry>
<para>name_present</para>
</entry>
<entry>
<para>One-bit field. This field is set to 1 if the name for the
procedure is present following the traceback field, as
determined by the name_len and name fields.</para>
</entry>
</row>
<row>
<entry>
<para>uses_alloca</para>
</entry>
<entry>
<para>One-bit field. This field is set to 1 if the procedure
performs dynamic stack allocation. To address their local
variables, these procedures require a different register to
hold the stack pointer value. This register may be chosen by
the compiler, and must be indicated by setting the value of the
alloc_reg field.</para>
</entry>
</row>
<row>
<entry>
<para>cl_dis_inv</para>
</entry>
<entry>
<para>Three-bit field. Reserved.</para>
</entry>
</row>
<row>
<entry>
<para>saves_cr</para>
</entry>
<entry>
<para>One-bit field. This field indicates whether the CR fields
are saved in the CR save word. If traceback tables are used in
place of DWARF unwind information, at least all volatile CR
fields must be saved in the CR save word.</para>
</entry>
</row>
<row>
<entry>
<para>saves_lr</para>
</entry>
<entry>
<para>One-bit field. This field is set to 1 if the function
saves the LR in the LR save doubleword.</para>
</entry>
</row>
<row>
<entry>
<para>stores_bc</para>
</entry>
<entry>
<para>One-bit field. This field is set to 1 if the function
saves the back chain (the SP of its caller) in the stack frame
header.</para>
</entry>
</row>
<row>
<entry>
<para>fixup</para>
</entry>
<entry>
<para>One-bit field. This field is set to 1 if the link editor
replaced the original instruction by a branch instruction to a
special fix-up instruction sequence.</para>
</entry>
</row>
<row>
<entry>
<para>fp_saved</para>
</entry>
<entry>
<para>Six-bit field. This field is set to the number of
nonvolatile floating-point registers that the function saves.
When traceback unwind and debug information is used, the last
register saved is always f31. Therefore, for example, a value
of 2 in this field indicates that f30 and f31 are saved.</para>
</entry>
</row>
<row>
<entry>
<para>has_vec_info</para>
</entry>
<entry>
<para>One-bit field. This field is set to 1 if the procedure
saves nonvolatile vector registers in the Vector Register Save
Area, specifies the number of vector parameters, or uses VMX
instructions.</para>
</entry>
</row>
<row>
<entry>
<para>spare4</para>
</entry>
<entry>
<para>One-bit field. Reserved.</para>
</entry>
</row>
<row>
<entry>
<para>gpr_saved</para>
</entry>
<entry>
<para>Six-bit field. This field is set to the number of
nonvolatile general registers that the function saves. As with
fp_saved, when traceback unwind and debug information is used,
the last register saved is always r31.</para>
</entry>
</row>
<row>
<entry>
<para>fixedparms</para>
</entry>
<entry>
<para>Eight-bit field. This field is set to the number of
fixed-point parameters.</para>
</entry>
</row>
<row>
<entry>
<para>floatparms</para>
</entry>
<entry>
<para>Seven-bit field. This field is set to the number of
floating-point parameters.</para>
</entry>
</row>
<row>
<entry>
<para>parmsonstk</para>
</entry>
<entry>
<para>One-bit field. This field is set to 1 if all of the
parameters are placed in the Parameter Save Area.</para>
</entry>
</row>
</tbody>
</tgroup>
</informaltable>
<para> </para>
</section>
</section>
</chapter>