M4 crepl
首先发现自己需要补一下编译链接的知识,于是找来 ICS 2025 年的视频回放看了一下:[09 链接与加载
- bilibili](https://www.bilibili.com/video/BV11LysBsEnb)
大致来说,gcc 编译的过程是
.c -----> .i -----> .s -----> .o -----> a.out
预处理 编译 汇编 链接
汇编得到的 .o 即为目标(object)文件,为 ELF 格式。有这几种目标文件:
- 可重定位目标文件(relocatable object file):.o 文件,包含了符号表和重定位信息,可以被链接器进一步处理。
- 共享目标文件(shared object file):.so 文件,包含了可被多个程序共享的代码和数据,可以被动态链接器加载和使用。
- 可执行目标文件(executable object file):.out 文件,包含了程序的入口点和可执行代码,可以被操作系统加载和执行。
日常语境里说“目标文件”,通常特指 .o 这种可重定位目标文件。
二进制代码中,会有对符号的引用,比如全局变量、函数。除非静态编译,否则存在一部分引用的实际地址(或者相对当前 PC 的偏移量)无法被确定。要么在下一步链接时确定,最后得到静态链接的可执行文件,要么在运行时动态链接时直接确定(GOT)或动态链接后调用时延迟绑定(PLT)。
理解了链接的基本概念后,需要了解 dlopen 和 dlsym 的使用。dlopen 用于在运行时加载共享库,返回一个句柄;dlsym 用于根据符号名查找共享库中的符号地址。