第七章——链接

0.总结

  • 链接编译时可以采用静态链接或动态链接。
  • 连接器主要任务:符号解析和重定位。
  • 多个目标文件可定义相同的符号,可以被连接到一个单独的静态库。
  • 链接器可以生成部分链接的可执行文件
  • 动态链接器通过加载共享库和重定位程序中的引用来完成链接任务。

1.编译器驱动程序

  • 编译系统提供的调用预处理器、编译器、汇编器和链接器来构造目标文件的程序。

2.静态链接

3.目标文件

三种形式:

  1. 1、可重定位目标文件;
  2. 2、可执行目标文件;
  3. 3、共享目标文件;

4.可重定位目标文件

ELF格式

5.符号和符号表

  • 每个可重定位目标模块m都有一个符号表,它包含m所定义和引用的符号的信息。
  • 有三种不同的符号:
  1. 1m定义 & 能被其他模块引用的全局符号;
  2. 2、其他模块定义 &被模块m引用的全局符号(外部符号);
  3. 3、只被模块m定义 & 引用的本地符号;

6.符号解析

  • 将每个引用与它输入的可重定位目标文件的符号表中的一个确定的符号定义联系起来。

规则

  1. 1.不允许有多个强符号。
  2. 2.如果有一个强符号和多个弱符号,那么选择强符号。
  3. 3.如果有多个弱符号,那么从这些弱符号中任意选择一个。

与静态库链接

  • 所有的编译系统都提供一种机制,将所有相关的目标模块打包成为一个单独的文件,称为静态库(Linux下是存档文件,Windows下是lib),只拷贝静态库里被应用程序引用的目标模块。

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

7.重定位

  • 重定位条目
  • 重定位符号引用

8.可执行目标文件

  • C程序开始时是一组ASCII文本文件,已经被转化为一个二进制文件,且这个二进制文件包含加载程序到存储器并运行它所需的所有信息。

9.加载可执行目标文件

  • 将程序拷贝到存储器并运行的过程叫做加载。
  • 在32位Linux系统中,代码段总是从地址0x08048000处开始。
  • 数据段是在接下来的下一个4KB对齐的地址处。运行时堆在读/写段之后接下来的第一个4KB对齐的地址处,并通过调用malloc库往上增长。
  • 还有一个段是为共享库保留的。
  • 用户栈总是最大的合法用户地址开始,向下增长的(向低存储器地址方向增长)。从栈的上部开始的段是为操作系统驻留存储器的部分(内核)的代码和数据保留的。

10.动态链接共享库

  • 共享库是一个目标,在运行时,可以加载到任意的存储器地址,并和一个在存储器中的程序链接起来。这个过程称为动态链接,是由一个叫做动态链接器(dynamic linker)的程序来执行的。
  • 通常用.so后缀来表示,称为DLL(动态链接库)。

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

  1. 1.在任何给定的文件系统中,对于一个库只有一个.so文件。所有引用该库的可执行目标文件共享这个.so文件中的代码和数据。
  2. 2.一种共享方式就是隐式链接,基本的思路:当创建可执行文件时,静态执行一些链接,然后在程序加载时,动态完成链接过程。
  3. 3.一种共享方式就是“显式链接”,应用程序被加载时,动态链接器加载和链接共享库的情景。应用程序还可能在它运行时要求动态链接器加载和链接任意共享库,而无需在编译时链接那些库到应用中。

11.从应用程序中加载和连接共享库

  1. void *dlopen( const char *file, int mode );//将共享目标文件打开并且映射到内存中,并且返回句柄
  2. void *dlsym( void *restrict handle, const char *restrict name );//回一个指向被请求入口点的指针
  3. char *dlerror();//返回 NULL 或者一个指向描述最近错误的 ASCII 字符串的指针
  4. char *dlclose( void *handle );//关闭句柄并且取消共享目标文件的映射

12.处理目标文件的工具

  1. AR:创建静态库,插入、删除、列出和提取成员。
  2. STRINGS:列出一个目标文件中所有可打印的字符串。
  3. STRIP:从目标文件中删除符号的信息。
  4. NM:列出一个目标文件的符号表中定义的符号。
  5. SIZE:目标文件中节的名字和大小。
  6. READELF:显示一个目标文件的完整结构,包括ELF头中的编码的所有信息。包含SIZENM的功能。
  7. OBJDUMP:所有二进制工具之母,能够显示一个目标文件中所有的信息。它最大的作用是反汇编.text节中的二进制指令。
  8. LDD:列出一个可执行文件在运行时所需要的共享库。

2013337朱荟潼 Linux&深入理解计算机系统第七章读书笔记——链接的更多相关文章

  1. <深入理解计算机系统>第七章读书笔记

    第七章读书笔记 链接 链接:将各种代码和数据部分收集起来并组合成为一个单一文件的过程.(这个文件可被加载或拷贝到存储器并执行) 链接可以执行于编译,加载或运行时. 静态链接: 两个主要任务: 1 符号 ...

  2. 20135202闫佳歆--week 7 深入理解计算机系统第七章--读书笔记

    参见上学期的学习笔记: http://www.cnblogs.com/20135202yjx/p/4836058.html

  3. 2013337朱荟潼 Linux第五章读书笔记——系统调用

    摘要: [20135337朱荟潼]原创作品转载请注明出处 第五章 系统调用 5.1 与内核通信 中间层 作用三个:1.为用户空间提供一种硬件的抽象接口:2.保证系统稳定和安全:3.除异常和陷入,是内核 ...

  4. 2013337朱荟潼 Linux第一章读书笔记——Linux内核简介

    一.Unix历史 二.Linux足迹 类Linux系统.非商业化产品.用途广泛 三.操作系统和Linux内核简介 1.操作系统 (1)是指在整个最基本功能系统中负责完成最基本功能和系统管理的部分. ( ...

  5. 2013337朱荟潼 Linux第二章读书笔记——从内核出发

    1.获取内核源码 1.1Git 分布式的:下载和管理Linux内核源代码: - 获取最新提交到版本树的一个副本 $ git clone git://git.kernel.org/pub/scm/lin ...

  6. 2013337朱荟潼 Linux第十八章读书笔记——调试

    第十八章 调试 0.总结 oops 内核的调试配置 用Git进行二分搜索 bug总会有,简洁描述发给LKML 1. 准备开始 在用户级的程序里,bug表现比较直接:在内核中却不清晰. 2. 内核中的b ...

  7. 2013337朱荟潼 Linux第三章读书笔记——进程管理

    第三章 进程管理 总结 fork创造的子进程复制了父进程资源,包括内存及进程描述符的内容,资源的复制而不是指针的复制. vfork的行为更像一个线程(指没有自已独立的内存空间),更明显的是vfork的 ...

  8. 2013337朱荟潼 Linux第四章读书笔记——进程调度

    第4章 进程调度 0. 总结 调度:调度是一个平衡的过程.一方面,它要保证各个运行的进程能够最大限度的使用CP:另一方面,保证各个进程能公平的使用CPU. 调度功能:决定哪个进程运行以及进程运行多长时 ...

  9. 《深入理解计算机系统》 Chapter 7 读书笔记

    <深入理解计算机系统>Chapter 7 读书笔记 链接是将各种代码和数据部分收集起来并组合成为一个单一文件的过程,这个文件可被加载(货被拷贝)到存储器并执行. 链接的时机 编译时,也就是 ...

随机推荐

  1. SDN2017 期末作业验收

    GIT仓库:GITHUB 负载均衡程序 拓扑如图 目的 实现一个负载均衡的北向程序: 服务器host 2 ,host 3,host 4上各自有不同的服务,host 1是客户端 当host 2,host ...

  2. [Python2]介绍关于Uiautomator的watcher使用场景及使用方法

    [官方的介绍]: Watcher You can register watcher to perform some actions when a selector can not find a mat ...

  3. myEtherWallet在线钱包的使用

    https://www.myetherwallet.com/#generate-wallet myEtherWallet是一款在线钱包,当你不想安装类似metamask这样的插件时,可以选择使用它 1 ...

  4. Excel操作

    区间范围计算 方法一:用IF函数 方法二:构建一个辅助区域,用VLOOKUP函数 方法一:用IF函数 在F3中输入:=IF(E3>=90%,5%,IF(E3>=80%,4%,IF(E3&g ...

  5. auto关键字使用

    auto类型变量--根据初始值推断真实的数据类型. 有些时候并不能很确定一个变量应该具备的数据类型,例如:将一个复杂表达式的值赋给某个变量,此时并不能很明显的确定这个值所具备的数据类型.此时auto关 ...

  6. (转)win7批量创建用户

    @echo off::zhangsan 改为你需要建立的用户名,123456改为你的密码,后面的两个参数的意思是“用户::不可以更改密码”和“密码永不过期”net user xiaowei 12345 ...

  7. jqgrid 基础应用

    jqgrid 是一个在jquery基础上做的一个表格插件,以ajax的方式和服务器端通信. 一个jqgrid的基础示例(基础参数说明)如下: $("#jqGrid").jqGrid ...

  8. Android 网络编程之---HttpClient 与 HttpURLConnection 共用cookie

    HttpClient 与 HttpURLConnection 共用 SessionId HttpClient 与 HttpUrlConnection 是Android 中HTTP操作最常见的訪问方式. ...

  9. Hibernae

    开始尝试挺java ee的课程,马士兵老师的 1.ssh的整个框架体系 spring会贯穿在整个过程之中 2.Hibernate的整个框架体系 3. 4. 5. 6.

  10. scala-数组操作

    package com.bigdata import scala.collection.mutable.ArrayBuffer object ArrayO { def main(args: Array ...