mirror of https://github.com/mkerrisk/man-pages
modify_ldt.2: Overhaul the documentation
This clarifies the behavior and documents all four functions. Signed-off-by: Andy Lutomirski <luto@amacapital.net> Signed-off-by: Michael Kerrisk <mtk.manpages@gmail.com>
This commit is contained in:
parent
97c0185b99
commit
38f7c37983
|
@ -1,4 +1,5 @@
|
||||||
.\" Copyright (c) 1995 Michael Chastain (mec@duracef.shout.net), 22 July 1995.
|
.\" Copyright (c) 1995 Michael Chastain (mec@duracef.shout.net), 22 July 1995.
|
||||||
|
.\" Copyright (c) 2015 Andrew Lutomirski
|
||||||
.\"
|
.\"
|
||||||
.\" %%%LICENSE_START(GPLv2+_DOC_FULL)
|
.\" %%%LICENSE_START(GPLv2+_DOC_FULL)
|
||||||
.\" This is free documentation; you can redistribute it and/or
|
.\" This is free documentation; you can redistribute it and/or
|
||||||
|
@ -23,37 +24,43 @@
|
||||||
.\"
|
.\"
|
||||||
.TH MODIFY_LDT 2 2012-07-13 "Linux" "Linux Programmer's Manual"
|
.TH MODIFY_LDT 2 2012-07-13 "Linux" "Linux Programmer's Manual"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
modify_ldt \- get or set ldt
|
modify_ldt \- get or set a per-process LDT entry
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.nf
|
.nf
|
||||||
.B #include <sys/types.h>
|
.B #include <sys/types.h>
|
||||||
.sp
|
.sp
|
||||||
.BI "int modify_ldt(int " "func" ", void *" "ptr" ", unsigned long " "bytecount" );
|
.BI "int modify_ldt(int " "func" ", void *" "ptr" ", unsigned long " "bytecount" );
|
||||||
.fi
|
.fi
|
||||||
|
.PP
|
||||||
.IR Note :
|
.IR Note :
|
||||||
There is no glibc wrapper for this system call; see NOTES.
|
There is no glibc wrapper for this system call; see NOTES.
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
.BR modify_ldt ()
|
.BR modify_ldt ()
|
||||||
reads or writes the local descriptor table (ldt) for a process.
|
reads or writes the local descriptor table (LDT) for a process. The LDT
|
||||||
The ldt is a per-process memory management table used by the i386 processor.
|
is an array of segment descriptors that can be referenced by user code.
|
||||||
For more information on this table, see an Intel 386 processor handbook.
|
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
|
.PP
|
||||||
When
|
When
|
||||||
.I func
|
.I func
|
||||||
is 0,
|
is 0,
|
||||||
.BR modify_ldt ()
|
.BR modify_ldt ()
|
||||||
reads the ldt into the memory pointed to by
|
reads the LDT into the memory pointed to by
|
||||||
.IR ptr .
|
.IR ptr .
|
||||||
The number of bytes read is the smaller of
|
The number of bytes read is the smaller of
|
||||||
.I bytecount
|
.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
|
.PP
|
||||||
When
|
When
|
||||||
.I func
|
.I func
|
||||||
is 1,
|
is 1 or 0x11,
|
||||||
.BR modify_ldt ()
|
.BR modify_ldt ()
|
||||||
modifies one ldt entry.
|
modifies the LDT entry indicated by
|
||||||
|
.I ptr\->entry_number.
|
||||||
.I ptr
|
.I ptr
|
||||||
points to a
|
points to a
|
||||||
.I user_desc
|
.I user_desc
|
||||||
|
@ -61,11 +68,6 @@ structure
|
||||||
and
|
and
|
||||||
.I bytecount
|
.I bytecount
|
||||||
must equal the size of this structure.
|
must equal the size of this structure.
|
||||||
.\"
|
|
||||||
.\" FIXME Should this page say something about func == 2 and func == 0x11?
|
|
||||||
.\" In Linux 2.4, func == 2 returned "the default ldt"
|
|
||||||
.\" In Linux 2.6, func == 2 is a nop, returning a zeroed out structure.
|
|
||||||
.\" Linux 2.4 and 2.6 implement an operation for func == 0x11
|
|
||||||
|
|
||||||
The
|
The
|
||||||
.I user_desc
|
.I user_desc
|
||||||
|
@ -89,12 +91,44 @@ struct user_desc {
|
||||||
.PP
|
.PP
|
||||||
In Linux 2.4 and earlier, this structure was named
|
In Linux 2.4 and earlier, this structure was named
|
||||||
.IR modify_ldt_ldt_s .
|
.IR modify_ldt_ldt_s .
|
||||||
.\" .PP
|
.PP
|
||||||
.\" The ldt is specific for the calling process. Any attempts to change
|
The
|
||||||
.\" the ldt to include the address space of another process or the kernel
|
.I contents
|
||||||
.\" will result in a segmentation violation when trying to access the memory
|
field is the segment type (data, expand-down data, non-conforming code, or
|
||||||
.\" outside of the process address space. The memory protection is enforced
|
conforming code). The other fields match their descriptions in the
|
||||||
.\" at the paging layer.
|
CPU manual, although
|
||||||
|
.BR modify_ldt ()
|
||||||
|
cannot set the accessed bit.
|
||||||
|
.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 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
|
.SH RETURN VALUE
|
||||||
On success,
|
On success,
|
||||||
.BR modify_ldt ()
|
.BR modify_ldt ()
|
||||||
|
@ -119,19 +153,40 @@ or
|
||||||
is 1 and
|
is 1 and
|
||||||
.I bytecount
|
.I bytecount
|
||||||
is not equal to the size of the structure
|
is not equal to the size of the structure
|
||||||
.IR modify_ldt_ldt_s ,
|
.IR user_desc ,
|
||||||
or
|
or
|
||||||
.I func
|
.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
|
.TP
|
||||||
.B ENOSYS
|
.B ENOSYS
|
||||||
.I func
|
.I func
|
||||||
is neither 0 nor 1.
|
is neither 0, 1, 2, nor 0x11.
|
||||||
.SH CONFORMING TO
|
.SH CONFORMING TO
|
||||||
This call is Linux-specific and should not be used in programs intended
|
This call is Linux-specific and should not be used in programs intended
|
||||||
to be portable.
|
to be portable.
|
||||||
|
.SH BUGS
|
||||||
|
On 64-bit kernels before Linux 3.19, one of the padding bits in
|
||||||
|
.I user_desc,
|
||||||
|
if set, would prevent the descriptor from being considered empty.
|
||||||
.SH NOTES
|
.SH NOTES
|
||||||
Glibc does not provide a wrapper for this system call; call it using
|
Glibc does not provide a wrapper for this system call; call it using
|
||||||
.BR syscall (2).
|
.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 (2)
|
||||||
|
is to run legacy 16-bit or segmented 32-bit code. Not all kernels allow
|
||||||
|
16-bit segments to be installed, however.
|
||||||
.SH SEE ALSO
|
.SH SEE ALSO
|
||||||
|
.BR set_thread_area (2),
|
||||||
|
.BR arch_prctl (2),
|
||||||
.BR vm86 (2)
|
.BR vm86 (2)
|
||||||
|
|
Loading…
Reference in New Issue