为什么未设置mmap syscall标志

时间:2019-02-16 16:40:40

标签: system-calls mmap flags

我正在尝试通过直接系统调用来调用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_ANONYMOUS。 事实是,如果我从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标志。但是我真的不明白发生了什么。

为什么只有在我将libc mmap调用放在前面时,mmap syscall示例才起作用?

1 个答案:

答案 0 :(得分:0)

AMD64上的内核syscall接口使用r10注册作为第四个参数,而不是rcx

mov $0x32, %r10

有关更多详细信息,请参见linked question