如何在C中查看Linux内存映射信息?

如何在C中查看Linux内存映射信息?,c,linux,memory,ld,dlopen,C,Linux,Memory,Ld,Dlopen,我正在用C动态加载一些Linux库。 我可以使用 dlinfo (见附件) 然而,我找不到任何信息来获得图书馆的大小 我唯一发现的是一个人必须阅读 /proc/[pid]/maps 文件并对其进行分析以获取相关信息(请参阅)。 有更优雅的方法吗?(这个答案是LINUX/GLIBC特有的) 据 有链接地图*地图;地图->地图开始和地图->地图结束 /* ** Start and finish of memory map for this object. **

我正在用C动态加载一些Linux库。 我可以使用

dlinfo

(见附件)

然而,我找不到任何信息来获得图书馆的大小

我唯一发现的是一个人必须阅读

/proc/[pid]/maps

文件并对其进行分析以获取相关信息(请参阅)。 有更优雅的方法吗?

(这个答案是LINUX/GLIBC特有的)

有链接地图*地图;地图->地图开始和地图->地图结束

    /* 
        ** Start and finish of memory map for this object.  
    ** l_map_start need not be the same as l_addr.  
    */
    ElfW(Addr) l_map_start, l_map_end;
正如这里所说的,这有点不准确 =某些库在内存中不是连续的;这封信有一些例子。。。e、 g.这是一个非常内部(到rtld)的函数,用于根据链接映射和直接使用ELF段来检测给定地址是否在lib的地址空间内:

/* Return non-zero if ADDR lies within one of L's segments.  */
int
internal_function
_dl_addr_inside_object (struct link_map *l, const ElfW(Addr) addr)
{
  int n = l->l_phnum;
  const ElfW(Addr) reladdr = addr - l->l_addr;

  while (--n >= 0)
    if (l->l_phdr[n].p_type == PT_LOAD
    && reladdr - l->l_phdr[n].p_vaddr >= 0
    && reladdr - l->l_phdr[n].p_vaddr < l->l_phdr[n].p_memsz)
      return 1;
  return 0;
}
/*如果ADDR位于L的一个段内,则返回非零*/
int
内部函数
_dl_addr_内部对象(结构链接映射*l,常量ElfW(addr)addr)
{
int n=l->l_phnum;
常量ElfW(Addr)reladdr=Addr-l->l_Addr;
而(--n>=0)
如果(l->l\u phdr[n].p\u type==PT\u LOAD
&&reladdr-l->l\u phdr[n]。p\u vaddr>=0
&&reladdr-l->l_phdr[n].p_vaddrl_phdr[n].p_memsz)
返回1;
返回0;
}
这个函数是另一个选择,它是查找加载的ELF的程序头/或节头(link_map中有一些指向此类信息的链接)

最简单的方法是使用一些带有
map->l_name
stat
系统调用从磁盘读取文件大小(在检测巨大的bss部分时不精确)。

(这个答案特定于LINUX/GLIBC)

有链接地图*地图;地图->地图开始和地图->地图结束

    /* 
        ** Start and finish of memory map for this object.  
    ** l_map_start need not be the same as l_addr.  
    */
    ElfW(Addr) l_map_start, l_map_end;
正如这里所说的,这有点不准确 =某些库在内存中不是连续的;这封信有一些例子。。。e、 g.这是一个非常内部(到rtld)的函数,用于根据链接映射和直接使用ELF段来检测给定地址是否在lib的地址空间内:

/* Return non-zero if ADDR lies within one of L's segments.  */
int
internal_function
_dl_addr_inside_object (struct link_map *l, const ElfW(Addr) addr)
{
  int n = l->l_phnum;
  const ElfW(Addr) reladdr = addr - l->l_addr;

  while (--n >= 0)
    if (l->l_phdr[n].p_type == PT_LOAD
    && reladdr - l->l_phdr[n].p_vaddr >= 0
    && reladdr - l->l_phdr[n].p_vaddr < l->l_phdr[n].p_memsz)
      return 1;
  return 0;
}
/*如果ADDR位于L的一个段内,则返回非零*/
int
内部函数
_dl_addr_内部对象(结构链接映射*l,常量ElfW(addr)addr)
{
int n=l->l_phnum;
常量ElfW(Addr)reladdr=Addr-l->l_Addr;
而(--n>=0)
如果(l->l\u phdr[n].p\u type==PT\u LOAD
&&reladdr-l->l\u phdr[n]。p\u vaddr>=0
&&reladdr-l->l_phdr[n].p_vaddrl_phdr[n].p_memsz)
返回1;
返回0;
}
这个函数是另一个选择,它是查找加载的ELF的程序头/或节头(link_map中有一些指向此类信息的链接)


最简单的方法是使用一些带有
map->l_name
stat
系统调用从磁盘读取文件大小(在检测巨大的bss部分时不精确)。

解析
/proc/self/maps
(或者
popen
-ing
pmap
命令)对我来说仍然是最简单的事情。还有一个功能(如果您有一些地址可以开始)。

解析
/proc/self/maps
(或者
popen
-ing
pmap
命令)对我来说似乎仍然是最简单的事情。还有一个函数(如果你有一些地址开始)。

正如我所知,解析
maps
是最简单的方法。为什么在您看来它不优雅?与简单地执行以下操作相比,处理字符串解析不是很好<代码>结构链接图*地图;dlinfo(图书馆、实时链接地图和地图);void*base=map->l\u addr有一个
map->l_name
,您可以根据库的路径执行
stat
。或者你可以试着更深入地挖掘link_map,找到加载的ELF文件的段/节。正如我所知,解析
maps
是最简单的方法。为什么在您看来它不优雅?与简单地执行以下操作相比,处理字符串解析不是很好<代码>结构链接图*地图;dlinfo(图书馆、实时链接地图和地图);void*base=map->l\u addr有一个
map->l_name
,您可以根据库的路径执行
stat
。或者,您可以尝试更深入地挖掘链接映射,并查找加载的ELF文件的段/节。