LWN:ELF hash table的ABI!

关注了就能看到更多这么棒的文章哦~

The ABI status of ELF hash tables

By Jonathan Corbet
August 19, 2022
DeepL assisted translation
https://lwn.net/Articles/904892/

确实有一些项目比其他项目会更关注 ABI 的兼容性;GNU C Library(glibc)这个项目在投入了大量精力来确保接口稳定的那些项目中也是最突出的一个,因此,人们有些惊讶地看到最近 glibc 的一个改动被人们指责破坏了一些应用程序,其中多数都是一些专有的游戏(proprietary games)。看来,有一类 glibc 的改动确实会破坏应用程序,但又不被认为是 ABI 变动。

在动态链接器(dynamic linker)启动一个程序时,它必须要把所有的符号引用 symbol references 解析到相应的共享库去(其中也包括 glibc)。这牵涉到在一个长长的列表中查找数以千计的符号。由于这个过程必须在应用程序真正开始运行之前就完成,所以它需要快速地完成。毕竟,没有人喜欢在启动 nethack 来开始打怪之前有一个漫长的延迟。因此,在优化符号查找方面人们自然做了不少工作。

当 linker 链接器为一个共享对象创建出 ELF 文件时,其中存储的一个 section 里就包含了该文件中的符号的哈希表。这个哈希表可以用来加快查找过程,使应用程序开始运行。多年来,System V 的标准中都规定这个 table 的格式是 DT_HASH;Linux 上的 toolchain 也支持这种格式。在 2006 年新增了 DT_GNU_HASH 格式,其中包括了一些改进,可以让 nethack 玩家可以更快进入他们的地下城,其中就包括了一个更好的哈希算法和一个 Bloom filter,用来缩短搜索缺失符号(missing symbols)的过程。这种格式没有很好的文档记录,但 2017 年的一篇博文(https://flapenguin.me/elf-dt-gnu-hash )给出了一些介绍。

由于哈希表位于自己独立的 ELF section,所以 ELF 文件里面这种 section 也可以不止一个。Linux 系统上的 linker 可以被要求来创建一种格式或另一种格式,甚至创建两种格式的内容但是分别位于自己的 section。glibc 在构建时(默认情况下)一直是有一个 linker option 来明确要求创建两种格式。不过,随着 8 月初 glibc 2.36 版本的发布,情况发生了变化;它包含了一个来自 Florian Weimer 的很小的 patch,导致只生成 DT_GNU_HASH 格式。

目前 glibc 2.36 已经被安装到一些更快更新的 Linux 发行版的系统上,很少有人注意到这种变动;DT_HASH 格式在这些系统上已经很多年没有被使用过了,删除它的唯一后果就是空出了一点点磁盘空间。不过,游戏玩家就没那么幸运了,而这个问题又与一个不能轻易改变的专有软件有关。

这就是 Easy Anti-Cheat(EAC)系统,它 EPIC 的一个专有工具,旨在防止游戏玩家通过修改游戏可执行文件来作弊。正如人们所期望的那样,其中实际使用的启发式规则完全没有说明,代码也是保密的,但其中之一的技术似乎是查看游戏可执行文件中的符号,来确保它们跟预期值相匹配。为了做到这一点,EAC 会通过 DT_HASH 表来进行搜索;如果找不到相应的 table,EAC 就可以自豪地宣布它已经抓住了一个作弊者,也就不再允许游戏继续运行。

玩家们似乎对这种行为感到很失望。例如,Arkadiusz Hiler 在博客中说:

我认为这整个情况正好说明了为什么给 Linux 创建原生游戏那么困难。很难责怪开发者主要针对 Windows 来开发游戏,或者依靠 Wine 之类的工具。毕竟 Windows 更稳定、更不容易出现问题。

Hiler 在 glibc 的 bug tracker 中报告了这个问题;后来讨论也转移到了项目的邮件列表上。该报告指出,这个改动 "破坏了 SysV ABI 的兼容性",建议应该 revert 掉。不过,项目开发者的回应并未完全采纳这个观点。Weimer 回答说:"现在任何一个进行符号查询的工具都需要支持 DT_GNU_HASH"。Adhemerval Zanella 说:"我不确定这是否属于 ABI 被破坏了的问题,毕竟符号查询信息确实仍然是支持的(尽管是以不同的格式)"

Carlos O'Donell 同意这一变动不算是破坏了 ABI:

在 Linux 上使用 ELF 的软件已经有 16 年的时间来进行修改,从而处理从 DT_HASH 到 DT_GNU_HASH 的转换(这是跟特定 OS 相关的)。

虽然我很同情应用开发者以及他们的向后兼容性要求,但这次的具体情况是关于使用 ELF 的一方的,它需要跟踪上游的 Linux ELF 的开发进展。

他继续说,生成的 ELF 文件的特性并不属于 glibc ABI 的一部分,尽管那里的变动缺失会破坏应用程序,并建议该 bug 应被关闭且标记为 "won't fix"。他还要求 EAC 的开发者提供信息来说明为什么 DT_HASH 应该被默认保留。截至目前,该 bug 仍然尚未关闭。

指责 EAC 的开发者没有跟上 Linux ELF 哈希表的格式的变动,这可能并不完全公平。DT_HASH 格式是由 System V ABI 规范授权的,而 DT_GNU_HASH 格式是没有文档的,也没有经历过让用户切换过来的 deprecation 的过程。这些开发者有可能和其他人一样感到惊讶,并且在过去十来年,他们并没有忽视他们的 issue tracker 中的 "切换到 DT_GNU_HASH" 这一条。不过,不管是什么原因,都需要做一些事情来解决这个问题,从而使游戏玩家避免不得不自己进行处理。

当然,如果 EAC 是免费软件,有可能会早已经有 patch 能处理这个问题了。而现在,只有这个软件的开发者自己可以直接处理这个问题。不过,与此同时,还有一个解决方法:发行商可以简单地打一个 patch 来恢复 DT_HASH section,从而让问题暂时消失。这样做就可以给 EAC(以及其他一些程序)一些时间来转移到 DT_GNU_HASH,无论从什么角度看,似乎都是最好的解决方案。

全文完
LWN 文章遵循 CC BY-SA 4.0 许可协议。

欢迎分享、转载及基于现有协议再创作~

长按下面二维码关注,关注 LWN 深度文章以及开源社区的各种新近言论~

format,png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值