ELF符号可见性

时间:2015-05-06 05:33:46

标签: shared-libraries visibility symbols elf

假设我在文件spec_a.h中定义了api(sym1) 在lib_imp1.so中有一个这个api的实现。 我可以有一个dlopen这个共享库的应用程序,dlsym()sym1并调用它。是否可以将应用程序dlopen()与sym1作为未定义的其他共享库,并将其解析为lib_imp1.so中的sym1? 如果是这样,我们该怎么做?

如果可能的话,我们可以有两个实现,lib_imp1.so和lib_imp2.so,它们都有两个不同的地址用于相同的符号sym1。 如果应用程序使用未解析的sym1加载另一个共享库,我们是否可以控制哪个sym1(lib_imp1.so或lib_imp2.so)被解析?

在生成lib_imp1.so时,我们可以说虽然我们想要导出sym1,但我们不希望任何未解析的符号被解析出来吗? (有点受控制的出口?)

感谢

1 个答案:

答案 0 :(得分:1)

  

我可以拥有一个dlopen这个共享库的应用程序,dlsym()sym1并调用它。是否可以将应用程序dlopen()与sym1作为未定义的其他共享库,并将其解析为lib_imp1.so中的sym1?

是:如果第一个dlopen使用RTLD_GLOBAL,则从lib_imp1.so(包括sym1)导出的所有符号都会输入到全局范围内,并对其他人可见库加载了以后。

  

如果可能,那么我们可以有两个实现,lib_imp1.so和lib_imp2.so,它们都有两个不同的地址用于相同的符号sym1。

是。这是不明智的。

  

如果应用程序使用未解析的sym1加载另一个共享库,我们是否可以控制哪个sym1(lib_imp1.so或lib_imp2.so)被解析为?

没有。假设您dlopen同时lib_imp1.solib_imp2.so同时使用RTLD_GLOBAL,则任何后续库将始终从第一个sym1 ed库绑定到dlopen提供它(即它将解析为lib_imp1.so定义)。

此外,如果lib_imp1.so也导出sym2以及lib_imp2.so调用sym2中的任何内容,该符号也将解析为内部定义lib_imp1.so(除非您特别小心并使用-Bsymbolic)。

最终结果是UNIX .so库的行为与归档库非常相似,而不像windows DLL。这使得两个单独的实现导出相同的接口在一个进程中基本上不可行。

  

在生成lib_imp1.so时,我们可以说虽然我们希望导出sym1,但是我们不希望将任何未解析的符号解析为它吗?

dlsym使用完全相同的解决方案流程。如果您使该符号无法解析,则dlsym也找不到该符号。相反,导出符号意味着“使其可用于解析”(通过dlopen或只是常规未解析的依赖关系解析)。