2010-04-08 71 views
2

我不瞭解mprotect使用中的'對齊分配的內存'部分。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); 
} 

對於我的理解給定的代碼示例中,我試圖用16的PAGESIZE和0010爲p的地址。 由於(((int) p + PAGESIZE-1) & ~(PAGESIZE-1)),我最終得到了0001。

你能否澄清一下這整個'對齊'是如何工作的?

謝謝,

回答

11

假設PAGESIZE是2(要求)的功率,積分值X可以向下舍入爲與PAGESIZE(x & ~(PAGESIZE-1))的倍數。同樣,((x + PAGESIZE-1) & ~(PAGESIZE-1))將導致x四捨五入爲PAGESIZE的倍數。

例如,如果PAGESIZE爲16,然後用一個32位字的二進制:
00000000000000000000000000010000PAGESIZE
00000000000000000000000000001111PAGESIZE-1
11111111111111111111111111110000~(PAGESIZE-1)
甲按位與(&)與上述值將清除低4位的值,使其成爲16的倍數。

也就是說,描述中引用的代碼來自舊版本的手冊頁,並且不是不錯,因爲它浪費內存,不適用於64位系統。最好使用posix_memalign() or memalign()來獲得已經正確對齊的內存。當前版本的mprotect()手冊頁上的示例使用memalign()posix_memalign()的優點在於它是POSIX標準的一部分,並且在不同的系統(如舊的非標準memalign())上沒有不同的行爲。

+0

感謝您的澄清。這肯定有幫助! – Chaitanya 2010-04-08 22:04:02