mprotect - как работает выравнивание на несколько страниц? - PullRequest
2 голосов
/ 08 апреля 2010

Я не понимаю «выравнивание выделенной памяти» из использования mprotect.

Я имею в виду пример кода, приведенного на http://linux.die.net/man/2/mprotect

char *p;
char c;
/* Allocate a buffer; it will have the default
   protection of PROT_READ|PROT_WRITE. */
p = malloc(1024+PAGESIZE-1);
if (!p) {
    perror("Couldn't malloc(1024)");
    exit(errno);
}
/* Align to a multiple of PAGESIZE, assumed to be a power of two */
p = (char *)(((int) p + PAGESIZE-1) & ~(PAGESIZE-1));
c = p[666];         /* Read; ok */
p[666] = 42;        /* Write; ok */
/* Mark the buffer read-only. */
if (mprotect(p, 1024, PROT_READ)) {
    perror("Couldn't mprotect");
    exit(errno);
}

Для моего понимания я попытался использовать PAGESIZE 16 и 0010 в качестве адреса p. Я получил 0001 в результате (((int) p + PAGESIZE-1) & ~(PAGESIZE-1)).

Не могли бы вы уточнить, как работает весь этот «выравнивание»?

Спасибо

1 Ответ

11 голосов
/ 08 апреля 2010

Предполагая, что PAGESIZE является степенью 2 (требование), целое значение x может быть округлено до кратного PAGESIZE с (x & ~(PAGESIZE-1)). Аналогично, ((x + PAGESIZE-1) & ~(PAGESIZE-1)) приведет к x , округленному до кратного PAGESIZE.

Например, если PAGESIZE равно 16, то в двоичном виде с 32-разрядным словом:
00000000000000000000000000010000 PAGESIZE
00000000000000000000000000001111 PAGESIZE-1
11111111111111111111111111110000 ~(PAGESIZE-1)
Побитовое и (&) с вышеуказанным значением очистит младшие 4 бита значения, делая его кратным 16.

Тем не менее, код, приведенный в описании, взят из старой версии страницы руководства, и он не очень хорош, потому что он тратит память и не работает на 64-битных системах. Лучше использовать posix_memalign() или memalign() для получения памяти, которая уже правильно выровнена. В примере текущей версии справочной страницы mprotect() используется memalign(). Преимущество posix_memalign() заключается в том, что он является частью стандарта POSIX и не ведет себя по-разному в разных системах, например, в более старых нестандартных memalign().

.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...