mmap 如何与 x32 ABI 配合使用?

mmap 如何与 x32 ABI 配合使用?

我正在查看 中的 Linux 5.0-rc5 源代码arch/x86/entry/syscalls/syscall_64.tbl,发现 x32 没有单独的系统调用号mmap

那么内核如何知道我们在用户空间中使用 x32 ABI,从而不给我们超过 4GiB 的映射地址呢?

或者一般来说,可能返回地址的系统调用如何知道我们正在使用 x32 并且不返回超过 4GiB 的地址?

答案1

想要进行 x32 系统调用的进程将在系统调用号中设置一个位,这将允许内核区分它们。

来自 syscall(2) 联机帮助页:

[5] The x32 ABI uses the same instruction as the x86_64 ABI and  is
    used  on  the  same processors.  To differentiate between them,
    the bit mask __X32_SYSCALL_BIT is bitwise-ORed into the  system
    call  number  for  system calls under the x32 ABI.  Both system
    call tables are available though, so setting the bit is  not  a
    hard requirement.

x32 并不是真正的独立环境; x32 程序可以进行 x64 系统调用,反之亦然;这与 ia32 模拟不同,ia32 模拟也可以与 x64 和 x32 并行支持。

通过以下函数在内核中检查该位in_x32_syscall()

static inline bool in_x32_syscall(void)
{
#ifdef CONFIG_X86_X32_ABI
        if (task_pt_regs(current)->orig_ax & __X32_SYSCALL_BIT)
                return true;
#endif
        return false;
}

找到内核代码实现的地方mmap()正在检查它作为练习留给读者(这并不难)。对于 x32 二进制文件的 execve() 来说,内核还将__X32_SYSCALL_BIT在保存的寄存器(系统调用号)上显式设置自身。RAX

答案2

如果您查看以下函数签名mmap

void *mmap(void *addr, size_t length, int prot, int flags,
           int fd, off_t offset);

您会注意到内存大小 ( length) 是一个size_t参数。

现在,size_t是一个平台依赖类型。size_t在32位平台上是32位,在64位平台上是64位。

也同样如此void *。 32 位架构中的指针将是 32 位地址。

所以内核不需要知道,编译器真正关心它。

相关内容