summaryrefslogtreecommitdiffstats
path: root/man/man2/modify_ldt.2
diff options
context:
space:
mode:
Diffstat (limited to 'man/man2/modify_ldt.2')
-rw-r--r--man/man2/modify_ldt.2196
1 files changed, 196 insertions, 0 deletions
diff --git a/man/man2/modify_ldt.2 b/man/man2/modify_ldt.2
new file mode 100644
index 0000000..faf87d9
--- /dev/null
+++ b/man/man2/modify_ldt.2
@@ -0,0 +1,196 @@
+.\" Copyright (c) 1995 Michael Chastain (mec@duracef.shout.net), 22 July 1995.
+.\" Copyright (c) 2015 Andrew Lutomirski
+.\"
+.\" SPDX-License-Identifier: GPL-2.0-or-later
+.\"
+.TH modify_ldt 2 2024-05-02 "Linux man-pages (unreleased)"
+.SH NAME
+modify_ldt \- get or set a per-process LDT entry
+.SH LIBRARY
+Standard C library
+.RI ( libc ", " \-lc )
+.SH SYNOPSIS
+.nf
+.BR "#include <asm/ldt.h>" " /* Definition of " "struct user_desc" " */"
+.BR "#include <sys/syscall.h>" " /* Definition of " SYS_* " constants */"
+.B #include <unistd.h>
+.P
+.BI "int syscall(SYS_modify_ldt, int " func ", void " ptr [. bytecount ],
+.BI " unsigned long " bytecount );
+.fi
+.P
+.IR Note :
+glibc provides no wrapper for
+.BR modify_ldt (),
+necessitating the use of
+.BR syscall (2).
+.SH DESCRIPTION
+.BR modify_ldt ()
+reads or writes the local descriptor table (LDT) for a process.
+The LDT
+is an array of segment descriptors that can be referenced by user code.
+Linux allows processes to configure a per-process (actually per-mm) LDT.
+For more information about the LDT, see the Intel Software Developer's
+Manual or the AMD Architecture Programming Manual.
+.P
+When
+.I func
+is 0,
+.BR modify_ldt ()
+reads the LDT into the memory pointed to by
+.IR ptr .
+The number of bytes read is the smaller of
+.I bytecount
+and the actual size of the LDT, although the kernel may act as though
+the LDT is padded with additional trailing zero bytes.
+On success,
+.BR modify_ldt ()
+will return the number of bytes read.
+.P
+When
+.I func
+is 1 or 0x11,
+.BR modify_ldt ()
+modifies the LDT entry indicated by
+.IR ptr\->entry_number .
+.I ptr
+points to a
+.I user_desc
+structure
+and
+.I bytecount
+must equal the size of this structure.
+.P
+The
+.I user_desc
+structure is defined in \fI<asm/ldt.h>\fP as:
+.P
+.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;
+};
+.EE
+.in
+.P
+In Linux 2.4 and earlier, this structure was named
+.IR modify_ldt_ldt_s .
+.P
+The
+.I contents
+field is the segment type (data, expand-down data, non-conforming code, or
+conforming code).
+The other fields match their descriptions in the CPU manual, although
+.BR modify_ldt ()
+cannot set the hardware-defined "accessed" bit described in the CPU manual.
+.P
+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.
+An LDT entry can be cleared by setting it to an "empty"
+.I user_desc
+or, if
+.I func
+is 1, by setting both
+.I base
+and
+.I limit
+to 0.
+.P
+A conforming code segment (i.e., one with
+.IR contents==3 )
+will be rejected if
+.I
+func
+is 1 or if
+.I seg_not_present
+is 0.
+.P
+When
+.I func
+is 2,
+.BR modify_ldt ()
+will read zeros.
+This appears to be a leftover from Linux 2.4.
+.SH RETURN VALUE
+On success,
+.BR modify_ldt ()
+returns either the actual number of bytes read (for reading)
+or 0 (for writing).
+On failure,
+.BR modify_ldt ()
+returns \-1 and sets
+.I errno
+to indicate the error.
+.SH ERRORS
+.TP
+.B EFAULT
+.I ptr
+points outside the address space.
+.TP
+.B EINVAL
+.I ptr
+is 0,
+or
+.I func
+is 1 and
+.I bytecount
+is not equal to the size of the structure
+.IR user_desc ,
+or
+.I func
+is 1 or 0x11 and the new LDT entry has invalid values.
+.TP
+.B ENOSYS
+.I func
+is neither 0, 1, 2, nor 0x11.
+.SH STANDARDS
+Linux.
+.SH NOTES
+.BR modify_ldt ()
+should not be used for thread-local storage, as it slows down context
+switches and only supports a limited number of threads.
+Threading libraries should use
+.BR set_thread_area (2)
+or
+.BR arch_prctl (2)
+instead, except on extremely old kernels that do not support those system
+calls.
+.P
+The normal use for
+.BR modify_ldt ()
+is to run legacy 16-bit or segmented 32-bit code.
+Not all kernels allow 16-bit segments to be installed, however.
+.P
+Even on 64-bit kernels,
+.BR modify_ldt ()
+cannot be used to create a long mode (i.e., 64-bit) code segment.
+The undocumented field "lm" in
+.I user_desc
+is not useful, and, despite its name,
+does not result in a long mode segment.
+.SH BUGS
+On 64-bit kernels before Linux 3.19,
+.\" commit e30ab185c490e9a9381385529e0fd32f0a399495
+setting the "lm" bit in
+.I user_desc
+prevents the descriptor from being considered empty.
+Keep in mind that the
+"lm" bit does not exist in the 32-bit headers, but these buggy kernels
+will still notice the bit even when set in a 32-bit process.
+.SH SEE ALSO
+.BR arch_prctl (2),
+.BR set_thread_area (2),
+.BR vm86 (2)