MODIFY_LDT - Linux手册页

时间:2019-08-20 17:59:00  来源:igfitidea点击:

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"位可防止将该描述符视为空。请记住,在3​​2位标头中不存在" lm"位,但是即使在32位进程中进行设置,这些越野车内核仍会注意到该位。

另外参见

arch_prctl(2),set_thread_area(2),vm86(2)

出版信息

这个页面是Linux手册页项目5.08版的一部分。有关项目的说明、有关报告错误的信息以及此页面的最新版本,请访问https://www.kernel.org/doc/man-pages/