# Thread-local storage The Hexagon development tools support thread-local storage (TLS), which is data that is allocated at runtime and accessible only by the thread that allocates it. ## Thread-local storage section Both initialized and uninitialized TLS data can be specified. At runtime, when a thread is created the initialized data must be provided. This data is provided in the sections identified with SHF\_TLS flag: - .tdata – Initialized TLS data - .tbss – Uninitialized data defined as COMMON symbols These combined sections form the TLS template that is used when a thread is created. Symbols associated with the TLS data are assigned type STT\_TLS. Their offset is relative to the beginning of the TLS template – this offset is used in the st\_value field of defined TLS symbols. The TLS template resides in a segment marked with PT\_TLS. ## Runtime allocation The TLS area is allocated in the following situations: - Whenever a thread is created (including the main executable thread) - Whenever the TLS area of a shared object is referenced for the first time after an executable was started When creating the TLS area for a thread (including the main executable thread), the runtime linker combines the TLS templates for all loaded shared objects – including the executable and shared libraries – into a single TLS template. This single TLS template is then used to initialize the TLS area allocated for each new thread. ## Load-time allocation When a shared object is loaded after process startup, and the object contains a TLS template, a TLS area might be allocated when the TLS data is first referenced. When a shared object is unloaded, the memory associated with its TLS template is freed (depending on the access method used – see [Thread-local storage access](https://docs.qualcomm.com/doc/80-N2040-23/topic/thread-local-storage.html#thread-local-storage-access) for details). ## Interface The TLS area is accessed at the processor level through the special register UGP ([Special registers](https://docs.qualcomm.com/doc/80-N2040-23/topic/process-initialization.html#special-registers)). This register is set to the address one location above the TLS area, which grows downwards from UGP. Depending on the TLS access method in use ([Thread-local storage access](https://docs.qualcomm.com/doc/80-N2040-23/topic/thread-local-storage.html#thread-local-storage-access)), different methods are used to locate the TLS area. The following (implementation-defined) function is assumed to be available: typedef struct { size_t ti_moduleid; ptrdiff_t ti_tlsoffset; } TLS_index; extern void \* tls_get_addr (TLS_index \*); Copy to clipboard This function returns a pointer to the address of the specified TLS data. ## Thread-local storage access The location of specific data items in an object’s TLS area is known at link time, and this information can be used to directly access the data. However, shared objects containing a TLS template can be loaded after process startup. In this case, more general methods are required for an executable object to access its TLS data. The following general methods can be used to access TLS data – they are listed here in order from the most general to the most restrictive (with the most restrictive methods also being the most efficient): - General dynamic (GD) - Local dynamic (LD) - Initial executable (IE) - Local executable (LE) Note Subject to the specified constraints, any of these methods can be used in a given shared object – the choice depends on which method is the most convenient to use in a specific instance. ### General dynamic (GD) In the GD method, TLS data can be referenced from either a shared object or an executable object. To obtain the address of a variable in the TLS area, the code must call the function tls\_get\_addr () with the address of a TLS\_index structure ([Interface](https://docs.qualcomm.com/doc/80-N2040-23/topic/thread-local-storage.html#interface)). Note In a shared object, the TLS template can be loaded only after process startup. Otherwise, the (standard ELF) dynamic tag DT\_FLAGS is set to the value DF\_STATIC\_TLS, which prevents the TLS data from being loaded after process startup. ### Local dynamic (LD) In the LD method, if a shared object contains TLS data that is protected or has local visibility, the location of the data in the TLS template is known at link time, and this location information can be used directly. To obtain the address of a variable in the TLS area, the code must first obtain the TLS base address by calling the function tls\_get\_addr () with the address of a TLS\_index structure ([Interface](https://docs.qualcomm.com/doc/80-N2040-23/topic/thread-local-storage.html#interface)) that has a ti\_tlsoffset member with a value of zero. The TLS variables can be accessed using the LD method through offsets from the obtained base address. Note In a shared object, the TLS template can be loaded only after process startup. Otherwise, the (standard ELF) dynamic tag DT\_FLAGS is set to the value DF\_STATIC\_TLS, which prevents the TLS data from being loaded after process startup. ### Initial executable (IE) In the IE method, an object can access TLS data only if it is part of the initial TLS template established at link time. When a shared object is loaded after process startup, its TLS data cannot be accessed using this method. To obtain the address of a variable in the TLS area, the dynamic linker creates a GOT entry to store the variable’s offset in the initial TLS area. Note When a shared object is loaded after process startup, its TLS data is not part of the initial TLS template. Therefore, if a shared object tries to use this method to access its TLS data, the access must be rejected. ### Local executable (LE) In the LE method, an object can access the TLS data of executable objects only. To obtain the address of a variable in the initial TLS area, simply use a static offset from the top of the initial TLS area (since the variable location is known at link time). Note If an object tries to use this method to access the TLS data of a non-executable object, the access must be rejected. Last Published: Oct 06, 2026 [Previous Topic Procedure linkage table](https://docs.qualcomm.com/bundle/publicresource/80-N2040-23/topics/dynamic-linking.md) [Next Topic Coding examples](https://docs.qualcomm.com/bundle/publicresource/80-N2040-23/topics/coding-examples.md)