2011-11-09 20 views
2

我動態加載一些Linux圖書館C. 我可以使用如何在C中查看Linux內存映射信息?

dlinfo

(見1)獲取庫的起始地址。

但是,我找不到任何信息來獲取庫的大小。

是我發現的唯一的事情就是一個必須閱讀

的/ proc/[PID] /映射

文件,並解析它的相關信息(見2) 。 有沒有更優雅的方法?

+0

據我所知,解析'maps'是最簡單的方法。爲什麼在你看來它不夠高雅? – osgx

+1

與簡單地做下面的事情相比,把字符串解析搞砸不是很好。 'struct link_map * map; dlinfo(hLibrary,RTLD_DI_LINKMAP,&map); void * base = map-> l_addr;' – user1036752

+0

有一個'map-> l_name',你可以根據庫的路徑做一個'stat',或者你可以嘗試挖掘link_map更深,並找到加載的ELF文件的段/段。 – osgx

回答

0

(此答案是LINUX/GLIBC特異性)

根據http://s.eresi-project.org/inc/articles/elf-rtld.txt

有link_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 =一些庫不在存儲器連續;這封信有一些例子...例如這是非常的內部(至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部分)。

0

解析/proc/self/maps(或者可能是popen -ing a pmap命令)對我來說仍然是最簡單的事情。還有dladdr函數(假設你有一些地址開頭)。