《Linkers and Loaders》 -- 阅读笔记

  1. 在编译器编译多个文件时,比如文件A,B,过程如下:

    1. C预处理器对问价A进行预处理,得到预处理的A。
    2. C编译器对预处理A进行编译,得到汇编文件A。
    3. 然后汇编器作用与汇编文件A,得到目标文件A。
    4. C预处理器对问价B进行预处理,得到预处理的B。
    5. C编译器对预处理B进行编译,得到汇编文件B。
    6. 然后汇编器作用与汇编文件B,得到目标文件B。
    7. 然后链接器将目标文件A和B还有系统库链接起来,形成最后的结果文件。
  2. 一些架构采用定长指令,而一些则采用变长指令。

  3. 程序的实际运行的地址只有在真正运行的时候才会知道
  4. 链接器将多个目标文件合并成一个;装载器将可执行文件载入内存。
  5. 一个目标文件包含的信息通常有:头信息、目标代码、重定位信息、符号、调试信息等。不是所有的目标文件都包含这些信息。
  6. 目标文件的格式,根据不同的用途其格式也相应的不同。一般来说有三种:a) 可链接的;b) 可执行的;c) 可装载的;还可以是这三种的组合。
  7. 在可执行文件中,符号信息和调试信息都为空,除非链接器将调试器需要的符号信息包含进去。
  8. ELF文件格式具有三个优点:可重定位、可执行、共享对象(包括共享库、链接器需要的符号信息、直接可运行的代码)。
  9. .bss区域在elf文件中的类型是NOBITS,它的属性是ALLOC + WRITE,该区域在elf文件中没有空间所以是NOBITS,他的空间在运行时分配。
  10. .init 和.fini区域的类型是PROGBITS,属性是ALLOC + EXECINTRS。它们和.test相似,只是它们包含的代码在程序开始和结束时运行。