为什么没有设置 mmap 系统调用标志
Why are mmap syscall flags not set
我正在尝试使用直接系统调用来调用 mmap。
#include <sys/mman.h>
int main() {
__asm__("mov [=10=]x0, %r9;"
"mov [=10=]xffffffffffffffff, %r8;"
"mov [=10=]x32, %rcx;"
"mov [=10=]x7, %rdx;"
"mov [=10=]x1000, %rsi;"
"mov [=10=]x303000, %rdi;"
"mov [=10=]x9, %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 [=13=]x0, %r9;"
"mov [=13=]xffffffffffffffff, %r8;"
"mov [=13=]x32, %rcx;"
"mov [=13=]x7, %rdx;"
"mov [=13=]x1000, %rsi;"
"mov [=13=]x303000, %rdi;"
"mov [=13=]x9, %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 标志是 "resolved" 之类的。但是我真的不明白发生了什么。
为什么只有在我之前调用 libc mmap 时,mmap 系统调用示例才有效?
AMD64 上的内核系统调用接口使用 r10
寄存器作为第四个参数,而不是 rcx
。
mov [=10=]x32, %r10
有关详细信息,请参阅 linked question。
我正在尝试使用直接系统调用来调用 mmap。
#include <sys/mman.h>
int main() {
__asm__("mov [=10=]x0, %r9;"
"mov [=10=]xffffffffffffffff, %r8;"
"mov [=10=]x32, %rcx;"
"mov [=10=]x7, %rdx;"
"mov [=10=]x1000, %rsi;"
"mov [=10=]x303000, %rdi;"
"mov [=10=]x9, %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 [=13=]x0, %r9;"
"mov [=13=]xffffffffffffffff, %r8;"
"mov [=13=]x32, %rcx;"
"mov [=13=]x7, %rdx;"
"mov [=13=]x1000, %rsi;"
"mov [=13=]x303000, %rdi;"
"mov [=13=]x9, %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 标志是 "resolved" 之类的。但是我真的不明白发生了什么。
为什么只有在我之前调用 libc mmap 时,mmap 系统调用示例才有效?
AMD64 上的内核系统调用接口使用 r10
寄存器作为第四个参数,而不是 rcx
。
mov [=10=]x32, %r10
有关详细信息,请参阅 linked question。