Provided by: manpages-ru-dev_4.21.0-2_all bug

ИМЯ

       modify_ldt - возвращает или изменяет запись LDT у процесса

LIBRARY

       Standard C library (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>

       Этот перевод является бесплатной документацией; прочитайте Стандартную общественную лицензию GNU версии 3
       или более позднюю, чтобы узнать об условиях авторского права. Мы не несем НИКАКОЙ ОТВЕТСТВЕННОСТИ.

       Если  вы обнаружите ошибки в переводе этой страницы руководства, пожалуйста, отправьте электронное письмо
       на man-pages-ru-talks@lists.sourceforge.net.

Linux man-pages 6.03                            10 ноября 2022 г.                                  modify_ldt(2)