读书笔记(chapter7)

第七章 链接

  链接是将各种代码和数据部分收集起来并且组合成为一个单一文件的过程。1.这个文件可被加载到存储器并执行;2.也可以执行于加载时,也就是在程序被加载器加载到存储器并执行;3.甚至可以执行于运行时,由应用程序来执行;在早期的计算机系统,链接是手动执行的。在现代系统中,链接是由叫做链接器的程序自动执行的

 

7.1编译器驱动程序

  大部分编译器驱动程序,它代表用户在需要时调用语言预处理器,编译器,汇编器,和链接器.

  1.驱动程序首先运行C预处理器cpp,将C源程序main.c翻译成一个ASCII码的中间文件main.i;

  2.驱动程序运行C编译器cc1,将main.i翻译成ASCII汇编语言文件main.s;

  3.驱动程序运行汇编器as,将main.s翻译成一个可重定位目标文件main.o;

  4.运行链接器1d,将.o文件和一些必要的系统目标文件组合起来,创建一个可执行目标文件p;

 

7.2静态链接

  输入的可重定位目标文件由各种不同的代码和数据节组成。指令在一个节中,初始化的全局变量在另一个节,未初始化的变量在另一个节;

  构造可执行文件,链接器必须完成:

  1.符号解析(目的是将每个符号引用刚好和一个符号定义联系起来)

  2.重定位(把每个符号定义与一个存储器位置联系起来,然后修改所有对这些符号的引用,使得他们指向这个存储器位置)

  *目标文件纯粹是字节块的集合

 

7.3目标文件

  目标文件有三种形式:

  1.可重定位目标文件

  2.可执行目标文件

  3.共享目标文件(特殊的可重定位目标文件)

  *一个目标模块就是一个字节序列;而一个目标文件就是存放在磁盘文件中的目标模块

 

7.4可重定位目标文件

  使用的是unix可执行和可链接格式ELF目标文件格式

  ELF头以一个16字节的序列开始,生成该文件的系统的字的的大小和字节顺序;头部剩下的部分   .....有节头部表,,,,,,

夹在ELF头和节头部表之间的都是节;

  .text

  .bss(未初始化的数据)

 

7.5符号和符号表

  每个可重定位目标模块m都有一个符号表,包含m所定义和引用的符号的信息,在链接器的上下文中,有三种不同的符号:

  1.由m定义并能被其他模块引用的全局符号

  2.由其他模块定义并被模块m引用的全局符号

  3.只被模块m定义和引用的本地符号

  *定义带有C static 属性的本地过程变量是不在栈中管理的;

 

  符号表由汇编器构造。name是字节串表的字节偏移;value是距定义目标的节的起始位置的偏移;size是目标的大小;每个符号都和目标文件的某一个节相关联,section字段表示,该字段也是一个到节头部表的索引:

  1.ABS代表不该被重定位的符号;

  2.UNDEF代表未定义的符号;

  3.COMMON表示还未被分配位置的未初始化的数据目标;

 

7.6符号解析

  链接器解析符号引用的方法是将每个引用与它输入的可重定位目标文件的符号表中的一个确定的符号定义联系起来。编译器还确保静态本地变量,它们也会有本地链接器符号,拥有唯一的名字

  1.如何解析多重定义的全局符号

    编译器向汇编器输出每个全局符号,或者强或者弱,而汇编器把这个信息隐含地编码在可重定位目标文件的符号表里,函数和已初始化的全局变量是强符号,未初始化的全局变量是弱符号,有三个规则:

      规则1、不允许有多个强符号;

      规则2、如果有一个强符号和多个弱符号,那么选择强符号;

      规则3、如果有多个弱符号,那么随机选择一个;

  2.与静态库链接

    将所有相关的目标模块打包成一个单独的文件称作静态库,可以用作链接器的输入。当链接器构造一个输出的的可执行文件,只需要拷贝静态库里被应用程序引用的模块。

特点:减少了可执行文件在磁盘和存储器中的大小;

    *静态库以一种称为存档的的特殊文件格式存放的磁盘中;存档文件由后缀.a标识

  3.如何使用静态库来解析引用

    链接器维持一个可重定位的目标文件E,一个未解析的符号U,和一个在前面输入文件中已定义的符号集合D;

    链接器会判断F是一个目标文件还是一个存档文件

 

7.7重定位

  1.重定位节和符号定义;重定位节中的符号引用(依赖于重定位条目);

  2.ELF中两个基本的重定位类型:R_386_PC32;R_386_32

  3.重定义符号引用分为PC相对引用和绝对引用

 

7.8可执行目标文件

  1.ELF包括程序的入口点,也就是当程序运行时的第一条指令的地址

  2.ELF可执行文件被设计得很容易加载到存储器,可执行文件的连续的片被映射到连续的存储器段。段头部表描述了这种映射关系

 

7.9加载可执行的目标文件

7.10动态链接共享库

  共享库是一个目标模块,  在运行时,可以加载到任意的存储器地址,并且和一个在存储器中的程序链接起来,这个过程就是动态链接

7.11从应用程序中加载和链接共享库

7.12与位置无关的代码PIC(引用、函数调用)

7.13处理目标文件的工具

 

posted on 2016-03-31 19:04  20135325  阅读(184)  评论(1编辑  收藏  举报

导航