一、背景

gcc将源码编译为.o,然后linker将.o连接为.so或者可执行程序,linker可以使用ld.bfd、ld.gold或者lld。

ld.bfd在binutils软件包中,是最常用的linker;ld.gold也在binutils软件包中,速度比ld.bfd快不少,但是内核以及其他一些项目不支持;lld是llvm的linker,据说比ld.gold更快,但是没怎么了解过,本文不讨论lld。

二、启用ld.gold

ubuntu上,可以sudo apt-get install binutils-gold安装ld.gold;如果是自己编译工具链,那么gcc和binutils进行configure时,都需要指定--enable-gold。

使用gcc时,需要指定参数-fuse-ld=gold。

如果想调试,确认使用的连接器是哪个,可以使用gcc参数-print-prog-name=ld。

三、dt-needed的问题

假设可执行程序exe1使用了so1和so2中的函数,so1使用了so2的函数。编译so1时,肯定需要指定-lso2;编译exe1时,肯定需要指定-lso1,但是exe1间接依赖了so2,是否需要指定-lso2呢?

ld.bfd在低于2.22版本时,可以不指定,不会报错,但是存在风险。假设哪一天,so1对外接口不变,但是不再使用so2中的函数了,也不添加-lso2。那么exe1编译时又没写-lso2,会出现编译问题以及运行问题。

ld.bfd高于2.22版本时,默认需要指定-lso2,否则会报错。但是也可以添加--copy-dt-needed-entries参数,来避免报错,这种方式不推荐。

ld.gold,不支持--copy-dt-needed-entries参数,必须指定-lso2。

四、hash table的问题

切换ld.gold后,遇到了一个问题。dlopen某个很大的.so时,ld.bfd只需要0.3s左右,ld.gold需要1s左右,性能不满足要求。

经过各种排查,最后readelf -S 看到,使用ld.gold编译出来的.so,缺少了一个.gnu.hash段,也就是DT_GNU_HASH。

参考文献2 中可以看到,解析符号的字符串时,有两种hash方式,sysv和gnu,gnu要比sysv快50%左右。所以,添加gcc参数-Wl,--hash-style=gnu或者-Wl,--hash-style=both来启用gnu hash。

五、结论

使用ld.gold,单纯看连接时间的话,确实减少了很多。但是连接时间在整体编译中,占的比例并不高,所以整体编译大概节约了5%左右。

使用ld.gold,即使使用了gnu hash,.so的载入还是会慢一些,大约慢4%左右。

以上数据仅供参考,具体项目需要自行测试。

参考文献

1、UnderstandingDSOLinkChange:http://fedoraproject.org/wiki/UnderstandingDSOLinkChange

2、ELF: better symbol lookup via DT_GNU_HASH:https://flapenguin.me/2017/05/10/elf-lookup-dt-gnu-hash/

3、binutils-2.22: ld and --copy-dt-needed-entries:https://lists.freebsd.org/pipermail/freebsd-current/2011-December/030114.html

ld.gold使用指南相关推荐

  1. 从零开始编译自己的Linux发行版 LFS简介

    LFS 的全称是 Linux From Scratch,就像它的名字一样,这个发行版是一个教我们如何从零开始打造自己的 Linux 发行版的指南,同时还有姊妹发行版 BLFS,全称是 Beyond L ...

  2. Python安全攻防-3渗透测试框架

    最近新买了一本关于Python的一本书<Python安全攻防渗透测试实战指南>,这本书出自MS08067安全实验室,才学到第三章,虽然书中有非常多的低级语法错误,但是总体来讲还是值得一学的 ...

  3. hitool java_hi3798cv200 android 编译

    hi3798cv200 android compile开发环境搭建和初次编译参考Android 解决方案 开发指南.pdf- >开发环境配置 烧写工具HiTool-STB-3.1.35.zip ...

  4. 从零开始构建Linux

    目的:深入了解以Linux内核为基础的系统是如何组成,运行,以构建一个最基础的,纯净的系统. LFS构建步骤 宿主机准备 - linux操作系统安装 - 使用独立硬盘,创建分区 - 配置用户和组 - ...

  5. ubuntu搭建tiny4412环境【学习笔记】

    一.安装完系统之后需要执行如下步骤 1.sudo apt-get update 更新软件源 2.sudo apt-get install vsftpd openssh-server nfs-kerne ...

  6. 【要闻】Kubernetes安全问题严峻、Linux v5.4安全性浅谈

    以下为您奉上今天的开源领域要闻. 谷歌提前发布Android 11首个开发者预览版 谷歌通常会在三月推出即将发布的Android预览版本.但谷歌今年更早实现了该功能,现已发布了Android 11首个 ...

  7. GNU binutils 里的九种武器 | Linux 中国

    原创: 译者/Xingyu.Wang Linux中国 10月10日 https://mp.weixin.qq.com/s/n2HHgcbpfwsQlYf93ocu1Q Table of Content ...

  8. Android NDK生成及连接静态库与动态库

    对于Android应用开发,大部分情况下我们使用Java就能完整地实现一个应用.但是在某些情况下,我们需要借助C/C++来写JNI本地代码.比如,在使用跨平台的第三方库的时候:为了提升密集计算性能的时 ...

  9. Ubuntu16.04编译Android5.1源码

    0.安装OpenJDK1.7 在安装前需要DNS设置,否则提示无法找到资源: <1>vi /etc/resolv.conf 加入: nameserver 8.8.8.8<2>重 ...

最新文章

  1. Python自然语言处理
  2. 我把公司当家,老板当爹,结局...
  3. Search Engine XSS Worm
  4. 2005年度国产空间信息系统软件测评
  5. java 数据结构_Java数据结构学习方法
  6. java 多线程下载文件
  7. 消息称阿里腾讯考虑互相开放生态系统 淘宝能用微信支付了?
  8. qt connect函数_Qt 串口上位机开发Rice 上位机 学习开发
  9. matlab 病态方程组,数值分析(Hilbert矩阵)病态线性方程组的求解Matlab程序
  10. IEEE JBHI 投稿因格式问题打回记录
  11. awg710 matlab,利用任意信号发生器模拟高速光驱信号
  12. VUE页面中加载外部HTML
  13. Arduino控制微小的六足3D打印机器人
  14. Android下载自带开源图标库教程
  15. Visual Odometry技术 (Of VSLAM)
  16. 2021年全国居住场所火灾死亡人数、受伤人数、火灾发生原因及造成直接财产损失分析[图]
  17. C# 调用中通快递查询物流轨迹接口
  18. iphone好的网站总结
  19. 8人Python-----day02
  20. 【实验五 一维数组】7-9 sdut-C语言实验- 排序

热门文章

  1. 【设计模式】【07】建造者模式
  2. WPS EXCEL制作二级下拉框、动态下拉框、联动下拉框
  3. 反者道之动,弱者道之用
  4. 【已解决】(新)西部数据移动硬盘插入,电脑无法识别盘符
  5. I/O 照相亭 | Flutter + Firebase = 轻松构建 Web 应用
  6. 转载--大内高手—序
  7. Notification在应用通知管理页添加更多设置入口
  8. Web安全-旁注攻击
  9. 利用网络分析工具对城市管道网络进行分析 对一个物流公司的运送路线进行合理的规划
  10. CSC公派|在读博士赴新加坡南洋理工大学联合培养