【问题标题】:Symbol reference resolution for dynamically loaded libraries on linuxlinux上动态加载库的符号引用解析
【发布时间】:2020-02-17 10:51:55
【问题描述】:

我试图了解在动态加载库的情况下如何解析符号。我观察到库的符号是使用作为库的动态依赖项链接的库来解析的。可以使用 - ldd <share_file_name.so>

列出相同的内容

这是正确的吗?

之前我假设加载器会查看LD_LIBRARY_PATH 并查看所有库以解析库中的符号。 但现在我想一想,我就明白为什么不能使用这种方法了。原因是,如果加载程序必须查看LD_LIBRARY_PATH 中列出的目录中的所有库,那么解析符号的方式将非常不优化。如果目录有一百万个文件,那么它会很慢,因为任何文件都可以有符号。

【问题讨论】:

标签: linux gcc ld dynamic-loading


【解决方案1】:

Loader基本上的工作原理是按照加载顺序扫描所有加载的库(首先是主可执行文件的直接依赖项,然后是它们的依赖项等)。通常,您的库需要的符号将从它自己的依赖项中解析(您可以通过在您的库上运行 readelf -lldd 来找到)。但是如果其他一些前面的库已经提供了它们,它们将从那里被解析(这称为符号插入,用于各种技巧,如LD_PRELOADImplib.so)。

还有更多可能影响加载器决策的细节(-Bsymbolic,符号版本控制等),例如解释在规范的How to write shared libraries 文档中。

【讨论】:

  • Usually symbols which your library needs will be resolved from it's own dependencies (which you can find by running readelf -l or ldd on your library) - 我的理解是 - 如果依赖项中没有符号,那么可执行文件将不会启动,因为链接器不知道哪个依赖项具有该符号,对吗?
  • 另外 LD_LIBRARY_PATH 与符号解析无关。它只是链接器搜索依赖项的一组目录,我们可以使用 ldd <name_of_executable> 列出这些依赖项。
  • “如果依赖项中没有符号,则可执行文件将无法启动,因为链接器不知道哪个依赖项具有该符号”-您是在谈论静态链接器还是动态链接器(又名加载器)?如果链接时符号不存在,静态链接器将中止,除非您使用“-Wl,--allow-shlib-undefined”运行它。如果符号在运行时不存在,动态链接器将不会中止而是继续运行,直到您尝试调用该函数(此时它将终止执行),除非您使用LD_BIND_NOW 运行(然后它将在启动时失败)。
  • 在生成中有很多细节会改变符号解析的工作方式,因此我鼓励您阅读我在回答中引用的 Drepper 的论文。
  • 感谢 cmets。当然,我会通过论文。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-10-23
  • 1970-01-01
  • 2018-05-13
  • 2013-06-11
  • 1970-01-01
  • 2018-03-07
相关资源
最近更新 更多