开发者

mprotect - how aligning to multiple of pagesize works?

开发者 https://www.devze.com 2022-12-25 21:56 出处:网络
I am not understanding the \'aligning allocated memory\' part from the mprotect usage. I am referring to the code example given on http://linux.die.net/man/2/mprotect

I am not understanding the 'aligning allocated memory' part from the mprotect usage.

I am referring to the code example given on 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. 开发者_JAVA技巧*/
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);
}

For my understanding, I tried using a PAGESIZE of 16, and 0010 as address of p. I ended up getting 0001 as the result of (((int) p + PAGESIZE-1) & ~(PAGESIZE-1)).

Could you please clarify how this whole 'alignment' works?

Thanks,


Assuming that PAGESIZE is a power of 2 (a requirement), an integral value x can be rounded down to a multiple of PAGESIZE with (x & ~(PAGESIZE-1)). Similarly, ((x + PAGESIZE-1) & ~(PAGESIZE-1)) will result in x rounded up to a multiple of PAGESIZE.

For example, if PAGESIZE is 16, then in binary with a 32-bit word:
00000000000000000000000000010000 PAGESIZE
00000000000000000000000000001111 PAGESIZE-1
11111111111111111111111111110000 ~(PAGESIZE-1)
A bitwise-and (&) with the above value will clear the low 4 bits of the value, making it a multiple of 16.

That said, the code quoted in the description is from an old version of the manual page, and is not good because it wastes memory and does not work on 64-bit systems. It is better to use posix_memalign() or memalign() to obtain memory that is already properly aligned. The example on the current version of the mprotect() manual page uses memalign(). The advantage of posix_memalign() is that it is part of the POSIX standard, and does not have different behavior on different systems like the older non-standard memalign().

0

精彩评论

暂无评论...
验证码 换一张
取 消