RFC: x86-64 TLS ABI

Jakub Jelinek jakub at redhat.com
Thu Sep 19 20:27:36 CEST 2002


Hi!

Looking for comments about x86-64 TLS ABI.
You can look at (somewhat outdated) IA-32, IA-64, SPARC* and SH TLS ABIs
at http://people.redhat.com/drepper/tls.pdf (I hope Ulrich will put a newer
version there soon).

.long 0x66666666 and .word 0x6666; .byte 0x66 are there so that
the instructions occupy 11 resp. 12 bytes which is needed so
that transitions work properly. If you have ideas how it could be written
faster while occupying the same number of bytes, you're welcome.

Dynamic relocations:
#define R_X86_64_DTPMOD64	16	/* ID of module containing symbol */
#define R_X86_64_DTPOFF64	17	/* Offset in TLS block */
#define R_X86_64_TPOFF64	18	/* Offset in initial TLS block */

Link time relocations:
#define R_X86_64_TLSGD		19	/* PC relative offset to GD GOT block */
#define R_X86_64_TLSLD		20	/* PC relative offset to LD GOT block */
#define R_X86_64_DTPOFF32	21	/* Offset in TLS block */
#define R_X86_64_GOTTPOFF	22	/* PC relative offset to IE GOT entry */
#define R_X86_64_TPOFF32	23	/* Offset in initial TLS block */

GD model
00	.long 0x66666666
04	leaq foo at tlsgd(%rip), %rdi	R_X86_64_TLSGD
0b	callq __tls_get_addr at plt	R_X86_64_PLT32
10
(all above has to be contiguous)
		GOT[n]			R_X86_64_DTPMOD64
		GOT[n+1]		R_X86_64_DTPOFF64

(or .byte 0x66, 0x66, 0x66; nop; leaq foo...
 or .byte 0x66, 0x66, 0x66; leaq %gs:foo...
 whatever is fastest)

LD model
00	leaq foo at tlsldm(%rip), %rdi	R_X86_64_TLSLD
07	callq __tls_get_addr at plt	R_X86_64_PLT32
0c
(both insns have to be contiguous)
		GOT[n]			R_X86_64_DTPMOD64
		GOT[n+1]		0
...
x	leaq foo at dtpoff(%rax), %rX	R_X86_64_DTPOFF32
x+7
...
y	leaq bar at dtpoff(%rax), %rY	R_X86_64_DTPOFF32
y+7

IE model - address
00	movq %gs:0, %rX
09	addq foo at gottpoff(%rip), %rX	R_X86_64_GOTTPOFF
10
		GOT[n]			R_X86_64_TPOFF64

(
IE model - value
00	movq foo at gottpoff(%rip), %rX	R_X86_64_GOTTPOFF
07	movq %gs:0(%rX), %rY
0c
		GOT[n]			R_X86_64_TPOFF64
)

LE model - address
00	movq %gs:0, %rX
09	leaq foo at tpoff(%rX), %rY	R_X86_64_TPOFF32
10

(
LE model - value
00	movq %gs:foo at tpoff, %rX		R_X86_64_TPOFF32
09
)

Transitions:
GD->IE
00	.long 0x66666666
04	leaq foo at tlsgd(%rip), %rdi	R_X86_64_TLSGD
0b	callq __tls_get_addr at plt	R_X86_64_PLT32
10
	||
	\/
00	movq %gs:0, %rax
09	addq foo at gottpoff(%rip), %rax	R_X86_64_GOTTPOFF
10

GD->LE
00	.long 0x66666666
04	leaq foo at tlsgd(%rip), %rdi	R_X86_64_TLSGD
0b	callq __tls_get_addr at plt	R_X86_64_PLT32
10
	||
	\/
00	movq %gs:0, %rax
09	leaq foo at tpoff(%rax), %rax	R_X86_64_TPOFF32
10
( should this be movq %gs:0, %rfi; leaq foo at tpoff(%rdi), %rax? )

LD->LE
00	leaq foo at tlsldm(%rip), %rdi	R_X86_64_TLSLD
07	callq __tls_get_addr at plt	R_X86_64_PLT32
0c
...
x	leaq foo at dtpoff(%rax), %rX	R_X86_64_DTPOFF32
x+7
...
y	leaq bar at dtpoff(%rax), %rY	R_X86_64_DTPOFF32
y+7
	||
	\/
00	.word 0x6666; .byte 0x66
03	movq %gs:0, %rax
0c
...
x	leaq foo at tpoff(%rax), %rX	R_X86_64_TPOFF32
x+7
...
y	leaq bar at tpoff(%rax), %rY	R_X86_64_TPOFF32
y+7

IE->LE
00	movq %gs:0, %rX
09	addq foo at gottpoff(%rip), %rX	R_X86_64_GOTTPOFF
10
	||
	\/
00	movq %gs:0, %rX
09	leaq foo at tpoff(%rX), %rX	R_X86_64_TPOFF32
10

( IE->LE - value
00	movq foo at gottpoff(%rip), %rX	R_X86_64_GOTTPOFF
07	movq %gs:0(%rX), %rY
0c
	||
	\/
00	movq $foo at tpoff, %rX		R_X86_64_TPOFF32
07	movq %gs:0(%rX), %rY
0c
)

	Jakub



More information about the discuss mailing list