From 34500d4e5335d248cc02dcad914328bcf2b9e531 Mon Sep 17 00:00:00 2001 From: Peter Smith Date: Wed, 14 Oct 2026 16:54:52 +0100 Subject: [PATCH] [sysvabi64] 2026q3 review comments on TLS chapter Typo fixes: * Removed duplicate "of accessing TLS". * Added apostrophes to executable's. * Expanded the local dynamic TLS section. The local dynamic section only mentioned that the _TLS_MODULE_BASE_ symbol was to be used to obtain the base of the TLS block for the module. It didn't mention the additional calculation to find the offset of the variable from _TLS_MODULE_BASE_. Added an example and the :dtprel_hi12: operator that was missing from the list of assembler operators. --- sysvabi64/sysvabi64.rst | 50 ++++++++++++++++++++++++++++++++--------- 1 file changed, 40 insertions(+), 10 deletions(-) diff --git a/sysvabi64/sysvabi64.rst b/sysvabi64/sysvabi64.rst index effce533..47b09699 100644 --- a/sysvabi64/sysvabi64.rst +++ b/sysvabi64/sysvabi64.rst @@ -618,6 +618,8 @@ syntax is of the form ``#::`` +-----------------------+-------------+---------------------------------------+ | ``tlsldm_lo12_nc`` | ``add`` | R_AARCH64_TLSLD_ADD_LO12_NC | +-----------------------+-------------+---------------------------------------+ + | ``dtprel_hi12`` | ``add`` | R_AARCH64_TLSLD_ADD_DTPREL_HI21 | + +-----------------------+-------------+---------------------------------------+ | ``dtprel_lo12`` | ``add`` | R_AARCH64_TLSLD_ADD_DTPREL_LO12 | +-----------------------+-------------+---------------------------------------+ | ``dtprel_lo12`` | ``ldr`` | R_AARCH64_TLSLD_LDST64_DTPREL_LO12 | @@ -2208,8 +2210,8 @@ applied to both static and dynamic TLS. TLS models ---------- -There are four defined models of accessing TLS -of accessing TLS that trade off generality for performance. In descending order of generality: +There are four defined models of accessing TLS that trade off +generality for performance. In descending order of generality: 1. General Dynamic, also known as Global Dynamic, can be used anywhere. @@ -2220,7 +2222,7 @@ of accessing TLS that trade off generality for performance. In descending order static TLS block. 4. Local Exec, can be used in the executable for TLS variables - defined in the executables static TLS block. + defined in the executable's static TLS block. AArch64 TLS SystemV design choices ---------------------------------- @@ -2268,7 +2270,7 @@ program header. A number of dynamic linkers use a different calculation that requires ``PT_TLS.p_vaddr ≡ 0 (modulo PT_TLS.p_align)`` to correctly align the -executables TLS block. In this case the expression above simplifies to +executable's TLS block. In this case the expression above simplifies to ``PADsize = Max(0, PT_TLS.p_align - TCBsize``). For maximum compatibility, static linkers and any linker scripts including TLS, are recommended to align the TLS block so that ``PT_TLS.p_vaddr ≡ 0 @@ -2378,7 +2380,7 @@ Small Code Model; adrp x0, :tlsdesc:var // R_AARCH64_TLSDESC_ADR_PAGE21 var ldr x1, [x0, #:tlsdesc_lo12:var] // R_AARCH64_TLSDESC_LD64_LO12 var - add x0, x0, #:tlsdesc_lo12:var] // R_AARCH64_TLSDESC_ADD_LO12 var + add x0, x0, #:tlsdesc_lo12:var // R_AARCH64_TLSDESC_ADD_LO12 var .tlsdesccall var blr x1 // R_AARCH64_TLSDESC_CALL var // offset of var from tp in x0 @@ -2422,11 +2424,39 @@ general dynamic when more than one TLS variable from the same module is accessed from the same function, but less efficient when accessing a single TLS variable. -The code sequence for local dynamic is the same as global dynamic and -like global dynamic must be emitted exactly as specified. There are no +The code sequence to obtain the offset of the module's TLS block from +the thread pointer is the same as the code sequence for finding the +offset of a variable from the thread pointer with global dynamic. Like +global dynamic must be emitted exactly as specified. There are no specific relocations for Local Dynamic using the descriptor dialect. A -special symbol ``_TLS_MODULE_BASE_`` is used to get a tlsdesccall to -return the offset of the module's TLS block from the thread pointer. +special symbol ``_TLS_MODULE_BASE_`` is used as the relocation target. +The static linker must define ``_TLS_MODULE_BASE_`` to the address of +the TLS block for the module if it is referenced. + +.. code-block:: asm + + adrp x0, :tlsdesc:_TLS_MODULE_BASE_ + ldr x1, [x0, #:tlsdesc_lo12:_TLS_MODULE_BASE_] + add x0, x0, #:tlsdesc_lo12:_TLS_MODULE_BASE_ + .tlsdesccall _TLS_MODULE_BASE_ + blr x1 + // offset of _TLS_MODULE_BASE_ from tp in x0 + +To calculation to find the address of a local dynamic tls variable +called ``var`` is: + +``TP`` + (offset of ``_TLS_MODULE_BASE_`` from ``TP``) + (offset of +``var`` from ``_TLS_MODULE_BASE_``). + +The calculation of the offset of ``var`` from ``_TLS_MODULE_BASE_`` is +not defined by the ABI. The code-sequence below shows one possibility: + +.. code-block:: asm + + // offset of _TLS_MODULE_BASE_from tp in x0 + add x0, x0, :dtprel_hi12:var // R_AARCH64_TLSLD_ADD_DTPREL_HI12 + add x0, x0, :dtprel_lo12_nc:var // R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC + // offset of var from tp in x0 Code-generators are not required to implement local dynamic and can emit general dynamic in its place. @@ -2495,7 +2525,7 @@ executables TLS block is smaller than 16 KiB. add xn, xn, :tprel_lo12_nc:var // R_AARCH64_TLSLE_ADD_TPREL_LO12_NC var // offset of var from tp in xn -Optimization to load a 64-bit var directly into a core register. +Optimization to load a var directly into a core register. .. code-block:: asm