more on TLS
Richard Henderson
rth@twiddle.net
Tue Feb 5 18:51:00 GMT 2002
On Mon, Feb 04, 2002 at 05:43:44PM -0800, Ulrich Drepper wrote:
> In case somebody is thinking about implementing the TLS stuff for
> anything but x86. I suggest to wait (read it as: I'll not integrate
> any changes for other archs yet). The design is still in flux. I
> know the differences between the ABIs for the different architectures
> and integrate appropriate configury.
I noticed a few inconsistancies (perhaps just typos) in the
existing document. I'll comment on them later. For now,
here's what I've come up with for Alpha. Comments appreciated.
r~
New relocs:
#define R_ALPHA_TLS_GD_HI 28
#define R_ALPHA_TLS_GD_LO 29
#define R_ALPHA_TLS_GD_16 30
#define R_ALPHA_TLS_LDM_HI 31
#define R_ALPHA_TLS_LDM_LO 32
#define R_ALPHA_TLS_LDM_16 33
#define R_ALPHA_TLS_LDO_HI 34
#define R_ALPHA_TLS_LDO_LO 35
#define R_ALPHA_TLS_LDO_16 36
#define R_ALPHA_TLS_IE_HI 37
#define R_ALPHA_TLS_IE_LO 38
#define R_ALPHA_TLS_IE_16 39
#define R_ALPHA_TLS_LE_HI 40
#define R_ALPHA_TLS_LE_LO 41
#define R_ALPHA_TLS_LE_16 42
#define R_ALPHA_DTPMOD32 43
#define R_ALPHA_DTPOFF32 44
#define R_ALPHA_TPOFF32 45
#define LITUSE_TLS_GD 4
#define LITUSE_TLS_LDM 5
Sequences:
GD32
ldah $16,x($gp) !tls_gd_hi
lda $16,x($16) !tls_gd_lo
ldq $27,__tls_get_addr($gp) !literal!1
jsr $26,($27),__tls_get_addr !lituse_tls_gd(x)!1
GD16
lda $16,x($16) !tls_gd_16
ldq $27,__tls_get_addr($gp) !literal!1
jsr $26,($27),__tls_get_addr !lituse_tls_gd(x)!1
LD32
ldah $16,0($gp) !tls_ldm_hi
lda $16,0($16) !tls_ldm_lo
ldq $27,__tls_get_addr($gp) !literal!1
jsr $26,($27),__tls_get_addr !lituse_tls_ldm!1
...
ldah $1,x($0) !tls_ldo_hi
lda $1,x($1) !tls_ldo_lo
LD16
lda $16,0($gp) !tls_ldm_16
ldq $27,__tls_get_addr($gp) !literal!1
jsr $26,($27),__tls_get_addr !lituse_tls_ldm!1
...
lda $1,x($0) !tls_ldo_16
IE32
ldah $1,x($gp) !tls_ie_hi
ldl $1,x($1) !tls_ie_lo
addq $tp,$1,$0
IE16
ldl $1,x($gp) !tls_ie_16
addq $tp,$1,$0
LE32
ldah $1,x($tp) !tls_le_hi
lda $1,x($1) !tls_le_lo
LE16
lda $1,x($tp) !tls_le_16
Relaxations:
literal+lituse_tls_gd(x) -> no relocs
ldq -> call_pal rduniq
jsr -> addq $16,$0,$0
tls_gd_hi -> tls_ie_hi
tls_gd_lo -> tls_ie_lo
lda -> ldl
tls_gd_16 -> tls_ie_16
lda -> ldl
tls_gd_hi -> tls_le_hi
tls_gd_lo -> tls_le_lo
literal+lituse_tls_ldm -> no relocs
ldq -> call_pal rduniq
jsr -> addq $16,$0,$0
tls_ldm_hi -> tls_le_hi vs .tdata
tls_ldm_lo -> tls_le_lo vs .tdata
tls_ie_hi -> tls_le_hi
tls_ie_lo -> tls_le_lo
ldl -> lda
Effects of Relaxations:
GD32/IE32
ldah $16,x($gp) !tls_ie_hi
ldl $16,x($16) !tls_ie_lo
call_pal rduniq
addq $16,$0,$0
GD16/IE16
ldl $16,x($gp) !tls_ie_16
call_pal rduniq
addq $16,$0,$0
GD32/LE32
ldah $16,x !tls_le_hi
lda $16,x($16) !tls_le_lo
call_pal rduniq
addq $16,$0,$0
IE32/LE32
ldah $1,x !tls_le_hi
lda $1,x($1) !tls_le_lo
addq $tp,$1,$0
LD32/LE32
ldah $16,.tdata !tls_le_hi
ldah $16,.tdata($16) !tls_le_lo
call_pal rduniq
addq $16,$0,$0
...
ldah $1,x($0) !tls_ldo_hi
lda $1,x($1) !tls_ldo_lo
Special Notes:
GD16, LD16, IE16 refer to 16-bit offsets from the GOT,
such as one finds with -fpic vs -fPIC.
LE16 refers to a 16-bit offset from the TP. Thus certain
relaxations from GD/LD/IE16 to LE cannot occur unless the
tls offset for the symbol is small enough. LE16 should be
usable directly via a compiler option.
The $tp register referred to in the IE and LE sequences
is some register in which the compiler has saved the thread
pointer that it acquired from "call_pal rduniq".
The TLS_LDM relocs do not reference their symbol.
The __tls_get_addr function preserves the $gp register.
Literals with lituse_tls_gd or lituse_tls_ldm uses cannot
be combined with other lituses.
Unlike other lituses, the symbol associated with lituse_tls_gd
is meaningful.
Relaxations are done strictly via reloations, thus the
above sequences can be arbitrarily re-ordered. With the
exception that the literal for one of the lituse_tls relocs
must be considered to set $0, not just $27.
Threads are limited to 2GB local storage. This is due to
the maximum displacement available in the ldah+lda insns
for LE32. Note that the IE form takes advantage of this
by storing the tlsoffset in a 32-bit slot, not a 64-bit slot.
The tls_index struct should also have 32-bit components to
save space.
More information about the Libc-hacker
mailing list