Skip to content

Commit ebf732f

Browse files
committed
Update comments
1 parent eba86d5 commit ebf732f

File tree

1 file changed

+40
-3
lines changed

1 file changed

+40
-3
lines changed

elf/tls.cc

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,18 +70,55 @@
7070
// compiled to a function call! The module ID and the offset are
7171
// usually stored to GOT as two consecutive words.
7272
//
73-
// The last access method provides the most generic, so the compiler emits
74-
// such code by default. But that's the most expensive one, so the linker
73+
// The last access method is the most generic, so the compiler emits such
74+
// code by default. But that's the most expensive one, so the linker
7575
// rewrites instructions if possible so that 3) is relaxed to 2) or even
7676
// to 1).
7777
//
78+
// 1) is often called the Local Exec access model. 2) is Initial Exec, and
79+
// 3) is called General Dynamic.
80+
//
7881
// There's also a trick that the compiler can use if it knows two TLVs are
7982
// in the same ELF file (usually in the same file as the code is). In this
8083
// case, we can call __tls_get_addr() only once with a module ID and the
8184
// offset 0 to obtain the base address of the ELF file's TLS block.
8285
// The base address obtained this way is sometimes called Dynamic Thread
8386
// Pointer or DTP. We can then compute TLVs' addresses by adding their
84-
// DTP-relative addresses to DTP.
87+
// DTP-relative addresses to DTP. This access model is called the Local
88+
// Dynamic.
89+
//
90+
//
91+
// === TLS Descriptor access model ===
92+
//
93+
// As described above, there are arguably too many different TLS access
94+
// models from the most generic one you can use in any ELF file to the
95+
// most efficient one you can use only in the main executable. Compiling
96+
// source code with an appropriate TLS access model is bothersome.
97+
// To solve the problem, a new TLS access model was proposed. That is
98+
// called the TLS Descriptor (TLSDESC) model.
99+
//
100+
// For a TLV compiled with TLSDESC, we allocate two consecutive GOT slots
101+
// and create a TLSDESC dynamic relocation for them. The dynamic linker
102+
// sets a function pointer to the first GOT slot and its argument to the
103+
// second slot.
104+
//
105+
// To access the TLV, we call the function pointer with the argument we
106+
// read from the second GOT slot. The function returns the TLV's
107+
// TP-relative address.
108+
//
109+
// The runtime chooses the best access method depending on the situation
110+
// and sets a pointer to the most efficient code to the first GOT slot.
111+
// For example, if a TLV's TP-relative address is known at process startup
112+
// time, the runtime sets that address to the second GOT slot and set a
113+
// function that just returns its argument to the first GOT slot.
114+
//
115+
// With TLSDECS, the compiler can always emit the same code for TLVs
116+
// without sacrificing runtime performance.
117+
//
118+
// TLSDESC is better than the traditional, non-TLSDESC TLS access models.
119+
// It's the default on ARM64, but on other targets, TLSDESC is
120+
// unfortunately either optional or even not supported at all. So we still
121+
// need to support both the traditional TLS models and the TLSDESC model.
85122

86123
#include "mold.h"
87124

0 commit comments

Comments
 (0)