Provided by: manpages-ru-dev_4.18.1-1_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 ⟨https://www.gnu.org/licenses/gpl-3.0.html⟩ или более позднюю, чтобы
       узнать об условиях авторского права. Мы не несем НИКАКОЙ ОТВЕТСТВЕННОСТИ.

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