diff options
Diffstat (limited to 'man2/set_thread_area.2')
-rw-r--r-- | man2/set_thread_area.2 | 229 |
1 files changed, 229 insertions, 0 deletions
diff --git a/man2/set_thread_area.2 b/man2/set_thread_area.2 new file mode 100644 index 0000000..b982112 --- /dev/null +++ b/man2/set_thread_area.2 @@ -0,0 +1,229 @@ +.\" Copyright (C) 2003 Free Software Foundation, Inc. +.\" Copyright (C) 2015 Andrew Lutomirski +.\" Author: Kent Yoder +.\" +.\" SPDX-License-Identifier: GPL-1.0-or-later +.\" +.TH set_thread_area 2 2023-03-30 "Linux man-pages 6.05.01" +.SH NAME +get_thread_area, set_thread_area \- manipulate thread-local storage information +.SH LIBRARY +Standard C library +.RI ( libc ", " \-lc ) +.SH SYNOPSIS +.nf +.BR "#include <sys/syscall.h>" " /* Definition of " SYS_* " constants */" +.B #include <unistd.h> +.PP +.B #if defined __i386__ || defined __x86_64__ +.BR "# include <asm/ldt.h>" " /* Definition of " "struct user_desc" " */" +.PP +.BI "int syscall(SYS_get_thread_area, struct user_desc *" u_info ); +.BI "int syscall(SYS_set_thread_area, struct user_desc *" u_info ); +.PP +.B #elif defined __m68k__ +.PP +.B "int syscall(SYS_get_thread_area);" +.BI "int syscall(SYS_set_thread_area, unsigned long " tp ); +.PP +.B #elif defined __mips__ +.PP +.BI "int syscall(SYS_set_thread_area, unsigned long " addr ); +.PP +.B #endif +.fi +.PP +.IR Note : +glibc provides no wrappers for these system calls, +necessitating the use of +.BR syscall (2). +.SH DESCRIPTION +These calls provide architecture-specific support for a thread-local storage +implementation. +At the moment, +.BR set_thread_area () +is available on m68k, MIPS, and x86 (both 32-bit and 64-bit variants); +.BR get_thread_area () +is available on m68k and x86. +.PP +On m68k and MIPS, +.BR set_thread_area () +allows storing an arbitrary pointer (provided in the +.B tp +argument on m68k and in the +.B addr +argument on MIPS) +in the kernel data structure associated with the calling thread; +this pointer can later be retrieved using +.BR get_thread_area () +(see also NOTES +for information regarding obtaining the thread pointer on MIPS). +.PP +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. +.PP +Both of these system calls take an argument that is a pointer +to a structure of the following type: +.PP +.in +4n +.EX +struct user_desc { + unsigned int entry_number; + unsigned int base_addr; + unsigned int limit; + unsigned int seg_32bit:1; + unsigned int contents:2; + unsigned int read_exec_only:1; + unsigned int limit_in_pages:1; + unsigned int seg_not_present:1; + unsigned int useable:1; +#ifdef __x86_64__ + unsigned int lm:1; +#endif +}; +.EE +.in +.PP +.BR get_thread_area () +reads the GDT entry indicated by +.I u_info\->entry_number +and fills in the rest of the fields in +.IR u_info . +.PP +.BR set_thread_area () +sets a TLS entry in the GDT. +.PP +The TLS array entry set by +.BR set_thread_area () +corresponds to the value of +.I u_info\->entry_number +passed in by the user. +If this value is in bounds, +.BR set_thread_area () +writes the TLS descriptor pointed to by +.I u_info +into the thread's TLS array. +.PP +When +.BR set_thread_area () +is passed an +.I entry_number +of \-1, it searches for a free TLS entry. +If +.BR set_thread_area () +finds a free TLS entry, the value of +.I u_info\->entry_number +is set upon return to show which entry was changed. +.PP +A +.I user_desc +is considered "empty" if +.I read_exec_only +and +.I seg_not_present +are set to 1 and all of the other fields are 0. +If an "empty" descriptor is passed to +.BR set_thread_area (), +the corresponding TLS entry will be cleared. +See BUGS for additional details. +.PP +Since Linux 3.19, +.BR set_thread_area () +cannot be used to write non-present segments, 16-bit segments, or code +segments, although clearing a segment is still acceptable. +.SH RETURN VALUE +On x86, these system calls +return 0 on success, and \-1 on failure, with +.I errno +set to indicate the error. +.PP +On MIPS and m68k, +.BR set_thread_area () +always returns 0. +On m68k, +.BR get_thread_area () +returns the thread area pointer value +(previously set via +.BR set_thread_area ()). +.SH ERRORS +.TP +.B EFAULT +\fIu_info\fP is an invalid pointer. +.TP +.B EINVAL +\fIu_info\->entry_number\fP is out of bounds. +.TP +.B ENOSYS +.BR get_thread_area () +or +.BR set_thread_area () +was invoked as a 64-bit system call. +.TP +.B ESRCH +.RB ( set_thread_area ()) +A free TLS entry could not be located. +.SH STANDARDS +Linux. +.SH HISTORY +.TP +.BR set_thread_area () +Linux 2.5.29. +.TP +.BR get_thread_area () +Linux 2.5.32. +.SH NOTES +These system calls are generally intended for use only by threading libraries. +.PP +.BR arch_prctl (2) +can interfere with +.BR set_thread_area () +on x86. +See +.BR arch_prctl (2) +for more details. +This is not normally a problem, as +.BR arch_prctl (2) +is normally used only by 64-bit programs. +.PP +On MIPS, the current value of the thread area pointer can be obtained +using the instruction: +.PP +.in +4n +.EX +rdhwr dest, $29 +.EE +.in +.PP +This instruction traps and is handled by kernel. +.SH BUGS +On 64-bit kernels before Linux 3.19, +.\" commit e30ab185c490e9a9381385529e0fd32f0a399495 +one of the padding bits in +.IR user_desc , +if set, would prevent the descriptor from being considered empty (see +.BR modify_ldt (2)). +As a result, the only reliable way to clear a TLS entry is to use +.BR memset (3) +to zero the entire +.I user_desc +structure, including padding bits, and then to set the +.I read_exec_only +and +.I seg_not_present +bits. +On Linux 3.19, a +.I user_desc +consisting entirely of zeros except for +.I entry_number +will also be interpreted as a request to clear a TLS entry, but this +behaved differently on older kernels. +.PP +Prior to Linux 3.19, the DS and ES segment registers must not reference +TLS entries. +.SH SEE ALSO +.BR arch_prctl (2), +.BR modify_ldt (2), +.BR ptrace (2) +.RB ( PTRACE_GET_THREAD_AREA " and " PTRACE_SET_THREAD_AREA ) |