2010-04-22 53 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