MODIFY_LDT - Linux手册页
Linux程序员手册 第2部分
更新日期: 2020-02-09
名称
Modify_ldt-获取或设置每个进程的LDT条目
语法
#include <sys/types.h> int modify_ldt(int func, void *ptr, unsigned long bytecount);
注意:此系统调用没有glibc包装器。请参阅注释。
说明
modify_ldt()读取或写入进程的本地描述符表(LDT)。 LDT是可以由用户代码引用的段描述符的数组。 Linux允许进程配置每个进程(实际上是每个毫米)的LDT。有关LDT的更多信息,请参阅《英特尔软件开发人员手册》或《 AMD体系结构编程手册》。
当func为0时,modify_ldt()将LDT读入ptr指向的内存中。读取的字节数是字节数和LDT的实际大小中的较小者,尽管内核可能会像在LDT上填充额外的尾随零字节一样工作。成功后,modify_ldt()将返回读取的字节数。
当func为1或0x11时,modify_ldt()修改由ptr-> entry_number指示的LDT条目。 ptr指向user_desc结构,字节数必须等于此结构的大小。
user_desc结构定义为:
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。
内容字段是段类型(数据,扩展数据,不合格代码或合格代码)。尽管modify_ldt()无法设置CPU手册中描述的硬件定义的"已访问"位,但其他字段与CPU手册中的描述相匹配。
如果将read_exec_only和seg_not_present设置为1并且所有其他字段均为0,则将user_desc视为"空"。可以通过将LDT条目设置为"空" user_desc来清除它,如果func为1,则可以通过将两个base并限制为0。
如果func为1或seg_not_present为0,则符合标准的代码段(即content == 3的代码段)将被拒绝。
当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的,不应在旨在可移植的程序中使用。
备注
Glibc不为该系统调用提供包装器;使用syscall(2)调用它。
modify_ldt()不应用于线程本地存储,因为它会减慢上下文切换的速度,并且仅支持有限数量的线程。线程库应改用set_thread_area(2)或arch_prctl(2),但在不支持这些系统调用的极其老旧的内核上除外。
modify_ldt()的正常用法是运行旧的16位或分段的32位代码。但是,并非所有内核都允许安装16位段。
即使在64位内核上,modify_ldt()也不能用于创建长模式(即64位)代码段。 user_desc中未记录的字段" lm"没有用,并且尽管名称很长,但不会导致长模式段。
BUGS
在Linux 3.19之前的64位内核上,在user_desc中设置" lm"位可防止将该描述符视为空。请记住,在32位标头中不存在" lm"位,但是即使在32位进程中进行设置,这些越野车内核仍会注意到该位。
另外参见
arch_prctl(2),set_thread_area(2),vm86(2)
出版信息
这个页面是Linux手册页项目5.08版的一部分。有关项目的说明、有关报告错误的信息以及此页面的最新版本,请访问https://www.kernel.org/doc/man-pages/。