获取页面起始地址

获取页面起始地址

我想获取内存页的开头,该页包含一个函数。

就我而言,我尝试实现主功能的页面开头。其中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,所以你需要打开并解析它。

相关内容