我在查看 Linux 5.0-rc5 源代码arch/x86/entry/syscalls/syscall_64.tbl
,发现 x32 没有单独的系统调用号mmap
。
那么内核如何知道我们在用户空间中使用 x32 ABI,所以不给我们超过 4GiB 的映射地址?
或者一般来说,可能返回地址的系统调用如何知道我们正在使用 x32 而不是返回超过 4GiB 的地址?
我在查看 Linux 5.0-rc5 源代码arch/x86/entry/syscalls/syscall_64.tbl
,发现 x32 没有单独的系统调用号mmap
。
那么内核如何知道我们在用户空间中使用 x32 ABI,所以不给我们超过 4GiB 的映射地址?
或者一般来说,可能返回地址的系统调用如何知道我们正在使用 x32 而不是返回超过 4GiB 的地址?
想要进行 x32 系统调用的进程将在系统调用号中设置一个位,这将允许内核区分它们。
从 syscall(2) 联机帮助页:
x32 并不是真正的独立环境;x32 程序可以进行 x64 系统调用,反之亦然;这与 ia32 仿真不同,它也可以与 x64 和 x32 并排支持。
该位通过以下
in_x32_syscall()
函数在内核中检查:查找内核代码实现在哪里
mmap()
检查它留给读者作为练习(这并不难)。在 x32 二进制文件的 execve() 的情况下,内核还将__X32_SYSCALL_BIT
在保存的寄存器(系统调用号)上显式设置自身。RAX
如果您查看 的函数签名
mmap
:您会注意到内存大小 (
length
) 是一个size_t
参数。现在,
size_t
是依赖于平台的类型。size_t
在 32 位平台上是 32 位,在 64 位平台上是 64 位。也是如此
void *
。32 位架构中的指针将是 32 位地址。所以不是内核需要知道,编译器真的会处理它。