ИМЯ
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 <[email protected]>, Alexey <[email protected]>, Azamat Hackimov <[email protected]>, Dmitriy S. Seregin <[email protected]>, Dmitry Bolkhovskikh <[email protected]>, ITriskTI <[email protected]>, Max Is <[email protected]>, Yuri Kozlov <[email protected]>, Иван Павлов <[email protected]> и Малянов Евгений Викторович <[email protected]> Этот перевод является бесплатной документацией; прочитайте Стандартную общественную лицензию GNU версии 3 или более позднюю, чтобы узнать об условиях авторского права. Мы не несем НИКАКОЙ ОТВЕТСТВЕННОСТИ. Если вы обнаружите ошибки в переводе этой страницы руководства, пожалуйста, отправьте электронное письмо на [email protected]10 ноября 2022 г. | Linux man-pages 6.03 |