Почему флаги системного вызова mmap не установлены? - PullRequest
0 голосов
/ 16 февраля 2019

Я пытаюсь вызвать 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.Дело в том, что если я поставлю еще один вызов mmap с помощью mmap из libc:

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 раньше?

1 Ответ

0 голосов
/ 16 февраля 2019

Интерфейс ядра syscall на AMD64 использует регистр r10 в качестве четвертого аргумента, а не rcx.

mov $0x32, %r10

Подробнее см. связанный вопрос .

...