-
Notifications
You must be signed in to change notification settings - Fork 0
/
get_thread_area.html
334 lines (248 loc) · 9.49 KB
/
get_thread_area.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
<!-- Creator : groff version 1.22.4 -->
<!-- CreationDate: Wed Jan 29 11:26:19 2020 -->
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta name="generator" content="groff -Thtml, see www.gnu.org">
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<meta name="Content-Style" content="text/css">
<style type="text/css">
p { margin-top: 0; margin-bottom: 0; vertical-align: top }
pre { margin-top: 0; margin-bottom: 0; vertical-align: top }
table { margin-top: 0; margin-bottom: 0; vertical-align: top }
h1 { text-align: center }
</style>
<title>SET_THREAD_AREA</title>
</head>
<body>
<h1 align="center">SET_THREAD_AREA</h1>
<a href="#NAME">NAME</a><br>
<a href="#SYNOPSIS">SYNOPSIS</a><br>
<a href="#DESCRIPTION">DESCRIPTION</a><br>
<a href="#RETURN VALUE">RETURN VALUE</a><br>
<a href="#ERRORS">ERRORS</a><br>
<a href="#VERSIONS">VERSIONS</a><br>
<a href="#CONFORMING TO">CONFORMING TO</a><br>
<a href="#NOTES">NOTES</a><br>
<a href="#BUGS">BUGS</a><br>
<a href="#SEE ALSO">SEE ALSO</a><br>
<a href="#COLOPHON">COLOPHON</a><br>
<hr>
<h2>NAME
<a name="NAME"></a>
</h2>
<p style="margin-left:11%; margin-top: 1em">get_thread_area,
set_thread_area - manipulate thread-local storage
information</p>
<h2>SYNOPSIS
<a name="SYNOPSIS"></a>
</h2>
<p style="margin-left:11%; margin-top: 1em"><b>#include
<linux/unistd.h></b></p>
<p style="margin-left:11%; margin-top: 1em"><b>#if defined
__i386__ || defined __x86_64__ <br>
# include <asm/ldt.h></b></p>
<p style="margin-left:11%; margin-top: 1em"><b>int
get_thread_area(struct user_desc *</b><i>u_info</i><b>);
<br>
int set_thread_area(struct user_desc
*</b><i>u_info</i><b>);</b></p>
<p style="margin-left:11%; margin-top: 1em"><b>#elif
defined __m68k__</b></p>
<p style="margin-left:11%; margin-top: 1em"><b>int
get_thread_area(void); <br>
int set_thread_area(unsigned long</b> <i>tp</i><b>);</b></p>
<p style="margin-left:11%; margin-top: 1em"><b>#elif
defined __mips__</b></p>
<p style="margin-left:11%; margin-top: 1em"><b>int
set_thread_area(unsigned long</b> <i>addr</i><b>);</b></p>
<p style="margin-left:11%; margin-top: 1em"><b>#endif</b></p>
<p style="margin-left:11%; margin-top: 1em"><i>Note</i>:
There are no glibc wrappers for these system calls; see
NOTES.</p>
<h2>DESCRIPTION
<a name="DESCRIPTION"></a>
</h2>
<p style="margin-left:11%; margin-top: 1em">These calls
provide architecture-specific support for a thread-local
storage implementation. At the moment,
<b>set_thread_area</b>() is available on m68k, MIPS, and x86
(both 32-bit and 64-bit variants); <b>get_thread_area</b>()
is available on m68k and x86.</p>
<p style="margin-left:11%; margin-top: 1em">On m68k and
MIPS, <b>set_thread_area</b>() allows storing an arbitrary
pointer (provided in the <b>tp</b> argument on m68k and in
the <b>addr</b> argument on MIPS) in the kernel data
structure associated with the calling thread; this pointer
can later be retrieved using <b>get_thread_area</b>() (see
also NOTES for information regarding obtaining the thread
pointer on MIPS).</p>
<p style="margin-left:11%; margin-top: 1em">On x86, Linux
dedicates three global descriptor table (GDT) entries for
thread-local storage. For more information about the GDT,
see the Intel Software Developer’s Manual or the AMD
Architecture Programming Manual.</p>
<p style="margin-left:11%; margin-top: 1em">Both of these
system calls take an argument that is a pointer to a
structure of the following type:</p>
<p style="margin-left:17%; margin-top: 1em">struct
user_desc { <br>
unsigned int entry_number; <br>
unsigned long base_addr; <br>
unsigned int limit; <br>
unsigned int seg_32bit:1; <br>
unsigned int contents:2; <br>
unsigned int read_exec_only:1; <br>
unsigned int limit_in_pages:1; <br>
unsigned int seg_not_present:1; <br>
unsigned int useable:1; <br>
#ifdef __x86_64__ <br>
unsigned int lm:1; <br>
#endif <br>
};</p>
<p style="margin-left:11%; margin-top: 1em"><b>get_thread_area</b>()
reads the GDT entry indicated by
<i>u_info->entry_number</i> and fills in the rest of the
fields in <i>u_info</i>.</p>
<p style="margin-left:11%; margin-top: 1em"><b>set_thread_area</b>()
sets a TLS entry in the GDT.</p>
<p style="margin-left:11%; margin-top: 1em">The TLS array
entry set by <b>set_thread_area</b>() corresponds to the
value of <i>u_info->entry_number</i> passed in by the
user. If this value is in bounds, <b>set_thread_area</b>()
writes the TLS descriptor pointed to by <i>u_info</i> into
the thread’s TLS array.</p>
<p style="margin-left:11%; margin-top: 1em">When
<b>set_thread_area</b>() is passed an <i>entry_number</i> of
-1, it searches for a free TLS entry. If
<b>set_thread_area</b>() finds a free TLS entry, the value
of <i>u_info->entry_number</i> is set upon return to show
which entry was changed.</p>
<p style="margin-left:11%; margin-top: 1em">A
<i>user_desc</i> is considered "empty" if
<i>read_exec_only</i> and <i>seg_not_present</i> are set to
1 and all of the other fields are 0. If an "empty"
descriptor is passed to <b>set_thread_area</b>(), the
corresponding TLS entry will be cleared. See BUGS for
additional details.</p>
<p style="margin-left:11%; margin-top: 1em">Since Linux
3.19, <b>set_thread_area</b>() cannot be used to write
non-present segments, 16-bit segments, or code segments,
although clearing a segment is still acceptable.</p>
<h2>RETURN VALUE
<a name="RETURN VALUE"></a>
</h2>
<p style="margin-left:11%; margin-top: 1em">On x86, these
system calls return 0 on success, and -1 on failure, with
<i>errno</i> set appropriately.</p>
<p style="margin-left:11%; margin-top: 1em">On MIPS and
m68k, <b>set_thread_area</b>() always returns 0. On m68k,
<b>get_thread_area</b>() returns the thread area pointer
value (previously set via <b>set_thread_area</b>()).</p>
<h2>ERRORS
<a name="ERRORS"></a>
</h2>
<table width="100%" border="0" rules="none" frame="void"
cellspacing="0" cellpadding="0">
<tr valign="top" align="left">
<td width="11%"></td>
<td width="9%">
<p style="margin-top: 1em"><b>EFAULT</b></p></td>
<td width="2%"></td>
<td width="78%">
<p style="margin-top: 1em"><i>u_info</i> is an invalid
pointer.</p> </td></tr>
<tr valign="top" align="left">
<td width="11%"></td>
<td width="9%">
<p><b>EINVAL</b></p></td>
<td width="2%"></td>
<td width="78%">
<p><i>u_info->entry_number</i> is out of bounds.</p></td></tr>
<tr valign="top" align="left">
<td width="11%"></td>
<td width="9%">
<p><b>ENOSYS</b></p></td>
<td width="2%"></td>
<td width="78%">
<p><b>get_thread_area</b>() or <b>set_thread_area</b>() was
invoked as a 64-bit system call.</p></td></tr>
<tr valign="top" align="left">
<td width="11%"></td>
<td width="9%">
<p><b>ESRCH</b></p></td>
<td width="2%"></td>
<td width="78%">
<p>(<b>set_thread_area</b>()) A free TLS entry could not be
located.</p> </td></tr>
</table>
<h2>VERSIONS
<a name="VERSIONS"></a>
</h2>
<p style="margin-left:11%; margin-top: 1em"><b>set_thread_area</b>()
first appeared in Linux 2.5.29. <b>get_thread_area</b>()
first appeared in Linux 2.5.32.</p>
<h2>CONFORMING TO
<a name="CONFORMING TO"></a>
</h2>
<p style="margin-left:11%; margin-top: 1em"><b>set_thread_area</b>()
and <b>get_thread_area</b>() are Linux-specific and should
not be used in programs that are intended to be
portable.</p>
<h2>NOTES
<a name="NOTES"></a>
</h2>
<p style="margin-left:11%; margin-top: 1em">Glibc does not
provide wrappers for these system calls, since they are
generally intended for use only by threading libraries. In
the unlikely event that you want to call them directly, use
<b>syscall</b>(2).</p>
<p style="margin-left:11%; margin-top: 1em"><b>arch_prctl</b>(2)
can interfere with <b>set_thread_area</b>() on x86. See
<b>arch_prctl</b>(2) for more details. This is not normally
a problem, as <b>arch_prctl</b>(2) is normally used only by
64-bit programs.</p>
<p style="margin-left:11%; margin-top: 1em">On MIPS, the
current value of the thread area pointer can be obtained
using the instruction:</p>
<p style="margin-left:17%; margin-top: 1em">rdhwr dest,
$29</p>
<p style="margin-left:11%; margin-top: 1em">This
instruction traps and is handled by kernel.</p>
<h2>BUGS
<a name="BUGS"></a>
</h2>
<p style="margin-left:11%; margin-top: 1em">On 64-bit
kernels before Linux 3.19, one of the padding bits in
<i>user_desc</i>, if set, would prevent the descriptor from
being considered empty (see <b>modify_ldt</b>(2)). As a
result, the only reliable way to clear a TLS entry is to use
<b>memset</b>(3) to zero the entire <i>user_desc</i>
structure, including padding bits, and then to set the
<i>read_exec_only</i> and <i>seg_not_present</i> bits. On
Linux 3.19, a <i>user_desc</i> consisting entirely of zeros
except for <i>entry_number</i> will also be interpreted as a
request to clear a TLS entry, but this behaved differently
on older kernels.</p>
<p style="margin-left:11%; margin-top: 1em">Prior to Linux
3.19, the DS and ES segment registers must not reference TLS
entries.</p>
<h2>SEE ALSO
<a name="SEE ALSO"></a>
</h2>
<p style="margin-left:11%; margin-top: 1em"><b>arch_prctl</b>(2),
<b>modify_ldt</b>(2), <b>ptrace</b>(2)
(<b>PTRACE_GET_THREAD_AREA</b> and
<b>PTRACE_SET_THREAD_AREA</b>)</p>
<h2>COLOPHON
<a name="COLOPHON"></a>
</h2>
<p style="margin-left:11%; margin-top: 1em">This page is
part of release 5.02 of the Linux <i>man-pages</i> project.
A description of the project, information about reporting
bugs, and the latest version of this page, can be found at
https://www.kernel.org/doc/man-pages/.</p>
<hr>
</body>
</html>