【问题标题】:ELF Dynamic loader symbol lookup orderingELF 动态加载器符号查找排序
【发布时间】:2012-09-21 21:17:53
【问题描述】:

解析动态重定位时符号查找的搜索顺序是什么?

当解析共享库的符号时,加载器首先在“主可执行文件”中搜索(让主可执行文件覆盖定义...)还是什么?

【问题讨论】:

    标签: linux gcc ld elf binutils


    【解决方案1】:

    据我了解,每个可执行对象都有自己的“查找范围”:

    • 主可执行文件通常是“全局”查找范围中的第一个对象。这意味着在主可执行文件中定义的符号将覆盖依赖共享库中的符号。使用 LD_PRELOAD 工具添加的共享对象将添加到全局查找范围,紧跟在主可执行文件之后。
    • 但是,如果正在加载的共享对象使用DF_SYMBOLIC 标志,则源自该对象的符号引用将在全局查找范围内搜索之前查找对象内的定义。
    • 使用dlopen() 打开的共享对象可能有自己的依赖关系。如果在调用dlopen() 期间未设置RTLD_GLOBAL 标志,则这些依赖项将添加到该对象的查找范围,但不会影响全局查找范围。如果RTLD_GLOBAL 标志被传递给dlopen(),那么共享对象(及其依赖项)将被添加到“全局”查找范围,从而改变后续符号查找的行为。

    推荐阅读 Ulrich Drepper 的指南“How to Write Shared Libraries”。

    【讨论】:

    • 为了完整性:主可执行文件的某些符号不会被导出到动态符号表中,除非您使用 rdynamic 选项(或类似选项)对其进行编译
    • 链接标志“-rdynamic”解决了@debuti指出的问题。我尝试了 dlopen 标志 RTLD_GLOBAL 或 RTLD_DEEPBIND,都不起作用。
    【解决方案2】:

    当解析共享库的符号时,加载器首先在“主可执行文件”中搜索(让主可执行文件覆盖定义...)还是什么?

    是的,没错。动态加载器有一个加载的 ELF 对象的链接列表(列表的头部是_r_dynamic.r_map),并在该列表中线性搜索对象的动态符号表,直到找到它正在寻找的符号定义。

    列表的头部总是指向主可执行文件。如果从主可执行文件中导出给定符号,则它(几乎)总是“获胜”(覆盖其他定义)。

    但是,请注意-Bsymbolic 链接器标志会稍微改变图片。

    【讨论】:

      猜你喜欢
      • 2015-12-20
      • 2016-10-12
      • 2021-02-25
      • 1970-01-01
      • 2017-07-07
      • 1970-01-01
      • 2014-11-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多