zoukankan      html  css  js  c++  java
  • 课本学习笔记5:第七章 20135115臧文君

    链接

    注:作者:臧文君,原创作品转载请注明出处。

    一、概述

    1、链接(linking):是将各种代码和数据部分收集起来并组合成为一个单一文件的过程,这个文件可被加载或被拷贝到存储器并执行。

    2、链接可以执行于编译时、加载时和运行时。

    3、链接器(linker):分离编译。

    链接通常是由链接器执行。

    二、编译器驱动程序

    1、大多数编译系统提供编译驱动程序(compiler driver),它代表用户在需要时调用语言预处理器、编译器、汇编器和链接器。

    例:ASCII码源文件-->可执行目标文件

     

    三、静态链接

    1、静态链接器(static linker):ld,以一组可重定位目标文件和命令行参数作为输入,生成一个完全链接的可以加载和运行的可执行目标文件作为输出。

    2、构造可执行文件,链接器必须完成两个主要任务:

    四、目标文件

    1、三种形式:

    2、编译器和汇编器生成可重定位目标文件(包括共享目标文件)。

    3、链接器生成可执行目标文件。

    4、目标文件格式:ELF可执行和可链接格式。

    五、可重定位目标文件

     

    1、ELF头以一个16字节的序列开始,描述了生成该文件的系统的字的大小和字节顺序。

    2、ELF头剩下的部分包含帮助链接器语法分析和解释目标文件的信息。

    3、一个典型的ELF可重定位目标文件包含下面几个节:

    .text:已编译程序的机器代码。

    .rodata:只读数据。

    .data:已初始化的全局C变量。

    .bss:未初始化的全局C变量。

    .symtab:一个符号表。

    .rel.text:一个.text节中位置的列表。

    .rel.data:被模块引用或定义的任何全局变量的重定位信息。

    .debug:一个调试符号表。

    .line:原始C源程序中的行号和.text节中机器指令之间的映射。

    .strtab:一个字符串表。

    六、符号和符号表

    1、每个可重定位目标模块m都有一个符号表,它包含m所定义和引用的符号的信息。

    2、三种不同的符号:

    .symtab中的符号表不包含对应于本地非静态程序变量的任何符号。

    3、定义为带有C static属性的本地过程变量是不在栈中管理的。相反,编译器在.data和.bss中为每个定义分配空间,并在符号表中创建一个有唯一名字的本地链接器符号。

    4、符号表是由汇编器构造的,使用编译器输出到汇编语言.s文件中的符号。

    .symtab节中包含ELF符号表。

    每个符号都和目标文件的某个节相关联,由section字段表示。有三个特殊的伪节:ABS,UNDEF,COMMON。

    七、符号解析

    1、函数和已初始化的全局变量是强符号,未初始化的全局变量是弱符号。

    2、所以的编译系统都提供一种机制,将所有相关的目标模块打包成为一个单独的文件,称为静态库,它可以用做链接器的输入。

    3、在Unix系统中,静态库以一种称为存档的特殊文件格式存放在磁盘中。

    4、-static参数告诉编译器驱动程序,链接器应该构建一个完全链接的可执行目标文件,它可以加载到存储器并运行,在加载时无需更进一步的链接。

     

    八、重定位

    1、链接器完成符号解析后,就可以开始重定位了。

    重定位由两步组成:

    2、汇编器遇到对最终位置未知的目标引用,就会生成一个重定位条目。

    代码的重定位条目放在.rel.text中,已初始化数据的重定位条目放在.rel.data中。

    3、ELF定义了11中不同的重定位类型,最基本的两种是:R_386_PC32和R_386_32。

    4、重定位符号引用:重定位PC相对引用和重定位绝对引用。

    九、可执行目标文件

    1、典型的ELF可执行文件中的各类信息:

     

    十、加载可执行目标文件

    1、任何Unix程序都可以通过调用execve函数来调用加载器,加载器将可执行目标文件中的代码和数据从磁盘拷贝到存储器中,然后通过跳转到程序的第一条指令或入口点(entry point)来运行该程序。

    2、将程序拷贝到存储器并运行的过程叫做加载。

    3、在32位Linux系统中,代码段总是从地址0x08048000处开始。

    十一、动态链接共享库

    1、共享库是一个目标模块,在运行时,可以加载到任意的存储器地址,并和一个在存储器中的程序链接起来。这个过程称为动态链接,是由一个叫做动态链接器的程序来执行的。

    2、共享库也称为共享目标,通常用.so后缀来表示。

    3、共享库是以两种不同的方式来“共享”的。

    十二、从应用程序中加载和链接共享库

    1、dlopen函数加载和链接共享库filename。

    2、dlsym函数的输入是一个指向前面已经打开共享库的句柄和一个符号名字。

    3、dlclose函数卸载共享库。

    4、dlerror函数返回调用时发生的最近的错误。

    十三、与位置无关的代码(PIC)

    1、多个进程是如何共享程序的一个拷贝?

    一种是给每个共享库分配一个事先预备的专用的地址空间片,然后要求加载器总是在这个地址加载共享库;另一种是编译库代码,使得不需要链接器修改库代码就可以在任何地址加载和执行这些代码。

    2、PIC:位置无关的代码。

    十四、处理目标文件的工具

  • 相关阅读:
    SQL后台分页三种方案和分析
    SQL分页查询语句
    SQL利用临时表实现动态列、动态添加列
    查询sybase DB中占用空间最多的前20张表
    敏捷软件开发之TDD(一)
    敏捷软件开发之开篇
    Sql Server 2012启动存储过程
    改变VS2013的菜单栏字母为小写
    Sql Server获得每个表的行数
    Sql Server trace flags
  • 原文地址:https://www.cnblogs.com/CatherineZang/p/5366266.html
Copyright © 2011-2022 走看看