2012-06-21 146 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