来自《深入理解计算机系统》
写在前面
ELF-64可重定位目标文件的格式
ELF(executable and linkable format)
常见的文件类型包括:可执行文件、共享库.so、目标文件.o和core文件
动态链接共享库
共享库 Shared Library
共享库的存在合理性:
静态库需要定期的维护和更新
动态链接的存在合理性: 静态链接中,假设两个程序共享一个模块,则静态链接后输出的两个可执行文件中各有一个共享模块的副本,若同时运行这两个可执行文件,则共享模块在磁盘和内存中都有两个副本,造成了磁盘和内存的极大浪费。
共享库.so是一个目标模块,在运行或加载时,可以加载到任意的内存位置,并和内存中的程序链接,整个过程称为 动态链接
动态链接与静态链接的区别
- 静态链接
- 将头文件的库全部加载到链接后的可执行文件中
- 动态链接
- 将某些符号的重定位推迟到程序执行阶段
- 减少库中无用函数带来的可执行文件过大
+---------------------+ +---------------------+
| 可执行文件 | | 可执行文件 |
| +---------------+ | | +---------------+ |
| | 程序代码 | | | | 程序代码 | |
| +---------------+ | | +---------------+ |
| | 静态库函数 | | | | 动态链接库 | |
| +---------------+ | | +---------------+ |
| | 其他资源 | | | | 其他资源 | |
| +---------------+ | | +---------------+ |
+---------------------+ +---------------------+
动态链接器工作流程
步骤 | 描述 |
---|---|
1. 加载可执行文件 | 加载可执行文件到内存中 |
2. 查找依赖的动态链接库 | 查找并加载程序所需的动态链接库,可以是系统默认路径下的库或自定义路径下的库 |
3. 符号解析 | 动态链接器遍历可执行文件和动态链接库,解析程序中对这些库的符号引用(函数名或变量名) |
4. 重定位 | 动态链接器将符号引用重定位到相应的库中的实际内存地址 |
5. 加载完成 | 当所有的符号解析和重定位工作完成后,动态链接器通知OS加载过程结束,程序准备就绪可以执行。 |
6. 运行时操作 | 在程序执行过程中,动态链接器还可以进行一些额外的运行时操作,如动态加载新的库、处理符号冲突等。 |
DDL和SO都是啥
DLL: Dynamic link libraries
SO: Shared object
- dll和so是不同OS上的动态链接库
- dll是window使用的动态链接库格式,通常用于windows平台上的程序;Windows程序下用
LoadLibrary
和GetProAddress
等程序动态加载 - so是类unix系统使用的动态链接库格式,通常用于类unix系统上的程序;类Unix程序使用
dlopen
和dlsym
等函数动态加载
- dll是window使用的动态链接库格式,通常用于windows平台上的程序;Windows程序下用