2010-04-22 82 views
13

例如:返回一個共享庫符號表

void* sdl_library = dlopen("libSDL.so", RTLD_LAZY); 
void* initializer = dlsym(sdl_library,"SDL_Init"); 

假設沒有錯誤,初始化將指向功能SD_Init在共享庫libSDK.so。

但是這需要知道符號「SDL_Init」存在。

是否有可能查詢庫的所有符號?例如,在這種情況下,它將返回SDL_Init,函數指針和libSDL.so導出的任何其他符號。

回答

14

沒有libc函數來做到這一點。但是,你可以自己寫一個(儘管代碼有點涉及)。

在Linux中,dlopen()實際上返回一個link_map結構,其中有一個名爲l_addr構件指向加載的共享對象的基地址(假設系統沒有隨機化共享庫放置的地址,並且您的圖書館尚未預先鏈接)。

在Linux上,找到基地址(地址Elf*_Ehdr)的方法是在庫後使用dl_iterate_phdr()

有ELF頭,你應該能夠遍歷導出的符號(動態符號表)的列表,首先定位PT_DYNAMIC類型的Elf*_Phdr,然後定位​​,DT_STRTAB條目,並遍歷所有符號在動態符號表中。使用/usr/include/elf.h爲您提供指導。

此外,您可以使用libelf,但我無法引導您,因爲我沒有以前的使用經驗。

最後要注意的是,這個練習有些徒勞無功:你會得到一個已定義函數的列表,但你不知道如何調用它們(他們期望的參數),那麼有什麼意義呢?

-2
void *dlsym(void *restrict handle, const char *restrict name); 

返回值

如果手柄並不是指由dlopen()的開了一個有效的 對象,或者如果 命名的符號不能內 任何被發現 句柄dlsym()將返回空值。 更詳細的診斷信息 應可通過dlerror()

(來源:http://www.opengroup.org/onlinepubs/009695399/functions/dlsym.html

換句話說,如果沒有找到符號,dlsym()將返回NULL。不知道這是你想要的,但這是我能找到的最簡單的方法。

+1

這聽起來好像在OP正在尋求獲得從庫中輸出符號的列表。如果不對ELF結構中的部分進行解析,我認爲這是不可能的。 – 2010-04-22 20:49:59