table of contents
- bookworm 4.18.1-1
- bookworm-backports 4.24.0-2~bpo12+1
- testing 4.24.0-2
- unstable 4.24.0-2
modify_ldt(2) | System Calls Manual | modify_ldt(2) |
ИМЯ¶
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 устанавливается в соответствующее значение.
ОШИБКИ¶
СТАНДАРТЫ¶
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-битном процессе.
СМОТРИТЕ ТАКЖЕ¶
ПЕРЕВОД¶
Русский перевод этой страницы руководства разработал(и) 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 (GNU General Public License - GPL, https://www.gnu.org/licenses/gpl-3.0.html версии 3 или более поздней) в отношении авторского права, но БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ.
Если вы обнаружите какие-либо ошибки в переводе этой страницы руководства, пожалуйста, сообщите об этом разработчику(ам) по его(их) адресу(ам) электронной почты или по адресу списка рассылки русских переводчиков.
2 мая 2024 г. | Справочные страницы Linux 6.8 |