]> git.ipfire.org Git - thirdparty/man-pages.git/blobdiff - man2/modify_ldt.2
sched_setattr.2: Minor tweaks to Claudio Scordino's patch
[thirdparty/man-pages.git] / man2 / modify_ldt.2
index 7b1f73c38d4608af6399370cd964ad9f6135e305..0db6efea47ad9e417fb2badb8a2f71d6cfd3f3bb 100644 (file)
@@ -1,7 +1,7 @@
-.\" Hey Emacs! This file is -*- nroff -*- source.
-.\"
 .\" Copyright (c) 1995 Michael Chastain (mec@duracef.shout.net), 22 July 1995.
+.\" Copyright (c) 2015 Andrew Lutomirski
 .\"
+.\" %%%LICENSE_START(GPLv2+_DOC_FULL)
 .\" This is free documentation; you can redistribute it and/or
 .\" modify it under the terms of the GNU General Public License as
 .\" published by the Free Software Foundation; either version 2 of
 .\" GNU General Public License for more details.
 .\"
 .\" You should have received a copy of the GNU General Public
-.\" License along with this manual; if not, write to the Free
-.\" Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111,
-.\" USA.
+.\" License along with this manual; if not, see
+.\" <http://www.gnu.org/licenses/>.
+.\" %%%LICENSE_END
 .\"
-.TH MODIFY_LDT 2 1995-07-22 "Linux 1.3.6" "Linux Programmer's Manual"
+.TH MODIFY_LDT 2 2017-09-15 "Linux" "Linux Programmer's Manual"
 .SH NAME
-modify_ldt \- get or set ldt
+modify_ldt \- get or set a per-process LDT entry
 .SH SYNOPSIS
 .nf
 .B #include <sys/types.h>
-.br
-.B #include <linux/unistd.h>
-.br
-.B #include <errno.h>
-.sp
-.BI "_syscall3(int, modify_ldt, int, " func ", void *, " ptr , 
-.BI "          unsigned long, " bytecount )
-          /* Using \fBsyscall\fP(2) may be preferable; see \fBintro\fP(2) */
-.sp
-.BI "int modify_ldt(int " "func" ", void *" "ptr" ", unsigned long " "bytecount" );
+.PP
+.BI "int modify_ldt(int " func ", void *" ptr ", unsigned long " bytecount );
 .fi
+.PP
+.IR Note :
+There is no glibc wrapper for this system call; see NOTES.
 .SH DESCRIPTION
 .BR modify_ldt ()
-reads or writes the local descriptor table (ldt) for a process.
-The ldt is a per-process memory management table used by the i386 processor.
-For more information on this table, see an Intel 386 processor handbook.
+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.
 .PP
 When
 .I func
 is 0,
 .BR modify_ldt ()
-reads the ldt into the memory pointed to by
+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.
+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.
 .PP
 When
 .I func
-is 1,
+is 1 or 0x11,
 .BR modify_ldt ()
-modifies one ldt entry.
+modifies the LDT entry indicated by
+.IR ptr\->entry_number .
 .I ptr
 points to a
-.I modify_ldt_ldt_s
-structure and
+.I user_desc
+structure
+and
 .I bytecount
 must equal the size of this structure.
-.\" .PP
-.\" The ldt is specific for the calling process. Any attempts to change
-.\" the ldt to include the address space of another process or the kernel
-.\" will result in a segmentation violation when trying to access the memory
-.\" outside of the process address space. The memory protection is enforced
-.\" at the paging layer.
-.SH "RETURN VALUE"
+.PP
+The
+.I user_desc
+structure is defined in \fI<asm/ldt.h>\fP as:
+.PP
+.in +4n
+.EX
+struct user_desc {
+    unsigned int  entry_number;
+    unsigned long 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
+.PP
+In Linux 2.4 and earlier, this structure was named
+.IR modify_ldt_ldt_s .
+.PP
+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.
+.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.
+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.
+.PP
+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.
+.PP
+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)
@@ -80,7 +142,8 @@ or 0 (for writing).
 On failure,
 .BR modify_ldt ()
 returns \-1 and sets
-.IR errno .
+.I errno
+to indicate the error.
 .SH ERRORS
 .TP
 .B EFAULT
@@ -95,16 +158,53 @@ or
 is 1 and
 .I bytecount
 is not equal to the size of the structure
-.IR modify_ldt_ldt_s ,
+.IR user_desc ,
 or
 .I func
-is 1 and the new ldt entry has invalid values.
+is 1 or 0x11 and the new LDT entry has invalid values.
 .TP
 .B ENOSYS
 .I func
-is neither 0 nor 1.
-.SH "CONFORMING TO"
+is neither 0, 1, 2, nor 0x11.
+.SH CONFORMING TO
 This call is Linux-specific and should not be used in programs intended
 to be portable.
-.SH "SEE ALSO"
+.SH NOTES
+Glibc does not provide a wrapper for this system call; call it using
+.BR syscall (2).
+.PP
+.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.
+.PP
+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.
+.PP
+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
+.IR 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
+.IR 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)