Skip to content

Commit 341e3d5

Browse files
authored
[AAELF64] TLS GOT generating relocations must have 0 addend. (#313)
Bring TLS GOT generating relocations in line with non GOT generating relocations in #272. The ABI rule is that static linkers should generate a GOT entry for each unique tuple of (S,A). However static linkers such as GNU ld and lld only generate a unique entry per unique S, and handle A inconsistently. With GNU ld ignoring A and lld adding it after. The only consistent behaviour between implementations is when A is 0.
1 parent 11fb4ef commit 341e3d5

File tree

1 file changed

+22
-19
lines changed

1 file changed

+22
-19
lines changed

aaelf64/aaelf64.rst

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,8 @@ changes to the content of the document for that release.
288288
| 2025Q1 | 7\ :sup:`th` | - In `Section Attribute Flags`_, added |
289289
| | April 2025 | `SHF_AARCH64_PURECODE` processor |
290290
| | | specific section attribute flag. |
291+
| | | - Clarify use of addends in GOT |
292+
| | | generating static TLS relocations. |
291293
+---------------+--------------------+-----------------------------------------+
292294
| 2025Q4 | 23\ :sup:`rd` | - In `Call and Jump relocations`_ added |
293295
| | January 2026 | static linker requirements on veneers |
@@ -1516,6 +1518,7 @@ In addition to the terms defined in `Relocation types`_, the tables listing the
15161518

15171519
- ``TLSDESC(S+A)`` resolves to a contiguous pair of pointer-sized values, as created by ``GTLSDESC(S+A)``.
15181520

1521+
Relocations using the operations ``GTLSDESC(S)``, ``GTPREL(S)`` and ``GTLSIDX(S)`` relocations must have a zero addend. Previous versions of this document included the addend ``A`` in ``Operation(S + A)`` where Operation is one of ``GTLSDESC,``, ``GTPREL`` and ``GTLSIDX``. This results in a GOT entry, or pair of entries for ``S + A``. With a zero addend ``Operation(S + 0)`` is equivalent to ``Operation(S)`` and ``Operation(S) + 0``.
15191522

15201523
General Dynamic thread-local storage model
15211524
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -1527,15 +1530,15 @@ General Dynamic thread-local storage model
15271530
+------------+------------+---------------------------------+---------------------------------+------------------------------------------------------------------------------------------+
15281531
| ELF64 Code | ELF32 Code | Name | Operation | Comment |
15291532
+============+============+=================================+=================================+==========================================================================================+
1530-
| 512 | 80 | R\_<CLS>\_TLSGD\_ADR\_PREL21 | G(GTLSIDX(S,A)) - P | Set an ADR immediate field to bits [20:0] of X; check –2\ :sup:`20` <= X < 2\ :sup:`20` |
1533+
| 512 | 80 | R\_<CLS>\_TLSGD\_ADR\_PREL21 | G(GTLSIDX(S)) - P | Set an ADR immediate field to bits [20:0] of X; check –2\ :sup:`20` <= X < 2\ :sup:`20` |
15311534
+------------+------------+---------------------------------+---------------------------------+------------------------------------------------------------------------------------------+
1532-
| 513 | 81 | R\_<CLS>\_TLSGD\_ADR\_PAGE21 | Page(G(GTLSIDX(S,A)) - Page(P) | Set an ADRP immediate field to bits [32:12] of X; check –2\ :sup:`32` <= X < 2\ :sup:`32`|
1535+
| 513 | 81 | R\_<CLS>\_TLSGD\_ADR\_PAGE21 | Page(G(GTLSIDX(S)) - Page(P) | Set an ADRP immediate field to bits [32:12] of X; check –2\ :sup:`32` <= X < 2\ :sup:`32`|
15331536
+------------+------------+---------------------------------+---------------------------------+------------------------------------------------------------------------------------------+
1534-
| 514 | 82 | R\_<CLS>\_TLSGD\_ADD\_LO12\_NC | G(GTLSIDX(S,A)) | Set an ADD immediate field to bits [11:0] of X. No overflow check |
1537+
| 514 | 82 | R\_<CLS>\_TLSGD\_ADD\_LO12\_NC | G(GTLSIDX(S)) | Set an ADD immediate field to bits [11:0] of X. No overflow check |
15351538
+------------+------------+---------------------------------+---------------------------------+------------------------------------------------------------------------------------------+
1536-
| 515 | \- | R\_<CLS>\_TLSGD\_MOVW\_G1 | G(GTLSIDX(S,A)) - GOT | Set a MOV[NZ] immediate field to bits [31:16] of X (see notes below) |
1539+
| 515 | \- | R\_<CLS>\_TLSGD\_MOVW\_G1 | G(GTLSIDX(S)) - GOT | Set a MOV[NZ] immediate field to bits [31:16] of X (see notes below) |
15371540
+------------+------------+---------------------------------+---------------------------------+------------------------------------------------------------------------------------------+
1538-
| 516 | \- | R\_<CLS>\_TLSGD\_MOVW\_G0\_NC | G(GTLSIDX(S,A)) - GOT | Set a MOVK immediate field to bits [15:0] of X. No overflow check |
1541+
| 516 | \- | R\_<CLS>\_TLSGD\_MOVW\_G0\_NC | G(GTLSIDX(S)) - GOT | Set a MOVK immediate field to bits [15:0] of X. No overflow check |
15391542
+------------+------------+---------------------------------+---------------------------------+------------------------------------------------------------------------------------------+
15401543

15411544
.. note::
@@ -1627,17 +1630,17 @@ Initial Exec thread-local storage model
16271630
+------------+------------+--------------------------------------------+--------------------------------+------------------------------------------------------------------------------------------+
16281631
| ELF64 Code | ELF32 Code | Name | Operation | Comment |
16291632
+============+============+============================================+================================+==========================================================================================+
1630-
| 539 | \- | R\_<CLS>\_TLSIE\_MOVW\_GOTTPREL\_G1 | G(GTPREL(S+A)) - GOT | Set a MOV[NZ] immediate field to bits [31:16] of X (see notes below) |
1633+
| 539 | \- | R\_<CLS>\_TLSIE\_MOVW\_GOTTPREL\_G1 | G(GTPREL(S)) - GOT | Set a MOV[NZ] immediate field to bits [31:16] of X (see notes below) |
16311634
+------------+------------+--------------------------------------------+--------------------------------+------------------------------------------------------------------------------------------+
1632-
| 540 | \- | R\_<CLS>\_TLSIE\_MOVW\_GOTTPREL\_G0\_NC | G(GTPREL(S+A)) - GOT | Set MOVK immediate to bits [15:0] of X. No overflow check |
1635+
| 540 | \- | R\_<CLS>\_TLSIE\_MOVW\_GOTTPREL\_G0\_NC | G(GTPREL(S)) - GOT | Set MOVK immediate to bits [15:0] of X. No overflow check |
16331636
+------------+------------+--------------------------------------------+--------------------------------+------------------------------------------------------------------------------------------+
1634-
| 541 | 103 | R\_<CLS>\_TLSIE\_ADR\_GOTTPREL\_PAGE21 | Page(G(GTPREL(S+A))) - Page(P) | Set an ADRP immediate field to bits [32:12] of X; check –2\ :sup:`32` <= X < 2\ :sup:`32`|
1637+
| 541 | 103 | R\_<CLS>\_TLSIE\_ADR\_GOTTPREL\_PAGE21 | Page(G(GTPREL(S))) - Page(P) | Set an ADRP immediate field to bits [32:12] of X; check –2\ :sup:`32` <= X < 2\ :sup:`32`|
16351638
+------------+------------+--------------------------------------------+--------------------------------+------------------------------------------------------------------------------------------+
1636-
| 542 | \- | R\_<CLS>\_TLSIE\_LD64\_GOTTPREL\_LO12\_NC | G(GTPREL(S+A)) | Set an LD offset field to bits [11:3] of X. No overflow check; check that X&7=0 |
1639+
| 542 | \- | R\_<CLS>\_TLSIE\_LD64\_GOTTPREL\_LO12\_NC | G(GTPREL(S)) | Set an LD offset field to bits [11:3] of X. No overflow check; check that X&7=0 |
16371640
+------------+------------+--------------------------------------------+--------------------------------+------------------------------------------------------------------------------------------+
1638-
| \- | 104 | R\_<CLS>\_TLSIE\_LD32\_GOTTPREL\_LO12\_NC | G(GTPREL(S+A)) | Set an LD offset field to bits [11:2] of X. No overflow check; check that X&3=0 |
1641+
| \- | 104 | R\_<CLS>\_TLSIE\_LD32\_GOTTPREL\_LO12\_NC | G(GTPREL(S)) | Set an LD offset field to bits [11:2] of X. No overflow check; check that X&3=0 |
16391642
+------------+------------+--------------------------------------------+--------------------------------+------------------------------------------------------------------------------------------+
1640-
| 543 | 105 | R\_<CLS>\_TLSIE\_LD\_GOTTPREL\_PREL19 | G(GTPREL(S+A)) – P | Set a load-literal immediate to bits [20:2] of X; check –2\ :sup:`20` <= X < 2\ :sup:`20`|
1643+
| 543 | 105 | R\_<CLS>\_TLSIE\_LD\_GOTTPREL\_PREL19 | G(GTPREL(S)) – P | Set a load-literal immediate to bits [20:2] of X; check –2\ :sup:`20` <= X < 2\ :sup:`20`|
16411644
+------------+------------+--------------------------------------------+--------------------------------+------------------------------------------------------------------------------------------+
16421645

16431646
.. note::
@@ -1708,23 +1711,23 @@ Thread-local storage descriptors
17081711
+------------+------------+---------------------------------+----------------------------------+----------------------------------------------------------------------------------------------+
17091712
| ELF64 Code | ELF32 Code | Name | Operation | Comment |
17101713
+============+============+=================================+==================================+==============================================================================================+
1711-
| 560 | 122 | R\_<CLS>\_TLSDESC\_LD\_PREL19 | G(GTLSDESC(S+A)) - P | Set a load-literal immediate to bits [20:2]; check -2\ :sup:`20` <= X < 2\ :sup:`20`; check |
1714+
| 560 | 122 | R\_<CLS>\_TLSDESC\_LD\_PREL19 | G(GTLSDESC(S)) - P | Set a load-literal immediate to bits [20:2]; check -2\ :sup:`20` <= X < 2\ :sup:`20`; check |
17121715
| | | | | X & 3 = 0. |
17131716
+------------+------------+---------------------------------+----------------------------------+----------------------------------------------------------------------------------------------+
1714-
| 561 | 123 | R\_<CLS>\_TLSDESC\_ADR\_PREL21 | G(GTLSDESC(S+A)) - P | Set an ADR immediate field to bits [20:0]; check -2\ :sup:`20` <= X < 2\ :sup:`20`. |
1717+
| 561 | 123 | R\_<CLS>\_TLSDESC\_ADR\_PREL21 | G(GTLSDESC(S)) - P | Set an ADR immediate field to bits [20:0]; check -2\ :sup:`20` <= X < 2\ :sup:`20`. |
17151718
+------------+------------+---------------------------------+----------------------------------+----------------------------------------------------------------------------------------------+
1716-
| 562 | 124 | R\_<CLS>\_TLSDESC\_ADR\_PAGE21 | Page(G(GTLSDESC(S+A))) - Page(P) | Set an ADRP immediate field to bits [32:12] of X; check -2\ :sup:`32` <= X < 2\ :sup:`32`. |
1719+
| 562 | 124 | R\_<CLS>\_TLSDESC\_ADR\_PAGE21 | Page(G(GTLSDESC(S))) - Page(P) | Set an ADRP immediate field to bits [32:12] of X; check -2\ :sup:`32` <= X < 2\ :sup:`32`. |
17171720
+------------+------------+---------------------------------+----------------------------------+----------------------------------------------------------------------------------------------+
1718-
| 563 | \- | R\_<CLS>\_TLSDESC\_LD64\_LO12 | G(GTLSDESC(S+A)) | Set an LD offset field to bits [11:3] of X. No overflow check; check X & 7 = 0. |
1721+
| 563 | \- | R\_<CLS>\_TLSDESC\_LD64\_LO12 | G(GTLSDESC(S)) | Set an LD offset field to bits [11:3] of X. No overflow check; check X & 7 = 0. |
17191722
+------------+------------+---------------------------------+----------------------------------+----------------------------------------------------------------------------------------------+
1720-
| \- | 125 | R\_<CLS>\_TLSDESC\_LD32\_LO12 | G(GTLSDESC(S+A)) | Set an LD offset field to bits [11:2] of X. No overflow check; check X & 3 = 0. |
1723+
| \- | 125 | R\_<CLS>\_TLSDESC\_LD32\_LO12 | G(GTLSDESC(S)) | Set an LD offset field to bits [11:2] of X. No overflow check; check X & 3 = 0. |
17211724
+------------+------------+---------------------------------+----------------------------------+----------------------------------------------------------------------------------------------+
1722-
| 564 | 126 | R\_<CLS>\_TLSDESC\_ADD\_LO12 | G(GTLSDESC(S+A)) | Set an ADD immediate field to bits [11:0] of X. No overflow check. |
1725+
| 564 | 126 | R\_<CLS>\_TLSDESC\_ADD\_LO12 | G(GTLSDESC(S)) | Set an ADD immediate field to bits [11:0] of X. No overflow check. |
17231726
+------------+------------+---------------------------------+----------------------------------+----------------------------------------------------------------------------------------------+
1724-
| 565 | \- | R\_<CLS>\_TLSDESC\_OFF\_G1 | G(GTLSDESC(S+A)) - GOT | Set a MOV[NZ] immediate field to bits [31:16] of X; check -2\ :sup:`32` <= X < 2\ :sup:`32`. |
1727+
| 565 | \- | R\_<CLS>\_TLSDESC\_OFF\_G1 | G(GTLSDESC(S)) - GOT | Set a MOV[NZ] immediate field to bits [31:16] of X; check -2\ :sup:`32` <= X < 2\ :sup:`32`. |
17251728
| | | | | See notes below. |
17261729
+------------+------------+---------------------------------+----------------------------------+----------------------------------------------------------------------------------------------+
1727-
| 566 | \- | R\_<CLS>\_TLSDESC\_OFF\_G0\_NC | G(GTLSDESC(S+A)) - GOT | Set a MOVK immediate field to bits [15:0] of X. No overflow check. |
1730+
| 566 | \- | R\_<CLS>\_TLSDESC\_OFF\_G0\_NC | G(GTLSDESC(S)) - GOT | Set a MOVK immediate field to bits [15:0] of X. No overflow check. |
17281731
+------------+------------+---------------------------------+----------------------------------+----------------------------------------------------------------------------------------------+
17291732
| 567 | \- | R\_<CLS>\_TLSDESC\_LDR | None | For relaxation only. Must be used to identify an LDR instruction which loads the TLS |
17301733
| | | | | descriptor function pointer for S + A if it has no other relocation. |

0 commit comments

Comments
 (0)