链接
链接:将各种代码和数据片段收集并组合成为一个单一文件的过程,这个文件可被加载(复制)到内存中。
编译器作用: .c -> .i -> .s -> .o
可重定位目标文件(.o):
包含二进制代码和数据,可和其他可重定位目标文件合成 可执行文件。
可重定位目标模块里面有一个符号表,包含定义和引用的符号的信息
可执行文件:包含二进制代码和数据,可以直接被复制到内存并执行。
共享目标文件:特殊可重定位目标文件,可在加载或运行时被动态地加载进内存并链接。
静态链接:步骤是 符号解析 和 重定位
静态库:.a ,是由很多.o合并而来
符号解析:符号对应一个函数、全局变量或是静态变量。符号解析作用是将每个符号引用和符号定义关联起来。
重定位:关联之后,重定位这些节,然后修改所有对这些符号的引用,使得它们指向这个内存位置。这样每个引用就能在内存中找到定义
链接器:
只复制被调用的目标模块(函数),减少可执行文件在内存中的大小。
链接器用库来解析其他目标模块中的符号引用。
许多链接器从左到右顺序扫描解析符号引用,顺序可能会引起链接错误。
动态链接
动态库: .so, 调用动态库的可执行文件可在内存中共享这个库的代码和数据,而不会复制。
当创建可执行文件时,静态执行一些链接,然后在程序加载时,动态完成链接过程。可执行程序只是复制走了一些重定位和符号表信息,使得运行时可以解析对.so中代码和数据的引用。
链接动态库
先运行一个 加载器(将可执行文件的内容映射到内存,并运行这个程序), 再运行 动态链接器。动态链接器 执 行 重定位.so的文本和数据到某个内存段,再重定位可执行程序中所有对.so定义的符号的引用 来完成链接任务。
还可以在程序中加载和链接动态库!!软件更新很多就是这么做,调用dlopen函数。