2012-06-21 139 views
2

的有效性,我通過VMALLOC_START和VMALLOC_END的網頁迭代,我想 檢查,如果我每次都遇到的地址是有效的。 我該如何管理?檢查虛擬內存地址

我通過這樣的頁面重複:

unsigned long *p; 

    for(p = (unsigned long *) VMALLOC_START; p <= (unsigned long *) (VMALLOC_END - PAGE_SIZE); p += PAGE_SIZE) 
    { 
      //How to check if p is OK to access it?  

    } 

謝謝!

回答

2

最簡單的方法就是要儘量紅色它,並捕獲異常。

捕捉異常通過定義在__ex_table secion的條目,使用內聯組件完成。
異常表條目包含指向存儲器訪問指令的指針和指向恢復地址的指針。如果在該指令上發生段錯誤,EIP將被設置爲恢復地址。

像這樣的東西(我沒有測試這一點,我可能失去了一些東西):

void *ptr=whatever; 
int ok=1; 
asm(
    "1: mov (%1),%1\n" // Try to access 
    "jmp 3f\n"   // Success - skip error handling 
    "2: mov $0,%0\n"  // Error - set ok=0 
    "3:\n"    // Jump here on success 
    "\n.section __ex_table,\"a\"" 
    ".long 1b,2b\n"  // Use .quad for 64bit. 
    ".prev\n" 
    :"=r"(ok) : "r"(ptr) 
); 
+1

您好,感謝您的答覆。這個解決方案是不可移植的,對嗎?我試圖用純C來管理這個。現在我有這個實現,但我認爲它是越野車: https://github.com/PanosSakkos/shedder/blob/master/src/shedder_core.c#L44 Any想法會比歡迎:) 謝謝! – Panos

+1

我不認爲有一個便攜式解決方案。我認爲你的代碼也是不可移植的。它也不能處理大頁面(例如在x86中,你可以有一個2MB的頁面,這意味着pmd有時直接指向物理地址(或類似的東西)。 – ugoren

+1

這裏http://www.phrack.org/ issues.html?ID = 3&問題= 61(搜索「中映射的問題」),這似乎說明了便攜式(純C)的方式來做到這一點。我只是不明白,因爲它是非常寫的。謝謝! – Panos