【问题标题】:Why are mmap syscall flags not set为什么未设置 mmap 系统调用标志
【发布时间】:2019-07-10 12:58:39
【问题描述】:

我正在尝试使用直接系统调用来调用 mmap。

#include <sys/mman.h>

int main() {
    __asm__("mov $0x0, %r9;"
            "mov $0xffffffffffffffff, %r8;"
            "mov $0x32, %rcx;"
            "mov $0x7, %rdx;"
            "mov $0x1000, %rsi;"
            "mov $0x303000, %rdi;"
            "mov $0x9, %rax;"
            "syscall;");
    return 0;
}

我静态编译了程序:

$ gcc -static -o foo foo.c

但是系统调用失败,如strace所示:

$ strace ./foo
mmap(0x303000, 4096, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, -1, 0) = -1 EBADF (Bad file descriptor)

我们可以看到 mmap 标志设置错误。 0x32 应该是 MAP_PRIVATE | MAP_FIXED | MAP_匿名。 问题是,如果我使用 libc 中的 mmap 进行另一个 mmap 调用:

int main() {
    mmap(0x202000, 4096, 0x7, 0x32, -1, 0);
    __asm__("mov $0x0, %r9;"
            "mov $0xffffffffffffffff, %r8;"
            "mov $0x32, %rcx;"
            "mov $0x7, %rdx;"
            "mov $0x1000, %rsi;"
            "mov $0x303000, %rdi;"
            "mov $0x9, %rax;"
            "syscall;");
    return 0;
}

然后两个 mmap 都可以工作:

$ strace ./foo
mmap(0x202000, 4096, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x202000
mmap(0x303000, 4096, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x303000

所以似乎使用 libc,mmap 标志被“解析”或其他东西。但我无法真正理解发生了什么。

为什么 mmap 系统调用示例只有在我之前调用 libc mmap 时才有效?

【问题讨论】:

    标签: system-calls mmap flags


    【解决方案1】:

    AMD64 上的内核系统调用接口使用r10 寄存器作为第四个参数,而不是rcx

    mov $0x32, %r10
    

    更多详情请见linked question

    【讨论】:

    • 就是这样,谢谢!现在我明白了为什么它之前与 libc 调用一起工作:r10 已设置并且在两个调用之间没有改变。
    猜你喜欢
    • 2016-03-06
    • 2020-12-05
    • 2018-07-31
    • 1970-01-01
    • 2021-10-27
    • 1970-01-01
    • 2016-05-23
    • 1970-01-01
    • 2011-09-25
    相关资源
    最近更新 更多