我在C中动态加载一些Linux库。 我可以使用
获取库的起始地址dlinfo
(见1)。
但是,我无法找到任何信息来获得图书馆的大小。
我发现的唯一一件事就是必须阅读
/ proc / [pid] / maps
文件并解析它以获取相关信息(请参阅2)。 有更优雅的方法吗?
答案 0 :(得分:0)
(这个答案是LINUX / GLIBC特定的)
根据http://s.eresi-project.org/inc/articles/elf-rtld.txt
有link_map * map; map-> l_map_start& MAP-> l_map_end
/*
** 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;
有点不精确,如http://www.cygwin.com/ml/libc-hacker/2007-06/msg00014.html所述 =有些图书馆在记忆中没有连续;链接的字母有一些例子......例如这是检测的内部(to rtld)函数是否是lib的地址空间内的给定地址,基于link_map并直接使用ELF段:
/* 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;
}
这个函数是另一种选择,它可以找到加载的ELF的程序头/或节头(在link_map中有一些指向这些信息的链接)
最简单的方法是使用一些stat
系统调用与map->l_name
- 从磁盘读取文件大小(检测巨大的bss部分时不准确)。
答案 1 :(得分:0)
解析/proc/self/maps
(或者popen
- pmap
命令 - 似乎对我来说仍然是最简单的事情。还有dladdr
功能(前提是你有一些地址)。