动态库深入解析与实验探究
1. 实验:观察加载命令和动态加载 - 阶段 I
在之前的实验中,我们使用 otool -h
查看 /bin/ls
时,报告有 13 个加载命令。若要显示这些命令,可使用 otool -l
(部分命令在示例中省略)。这里我们以 64 位二进制文件为例进行研究,同时也鼓励大家通过 otool -arch i386
来查看 32 位二进制文件。
2. 动态库概述
可执行文件很少是独立运行的,除了极少数静态链接的文件外,大多数可执行文件都是动态链接的,依赖于操作系统自带或第三方提供的现有库。下面将探讨库的加载过程,包括应用启动时和运行时的加载。
3. 库的启动时加载
内核加载器(位于 bsd/kern/mach_loader.c
)会根据段和其他指令来初始化进程地址空间。但对于绝大多数 OS X 上的程序而言,这远远不够,因为它们几乎都是动态链接的。这意味着 Mach - O 镜像中存在很多“空洞”,即对外部库和符号的引用,这些引用会在程序启动时由动态链接器解决,此过程也被称为符号“绑定”。
动态链接器通常由内核在遇到 LC_DYLINKER
加载命令时启动,一般是 /usr/lib/dyld
,不过该命令也可以指定其他程序。内核会将进程的入口点设置为链接器的入口点,从而使链接器接管进程。
链接器的主要任务是“填补空洞”,即找出所有符号和库的依赖关系并解决它们。由于库