The Visual Studio linker supports thread local variables (for _declspec(thread)) by providing a section sorting mechanism. E.g. one can write the "segments" below and the linker will sort the segments starting with .tls based on the additional name fragments after the $ sign.
I'd like to get the relative offset of MyVariable (from the code below) wrt the .tls section as a constant, allowing me to write
; get pointer to thread local storage
mov rsi, [gs:abs 0x58] ; get pointer to thread local storage array
mov eax, [rel _tls_index] ; get module-specific index to thread local storage
mov rsi, [rsi+8*rax] ; get pointer to thread local offset
; determine offset
mov rcx, CONSTANT ; constant needed is relative offset of MyVariable wrt the beginning of the .tls section, (which starts at _tls_start in the example below)
; fetch value
mov rax, [rsi+rcx] ; or even better mov rax, [rsi+CONSTANT] avoiding the preceding mov instruction
Is there a way to do this in nasm, or is the only way to get the offset to compute the difference between the address of MyVariable and the address of _tls_start?
Segment declarations
; in separately assembled file needing MyVariable
segment .tls$RTS data align=8
; note: place thread local data in this section
; the linker sorts all .tls$... sections alphabetically, resulting in all data being placed between _tls_start and _tls_end
; each thread has a thread local copy of this data, initialized by the origin value
MyVariable: dq 1
; in separately assembled file specifying the tls directory used by the linker and the windows program/dll loader
segment .rdata
alignb 64, db 0
extern _tls_used
_tls_used:
istruc ImageTlsDirectoryStructure
at ImageTlsDirectoryStructure.StartAddressOfRawData, dq _tls_start
at ImageTlsDirectoryStructure.EndAddressOfRawData, dq _tls_end
at ImageTlsDirectoryStructure.AddressOfIndex, dq _tls_index
at ImageTlsDirectoryStructure.AddressOfCallBacks, dq _tls_callbacks
at ImageTlsDirectoryStructure.SizeOfZeroFill, dd 0
at ImageTlsDirectoryStructure.Characteristics, dd 0
iend
segment .tls$AAA data align=8
_tls_start:
dq 0
segment .tls$ZZZ data align=8
_tls_end:
dq 0