拜读大牛Ulrich Drepper大作之How To Write Shared Libraries

本文详细解读了Ulrich Drepper的《How To Write Shared Libraries》一文,探讨了DSO(Dynamic Shared Objects)、PLT(Procedure Linkage Table)和ELF文件格式。内容涉及DSO的效率优化、lookup scope的复杂性、GOT与PLT的工作原理,以及动态链接器的角色和任务。文章还讨论了符号查找的优化、DSO的性能考量和API/ABI的维护策略。
摘要由CSDN通过智能技术生成

读大牛Ulrich Drepper关于如何写动态库的大作心得。

原文地址:

https://www.akkadia.org/drepper/dsohowto.pdf

 

一些术语

DSO, Dynamic Shared Objects
PLT,Procedure Linkage Table

 

关键点

  1. section 1
    回顾a.out的历史,阐述它的优缺点, 引入COFF, 再到ELF. 相关描述也可以参照有一定年头的Linker and Loader一书. 其中有更多不同平台上的文件格式的发展的介绍:)


    简述ELF的结构及组织:
    • 系统中同时存在static linker和dynamic linker, DSO要依靠dynamic linker来相互合作. 经由dynamic linker的一些动作, 如reloaction之后, 控制流才会转到相应的可执行文件.
    • ELF header提供了所有ELF section的相关信息, 它的结构可以参照Dwarf3.pdf, 本章简单的介绍了一下ELF header中的各个结构成员的用途. 它会指向各个program header.
    • program header中有一个关键的PT INTERP tag, 它表示了应该用什么样的dynamic linker, 利用它来指定具体的dynamic linker. 当它被kernel 映射到进程空间之后, 还需要为它准备auxiliary vector的数据结构(以便绕过一些不必要的系统调用, 使得dynamic linker更易工作, AT_开头的tag,都是与auxiliary vector相关的), 之后才能把控制权转交到dynamic linker.
    • dynamic linker的三个任务:确认并加载相关依赖, 重定位应用程序和所有的依赖, 正确的初始化应用程序和其依赖.
      最繁重的任务就是重定位, 它的时间复杂度是O(R +nr), 其中R是相关重地位的个数, r是命名重地位的个数, n是主程序所用到的DSO的个数
      有不少针对上诉任务的优化方案, 其中有的能使得时间复杂度变为O(R + rn log s), 其中s是符号的个数. 从中可见,最终要的就是尽可能的减少重定位和符号的个数.
      而重地位中最复杂的就是symbol relocation.
       
    • 禁止lazy relocation: 对linker 使用-z now参数. 但是, 这依赖于重新link DSO或者更改binary, 所以, 慎用.
       
    有两种方式来搜寻一个给定的symbol, 其中对于lookup scope的定义和选择相当复杂, 文中在1.5.4中详细介绍了
    • 传统的ELF方式
      1. 计算symbol name的hash值
      2. 在lookup scope内,对各个object进行以下操作
        2.1 使用该object的hash值和hash table的大小来决定hash bucket
        2.2 获得该symbol名称的offset, 并用它作为一个以NUL结尾的名称
        2.3 拿该symbol name与relocation name比较
        2.4 如果名称相符, 再比较它们的version name, 两者都相同, 则找到所要的.
        2.5 如果名称不相符, 在hash bucket中选取下一个
        2.6 如果当前的object所包含的链中都没有找到, 就选取下一个lookup scope
      3. 如果在所有的lookup scope中都没有找到, 则搜寻失败
          从中可以看出, 关键的效率考量在如何选取lookup scope中的object数及hash chain的长度. GNU 通过优化这两者提供了另外一种更有效的方式.
    • GNU 方式, 优化symbol name comparison, symbol entry link list更好的利用了CPU cache
      1. 计算symbol name的hash值
      2. 在lookup scope内,对各个object进行以下操作
        2.1 该hash值用来判断是否该当前的object中已经有该值了. 这是通过2-bit的Bloom filter来完成的(它使得比较操作被显著减少了). 如果没有, 就在该scope中选取下一个object进行查找.
        2.2 使用该object的hash值和hash table的大小来决定hash bucket. 该值是一个symbol index
        2.3 从object chain中拿到这个symbol index所对应的entry, 用该entry中的值与1中的值比较. 忽略bit 0
  • 3
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值