![获取页面起始地址](https://linux22.com/image/172605/%E8%8E%B7%E5%8F%96%E9%A1%B5%E9%9D%A2%E8%B5%B7%E5%A7%8B%E5%9C%B0%E5%9D%80.png)
我想获取内存页的开头,该页包含一个函数。
就我而言,我尝试实现主功能的页面开头。其中0x400a80
,我认为它位于内存的代码部分。如果您能证实这是否属实,我将不胜感激。
据我了解,地址0x400a80
位于页面中。
当我使用 显示进程的内存段时pmap
,它显示以大小 8K 开头的段0x400000
,下一部分以0x601000
大小 4K 开头。
我想获取地址,0x400000
因为它有函数的地址main()
。当我有一个地址驻留在该页面时,如何获得该页面的起始地址? linux 有没有内置的方法可以做?
答案1
欢迎来到 Unix 和 Linux StackExchange!
这个问题可能可以更好地回答堆栈溢出,专门解决编程问题的 StackExchange 站点。但不管怎么说...
在 x86 架构中,标准内存页为 4 KiB,即 0x1000 字节。内存页从地址 0 开始,连续分配,没有重叠。
查找内存页的起始地址:
beginning of page = memory address AND (NOT page size - 1)
因此,如果地址为 0x400a80,则该页面的开头 = 0x400a80 AND(不是 0x000fff)= 0x400a80 AND 0xfff000 = 0x400000。
答案2
如果您正在查找包含内存位置的页面的开头,您可以使用sysconf(_SC_PAGE_SIZE)
检索系统的页面大小,并向下舍入:
void *alloc;
long pagesz;
pagesz = sysconf(_SC_PAGESIZE);
printf("Default page size: %ld\n", pagesz);
alloc = malloc(512 * 1024 * 1024);
printf("512MiB allocated at %zx\n", alloc);
printf("The corresponding page starts at %zx\n", (((off_t) alloc) / pagesz) * pagesz);
在页面大小不同的情况下,这可能会产生误导,例如在 Linux 上使用巨大映射时。
如果您正在寻找包含内存位置的地址空间分配的开始,我不知道有什么可移植的方法可以做到这一点。在 Linux 上,检索映射信息的接口是 /proc/self/maps
,所以你需要打开并解析它。