CSAPP-链接

128 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

一个c文件是如何运行的?它的内部经过了什么?这正是这篇文章的主题。

代码的旅程

C语言代码要想最终成为机器可执行的程序,都会经过以下处理:

  • 预处理器:将 C 语言代码(da.c)转化成 da.i 文件(gcc –E)
  • 编译器:C 语言代码(da.c, wang.c)经过编译器的处理(gcc -0g -S)成为汇编代码(da.s, wang.s)
  • 汇编器:汇编代码(da.s, wang.s)经过汇编器的处理(gcc 或 as)成为对象程序(da.o, wang.o)
  • 链接器:对象程序(da.o, wang.o)以及所需静态库(lib.a)经过链接器的处理(gcc 或 ld)最终成为计算机可执行的程序
  • 加载器:将可执行程序加载到内存并进行执行,loader 和 ld-linux.so

本章的学习重点就是链接器部分:

链接基本知识

连接器主要负责做两件事情

  1. 符号解析 Symbol resolution

我们在代码中会声明变量及函数,之后会调用变量及函数,所有的符号声明都会被保存在符号表(symbol table)中,而符号表会保存在由汇编器生成的 object 文件中(也就是 .o 对象文件)。符号表实际上是一个结构体数组,每一个元素包含名称、大小和符号的位置。

所谓的对象文件(Object File)实际上是一个统称,具体来说有以下三种形式:

  • 共享目标文件 Shared object file (.so file)
  • 可重定位目标文件 Relocatable object file (.o file)
  • 可执行目标文件 Executable object file (a.out file)

在 symbol resolution 阶段,链接器会给每个符号应用一个唯一的符号定义,用作寻找对应符号的标志。


  1. 重定位 Relocation

这一步所做的工作是把原先分开的代码和数据片段汇总成一个文件,会把原先在 .o 文件中的相对位置转换成在可执行程序的绝对位置,并且据此更新对应的引用符号(才能找到新的位置)