背景
静态链接的缺点
- 浪费内存
- 浪费磁盘空间
- 模块更新困难
为解决空间浪费和更新困难的办法是把程序的模块相互分割开来,形成独立的文件,等程序运行时才链接,这就是动态链接。
动态链接
优点
- 节省内存
- 升级容易
- 便于独立开发和测试
- 可扩展性
一个软件制定好程序的接口,其他开发者编写符合要求的动态链接文件,作为该软件的插件。该软件能够动态的载入各种第三方开发的模块(插件),实现该软件的扩展功能
- 兼容性
动态链接库相当于在程序和操作系统之间加了一个中间层,从而消除了程序对不同平台之间依赖的差异性
原理
程序装载时,系统的动态链接器将程序所需要的所有动态链接库装载到进程的地址空间,将程序中所有未决议的符号绑定到相应的动态链接库中,进行重定位工作。动态链接将链接过程从程序装载前推迟到了装载的时候,性能损失约 5%。为了优化动态链接,常采用延迟绑定(PLT),即当函数第一次被用到时,才进行绑定,没用到则不绑定。
步骤
- 动态链接器自举
- 动态链接器本身也是一个共享对象,不可以依赖其他任何共享对象,本身所需要的全局变量和静态变量的重定位工作有它本身完成
- 装载共享对象
- 将所有可执行文件和链接器本身的符号表合并到一个符号表中
- 当一个符号需要被加入到全局符号表时,如果相同的符号名已经存在,则后加入的符号被忽略
- 重定位和初始化
- 完成上述步骤后,链接器开始重新遍历可执行文件和每个共享对象的重定位表,重定位完成后,将共享对象初始化
显式运行时链接(运行时加载)
支持动态链接的系统大都支持更灵活的模块加载方式,显式运行时链接,也叫做运行时加载。即程序自己在运行时控制加载指定的模块,且在不需要时将该模块卸载。
动态链接器的相关问题
- 动态链接器本身应该是静态链接的,不依赖其他共享对象
- 动态链接器的装载地址和一般的共享对象没有区别