Provided by: manpages-ru-dev_4.26.0-1_all 

НАИМЕНОВАНИЕ
modify_ldt - возвращает или изменяет запись LDT у процесса
БИБЛИОТЕКА
Стандартная библиотека языка C (libc, -lc)
ОБЗОР
#include <asm/ldt.h> /* Definition of struct user_desc */
#include <sys/syscall.h> /* Definition of SYS_* constants */
#include <unistd.h>
int syscall(SYS_modify_ldt, int func, void ptr[.bytecount],
unsigned long bytecount);
Note: glibc provides no wrapper for modify_ldt(), necessitating the use of syscall(2).
ОПИСАНИЕ
Вызов modify_ldt() считывает или записывает таблицу локальных дескрипторов (LDT) процесса. LDT
представляет собой массив дескрипторов сегментов, которые могут использоваться в пользовательском коде. В
Linux процессам разрешено настраивать попроцессные (в действительности, пространство памяти) LDT.
Дополнительную информацию о LDT, смотрите в Intel Software Developer's Manual или AMD Architecture
Programming Manual.
Если func равно 0, то modify_ldt() читает LDT в память, на которую указывает ptr. Количество читаемых
байт — меньшее из bytecount и реального размера LDT несмотря на то, что ядро может действовать как будто
LDT заполняется дополнительными нулевыми байтами в конце. При успешном выполнении modify_ldt() возвращает
количество прочитанных байт.
Если значение func равно 1 или 0x11, то modify_ldt() изменяет запись LDT, на которую указывает
ptr->entry_number. Значение ptr указывает на структуру user_desc, а bytecount должно быть равно размеру
этой структуры.
Структура user_desc определена в <asm/ldt.h> следующим образом:
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;
};
В Linux версии 2.4 и более ранних эта структура называлась modify_ldt_ldt_s.
В поле contents определяется тип сегмента (данные, данные, расширяемые вниз (expand-down data), не
соответствующий код (non-conforming code) или соответствующий код). Назначение других полей совпадает с
их описанием в руководстве к процессору, несмотря на то, что modify_ldt() не может изменить
аппаратно-определяемый бит «доступа», описанный в руководстве к ЦП.
A user_desc считается «пустым», если read_exec_only и seg_not_present равны 1, а все остальные поля равны
0. Элемент LDT можно очистить, назначив ему «пустой» user_desc или, если func равно 1, установив base и
limit в 0.
Сегмент соответствующего кода (conforming code segment, т. е., с contents==3) будет отклонён, если func
равно 1 или если seg_not_present равно 0.
Если func равно 2, то modify_ldt() прочитает нули. Это, кажется, пережиток из Linux 2.4.
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При успешном выполнении modify_ldt() возвращается реальное количество прочитанных байт (при чтении) или 0
(при записи). При ошибке modify_ldt() возвращает -1, а errno устанавливается в соответствующее значение.
ОШИБКИ
EFAULT Значение ptr указывает за пределы адресного пространства.
EINVAL Значение ptr равно 0, или func равно 1, а bytecount не равно размеру структуры user_desc, или func
равно 1 или 0x11, а новый элемент LDT содержит неправильные значения.
ENOSYS Значение func не равно 0, 1, 2 или 0x11.
СТАНДАРТЫ
Linux.
ПРИМЕЧАНИЯ
Вызов modify_ldt() не должен использоваться для локального хранилища нити, так как это замедляет
переключение контекста и поддерживается только для ограниченного количества нитей. Вместо этого в
библиотеках нитей должны использоваться set_thread_area(2) или arch_prctl(2), только если не нужна
поддержка старых ядер, где нет этих вызовов.
Обычно, modify_ldt() используют для запуска старого 16-битного или сегментированного 32-битного кода.
Однако, не все ядра допускают установку 16-битных сегментов.
Даже в 64-битных ядрах вызов modify_ldt() нельзя использовать для создания сегмента кода в длинном режиме
(т. е., 64-битного). Недокументированное поле «lm» в user_desc не помогает и, несмотря на имя, не
образует сегмент в длинном режиме.
ОШИБКИ
В 64-битных ядрах до Linux 3.19, установка бита «lm» в user_desc приводила к тому, что дескриптор
переставал считаться пустым. Учтите, что бит «lm» не существует в 32-битных заголовках, но есть дефектные
ядра, которые по-прежнему сообщают о бите даже в 32-битном процессе.
СМОТРИТЕ ТАКЖЕ
arch_prctl(2), set_thread_area(2), vm86(2)
ПЕРЕВОД
Русский перевод этой страницы руководства разработал(и) aereiae <aereiae@gmail.com>, Alexey
<a.chepugov@gmail.com>, Azamat Hackimov <azamat.hackimov@gmail.com>, Dmitriy S. Seregin <dseregin@59.ru>,
Dmitry Bolkhovskikh <d20052005@yandex.ru>, ITriskTI <ITriskTI@gmail.com>, Max Is <ismax799@gmail.com>,
Yuri Kozlov <yuray@komyakino.ru>, Иван Павлов <pavia00@gmail.com>, Малянов Евгений Викторович
<maljanow@outlook.com> и Kirill Rekhov <krekhov.dev@gmail.com>
Этот перевод является свободной программной документацией; он распространяется на условиях общедоступной
лицензии GNU (GNU General Public License - GPL, https://www.gnu.org/licenses/gpl-3.0.html версии 3 или
более поздней) в отношении авторского права, но БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ.
Если вы обнаружите какие-либо ошибки в переводе этой страницы руководства, пожалуйста, сообщите об этом
разработчику(ам) по его(их) адресу(ам) электронной почты или по адресу списка рассылки русских
переводчиков.
Справочные страницы Linux 6.9.1 2 мая 2024 г. modify_ldt(2)