返回共享库符号表

时间:2010-04-22 20:38:10

标签: c dll plugins shared-libraries dlopen

例如:

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

假设没有错误,初始化程序将指向共享库libSDK.so中的函数SD_Init。

然而,这需要知道符号“SDL_Init”存在。

是否可能在库中查询其所有符号?例如,在这种情况下,它将返回SDL_Init,函数指针和libSDL.so导出的任何其他符号。

5 个答案:

答案 0 :(得分:15)

没有libc功能可以做到这一点。但是,您可以自己编写一个(尽管代码有点参与)。

在Linux上,dlopen()实际上返回link_map结构的地址,该结构有一个名为l_addr的成员,指向已加载的共享对象的基址(假设您的系统)不会随机化共享库放置,并且您的库尚未预先链接。)

在Linux上,找到基址(Elf*_Ehdr的地址)的可靠方法是在dl_iterate_phdr()库之后使用dlopen()

拥有ELF标头,您应该能够迭代导出符号列表(动态符号表),首先找到类型Elf*_Phdr的{​​{1}},然后找到{{1 },PT_DYNAMIC条目,并迭代动态符号表中的所有符号。使用DT_SYMTAB为您提供指导。

此外,您可以使用libelf,但我无法指导您,因为我之前没有相关经验。

最后请注意,练习有点徒劳:您将获得已定义函数的列表,但您不知道如何调用它们(它们期望的参数),那么重点是什么?

答案 1 :(得分:1)

我认为没有为此发布的API。您可以使用binutils中的nm工具或检查其源代码: http://sourceware.org/cgi-bin/cvsweb.cgi/src/binutils/?cvsroot=src

http://sourceware.org/cgi-bin/cvsweb.cgi/src/binutils/nm.c?rev=1.63&content-type=text/x-cvsweb-markup&cvsroot=src

(显然是假设精灵)

答案 2 :(得分:0)

Boost.DLL通过library_info::symbols功能提供此功能。改编自Querying libraries for symbols上的教程:

// Class `library_info` can extract information from a library
boost::dll::library_info inf(libpath);

// Getting exported symbols
std::vector<std::string> exports = inf.symbols();

// Printing symbols
for (std::size_t j = 0; j < exports.size(); ++j) {
    std::cout << exports[j] << std::endl;
}

请注意,这仅适用于nm列出而没有 --dynamic标志的符号,即.symtab部分中的符号。似乎有些库在该节中未导出任何符号。在这种情况下,我已经打开feature request以支持退回到.dynsym部分。

答案 3 :(得分:-2)

答案 4 :(得分:-3)

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

返回值

     

如果句柄没有引用有效的   由 dlopen()打开的对象,或者如果是   命名符号无法在其中找到   任何与之相关的对象   句柄 dlsym()应返回NULL。   更详细的诊断信息   应通过 dlerror()提供。

(资料来源:http://www.opengroup.org/onlinepubs/009695399/functions/dlsym.html

换句话说,如果找不到符号,dlsym()将返回NULL。不确定这是否是您正在寻找的,但这是我能找到的最简单的方式。