只有一种——嵌入式Linux中的哈希样式.为什么?



我正在尝试使用基于OpenEmbedded的Arago将软件包构建并部署到rootfs中。不幸的是,该软件包包含预构建的共享库。据我所知,Arago用--hash-style=gnu构建了整个Linux发行版,而我怀疑这些共享库是用--hash-style=sysv构建的。至少构建会因"ELF二进制文件中没有GNU_HASH"QA问题而停止。

我明白哈希是干什么的。但我想我不明白当系统运行时它们是如何使用的。

为什么系统中的所有ELF都必须有一个散列样式?为什么动态链接器不能动态确定哈希样式并直接使用它?

动态链接器可以并且确实计算出ELF中存在的哈希表类型("sysv"或"gnu")并相应地工作。

不幸的是,您看到的情况是,对gnu哈希部分的支持并没有向后移植到系统上使用的旧版本的动态链接器。

存在类似的情况,其中为RHEL5/FC6构建的二进制文件在RHEL4/FC5上不起作用。


为什么.gnu.hash与.hash(sysv)不兼容

使用gnu散列部分生成ELF对动态符号表的构造施加了某些限制(附加规则)。

使用GNU散列,动态符号表被分为两部分。第一部分接收可以从哈希表中省略的符号。GNU哈希不会对动态符号表的这一部分中的符号强加任何特定的顺序。

动态符号表的第二部分接收可从哈希表访问的符号。这些符号需要使用上述GNU哈希函数,通过增加(hash%nbuckets)值进行排序。散列桶(nbuckets)的数量记录在GNU散列部分中,如下所述。因此,将在单个哈希链中找到的符号在内存中是相邻的,从而获得更好的缓存性能。

参考:blogs.oracle.com/ali/entry/gnu_hash_elf_sections

我在Yocto-Arago构建中遇到了同样的No GNU_HASH in the ELF binary问题,但事实证明,我的应用程序的Makefile没有使用由Yocto构建设置的$(LDFLAGS),它包含-Wl,--hash-style=gnu以及其他重要内容。

我之所以提到这一点,是因为这个问题是该错误消息的首选搜索结果,这可能会帮助其他人。

最新更新