]>
Commit | Line | Data |
---|---|---|
fea681da | 1 | .\" Copyright (c) 1995 Michael Chastain (mec@duracef.shout.net), 22 July 1995. |
38f7c379 | 2 | .\" Copyright (c) 2015 Andrew Lutomirski |
fea681da | 3 | .\" |
e4a74ca8 | 4 | .\" SPDX-License-Identifier: GPL-2.0-or-later |
fea681da | 5 | .\" |
4c1c5274 | 6 | .TH modify_ldt 2 (date) "Linux man-pages (unreleased)" |
fea681da | 7 | .SH NAME |
38f7c379 | 8 | modify_ldt \- get or set a per-process LDT entry |
481166e4 AC |
9 | .SH LIBRARY |
10 | Standard C library | |
8fc3b2cf | 11 | .RI ( libc ", " \-lc ) |
fea681da | 12 | .SH SYNOPSIS |
16718a1c | 13 | .nf |
57d2facb AC |
14 | .BR "#include <asm/ldt.h>" " /* Definition of " "struct user_desc" " */" |
15 | .BR "#include <sys/syscall.h>" " /* Definition of " SYS_* " constants */" | |
16 | .B #include <unistd.h> | |
c6d039a3 | 17 | .P |
c64cd13e | 18 | .BI "int syscall(SYS_modify_ldt, int " func ", void " ptr [. bytecount ], |
57d2facb | 19 | .BI " unsigned long " bytecount ); |
16718a1c | 20 | .fi |
c6d039a3 | 21 | .P |
45c99e3e | 22 | .IR Note : |
57d2facb AC |
23 | glibc provides no wrapper for |
24 | .BR modify_ldt (), | |
25 | necessitating the use of | |
26 | .BR syscall (2). | |
fea681da | 27 | .SH DESCRIPTION |
e511ffb6 | 28 | .BR modify_ldt () |
7acf749e MK |
29 | reads or writes the local descriptor table (LDT) for a process. |
30 | The LDT | |
38f7c379 AL |
31 | is an array of segment descriptors that can be referenced by user code. |
32 | Linux allows processes to configure a per-process (actually per-mm) LDT. | |
33 | For more information about the LDT, see the Intel Software Developer's | |
34 | Manual or the AMD Architecture Programming Manual. | |
c6d039a3 | 35 | .P |
fea681da MK |
36 | When |
37 | .I func | |
38 | is 0, | |
e511ffb6 | 39 | .BR modify_ldt () |
38f7c379 | 40 | reads the LDT into the memory pointed to by |
fea681da MK |
41 | .IR ptr . |
42 | The number of bytes read is the smaller of | |
43 | .I bytecount | |
38f7c379 | 44 | and the actual size of the LDT, although the kernel may act as though |
7acf749e MK |
45 | the LDT is padded with additional trailing zero bytes. |
46 | On success, | |
38f7c379 AL |
47 | .BR modify_ldt () |
48 | will return the number of bytes read. | |
c6d039a3 | 49 | .P |
fea681da MK |
50 | When |
51 | .I func | |
38f7c379 | 52 | is 1 or 0x11, |
e511ffb6 | 53 | .BR modify_ldt () |
38f7c379 | 54 | modifies the LDT entry indicated by |
7acf749e | 55 | .IR ptr\->entry_number . |
fea681da MK |
56 | .I ptr |
57 | points to a | |
5a16bf48 MK |
58 | .I user_desc |
59 | structure | |
60 | and | |
fea681da MK |
61 | .I bytecount |
62 | must equal the size of this structure. | |
c6d039a3 | 63 | .P |
5a16bf48 MK |
64 | The |
65 | .I user_desc | |
c84371c6 | 66 | structure is defined in \fI<asm/ldt.h>\fP as: |
c6d039a3 | 67 | .P |
088a639b | 68 | .in +4n |
e646a1ba | 69 | .EX |
5a16bf48 MK |
70 | struct user_desc { |
71 | unsigned int entry_number; | |
59b191dc | 72 | unsigned int base_addr; |
5a16bf48 MK |
73 | unsigned int limit; |
74 | unsigned int seg_32bit:1; | |
75 | unsigned int contents:2; | |
76 | unsigned int read_exec_only:1; | |
77 | unsigned int limit_in_pages:1; | |
78 | unsigned int seg_not_present:1; | |
79 | unsigned int useable:1; | |
80 | }; | |
b8302363 | 81 | .EE |
5a16bf48 | 82 | .in |
c6d039a3 | 83 | .P |
5a16bf48 MK |
84 | In Linux 2.4 and earlier, this structure was named |
85 | .IR modify_ldt_ldt_s . | |
c6d039a3 | 86 | .P |
38f7c379 AL |
87 | The |
88 | .I contents | |
89 | field is the segment type (data, expand-down data, non-conforming code, or | |
7acf749e MK |
90 | conforming code). |
91 | The other fields match their descriptions in the CPU manual, although | |
38f7c379 | 92 | .BR modify_ldt () |
c79a3031 | 93 | cannot set the hardware-defined "accessed" bit described in the CPU manual. |
c6d039a3 | 94 | .P |
38f7c379 AL |
95 | A |
96 | .I user_desc | |
97 | is considered "empty" if | |
98 | .I read_exec_only | |
99 | and | |
100 | .I seg_not_present | |
101 | are set to 1 and all of the other fields are 0. | |
102 | An LDT entry can be cleared by setting it to an "empty" | |
103 | .I user_desc | |
104 | or, if | |
105 | .I func | |
106 | is 1, by setting both | |
107 | .I base | |
108 | and | |
109 | .I limit | |
110 | to 0. | |
c6d039a3 | 111 | .P |
c79a3031 MK |
112 | A conforming code segment (i.e., one with |
113 | .IR contents==3 ) | |
114 | will be rejected if | |
38f7c379 AL |
115 | .I |
116 | func | |
117 | is 1 or if | |
118 | .I seg_not_present | |
119 | is 0. | |
c6d039a3 | 120 | .P |
38f7c379 AL |
121 | When |
122 | .I func | |
123 | is 2, | |
124 | .BR modify_ldt () | |
7acf749e MK |
125 | will read zeros. |
126 | This appears to be a leftover from Linux 2.4. | |
47297adb | 127 | .SH RETURN VALUE |
fea681da | 128 | On success, |
e511ffb6 | 129 | .BR modify_ldt () |
fea681da MK |
130 | returns either the actual number of bytes read (for reading) |
131 | or 0 (for writing). | |
132 | On failure, | |
e511ffb6 | 133 | .BR modify_ldt () |
fea681da | 134 | returns \-1 and sets |
0daa9e92 | 135 | .I errno |
5a16bf48 | 136 | to indicate the error. |
fea681da MK |
137 | .SH ERRORS |
138 | .TP | |
139 | .B EFAULT | |
140 | .I ptr | |
141 | points outside the address space. | |
142 | .TP | |
143 | .B EINVAL | |
144 | .I ptr | |
145 | is 0, | |
146 | or | |
147 | .I func | |
148 | is 1 and | |
149 | .I bytecount | |
150 | is not equal to the size of the structure | |
38f7c379 | 151 | .IR user_desc , |
fea681da MK |
152 | or |
153 | .I func | |
7acf749e | 154 | is 1 or 0x11 and the new LDT entry has invalid values. |
fea681da MK |
155 | .TP |
156 | .B ENOSYS | |
157 | .I func | |
38f7c379 | 158 | is neither 0, 1, 2, nor 0x11. |
3113c7f3 | 159 | .SH STANDARDS |
4131356c | 160 | Linux. |
c12fd10d | 161 | .SH NOTES |
38f7c379 AL |
162 | .BR modify_ldt () |
163 | should not be used for thread-local storage, as it slows down context | |
7acf749e MK |
164 | switches and only supports a limited number of threads. |
165 | Threading libraries should use | |
38f7c379 AL |
166 | .BR set_thread_area (2) |
167 | or | |
168 | .BR arch_prctl (2) | |
169 | instead, except on extremely old kernels that do not support those system | |
170 | calls. | |
c6d039a3 | 171 | .P |
38f7c379 | 172 | The normal use for |
bf7bc8b8 | 173 | .BR modify_ldt () |
7acf749e MK |
174 | is to run legacy 16-bit or segmented 32-bit code. |
175 | Not all kernels allow 16-bit segments to be installed, however. | |
c6d039a3 | 176 | .P |
f89f50fa | 177 | Even on 64-bit kernels, |
bf7bc8b8 | 178 | .BR modify_ldt () |
6da93ae6 MK |
179 | cannot be used to create a long mode (i.e., 64-bit) code segment. |
180 | The undocumented field "lm" in | |
1ae6b2c7 | 181 | .I user_desc |
6da93ae6 MK |
182 | is not useful, and, despite its name, |
183 | does not result in a long mode segment. | |
7acf749e | 184 | .SH BUGS |
c79a3031 MK |
185 | On 64-bit kernels before Linux 3.19, |
186 | .\" commit e30ab185c490e9a9381385529e0fd32f0a399495 | |
f89f50fa | 187 | setting the "lm" bit in |
1ae6b2c7 | 188 | .I user_desc |
6da93ae6 MK |
189 | prevents the descriptor from being considered empty. |
190 | Keep in mind that the | |
f89f50fa AL |
191 | "lm" bit does not exist in the 32-bit headers, but these buggy kernels |
192 | will still notice the bit even when set in a 32-bit process. | |
47297adb | 193 | .SH SEE ALSO |
38f7c379 | 194 | .BR arch_prctl (2), |
7acf749e | 195 | .BR set_thread_area (2), |
fea681da | 196 | .BR vm86 (2) |