六、动态链接

  • 动态链接

    • 静态链接可以让模块单独开发测试,但是每个程序内部都需要包含所有的模块,占用空间很大;如果两个程序都需要同一个模块,那么静态链接会有两个重复的模块都在内存中;再者,程序中模块更新,程序就要重新链接发布。
    • 动态链接同样也是将程序分模块,但是不再静态链接在一起,而是在运行时才链接在一起。
    • 动态链接还有一个特点是:可以在运行时动态选择加载各种程序模块。动态链接还可以加强程序的兼容性,在两个机器上printf()不同,那么只需要加载不同的运行库,而不是编译两套程序。
  • 基本实现

    • 一个小例子: 将lib.c文件编译为共享对象文件(Linux下动态链接文件,windows下叫动态链接库),调用库中的foobar()函数。
    • 编译过程如下:
    • 我们可以看到,上面Lib.c独立编译链接成了Lib.so,而好像Program1.o在链接的时候也用到了Lib.so,这是怎么回事呢?是因为在这一步,普通的静态链接会将地址等重定位,而他需要确定foobar()是一个动态链接的函数(在Lib.so中定义了foobar的符号),而标记为一个动态链接符号,在运行前装载时再确定地址。
    • 动态链接so文件也是ELF文件,起始地址是0x00000000,是无效的,所以说明最终装载地址在编译时是不确定的。
  • 地址无关代码

    • 共享对象的装载地址,很早以前是固定的,很多弊端。现在是会被分配到不同地址。而可执行文件基本可以确定自己在进程虚拟空间的起始位置(这里不是很明白),因为可执行文件往往是第一个被加载的文件,它可以选择一个固定空闲的地址,比如 Linux下般都是0x08040000, Windows下一般都是0x0040000。
    • 为了能让共享对象在任意地址装载,可以装载时重定位,装载地址确定了之后,系统对程序中所有动态链接地址进行重定位。但是有一个问题:动态模块装载至虚拟空间后,重定位会修改指令部分,比如一些模块间的调用,而同一份指令不能被多个进程共享。(为啥???)
    • 解决办法之一是地址无关代码(PIC Position-independent Code)。基本想法就是把指令中那些需要被修改的部分分离出来,跟数据部分放在一起,这样指令部分就可以保持不变,而数据部分可以在每个进程中拥有一个副本。
    • 有几种地址引用,一种是内部的函数调用、数据访问等,这个编译时按照相对寻址,所以不用加载也可以确定。另一种是外部的模块间的函数调用、数据访问等,这就涉及到这些模块都加载到什么位置了,编译时是无法确定的,那么可以将地址信息剥离,放进数据部分,怎么做呢?把这些地址放进一个全局偏移表(Global Offset Table),指令中通过间接引用,执行表中对应位置。
    • GOT是放在数据部分的,在模块加载时呗修改,每个进程的有独立的副本,互不影响,则代码部分做法哦了地址无关
    • 地址无关代码的编译参数是 -fPIC。
    • 使用装载时重定位方式的共享对象比地址代码无关的共享对象,运行时要快一些,因为少了一个间接地址寻址的过程。
  • 延迟绑定

    • 动态链接机制下,可能包含大量的函数调用,但不一定都会用得到,但动态链接过程很费事儿。所以在函数第一次被用到的时候才进行绑定。
  • 动态链接过程

    • 动态链接器自举,自举就是自己加载自己。
    • 然后将可执行文件和链接器的符号表合并,形成全局符号表。然后寻找依赖的共享对象。然后一个个加载,首先打开相应so文件,读取ELF头和.dynamic段,将相应的代码段和数据段映射到进程空间。
    • 如果这个共享对象还依赖其他的共享对象,则再进行加载。本质上是一个图,可以使用广度优先搜索的方式进行加载。
    • 每个对象的符号表都会被合并进全局符号表。
    • 上述完成后,动态链接器会对每一个共享对象的重定位表,将每个需要重定位的位置进行修正。
  • 显式运行时链接

    • 支持动态链接的系统往往都支持一种更加灵活的模块加载方式,叫做显式运行时链接
      ( Explicit Run-time Linking)
      ,有时候也叫做运行时加载。也就是让程序自己在运行时控制加载指定的模块,并且可以在不需要该模块时将其卸载。0

七、Linux共享库的组织

  • 共享库与共享对象从文件结构上来讲没什么差别,Linux下就是ELF的共享对象。
  • 命名一般以libname.so.x.y.z 或者 libname-x-y-z.so 。x为主版本号,y为次版本号,z为发布版本号。主版本号之间不兼容,次版本兼容,增量升级。
  • 共享库的路径一般是 /lib - 系统, /usr/lib - 非系统开发, /usr/local/lib - 第三方。
  • 环境变量: LD LIBRARY PATH。

阿龙的学习笔记---《程序员自我修养-链接、装载与库》读书笔记(三)相关推荐

  1. 《程序员自我修养》第七章读书笔记

    书还是接上回,本篇主要对第七章的相关内容进行总结.第七章主要对动态链接的相关内容进行分析. 7.1 为什么要动态链接 既然要对动态链接进行分析,首先应对动态链接出现的原因进行一个简单的分析.动态链接从 ...

  2. 《程序员的自我修养-链接-装载与库》第三章 目标文件里有什么(1)

    目录 0.引言 1.目标文件的格式 1.1 目标文件的格式及ELF文件格式的文件的分类 1.2 目标文件与可执行文件格式的小历史 2.目标文件是什么样的 2.1 程序与目标文件简介 2.2 BSS历史 ...

  3. 【《程序员的自我修养---链接装载于库》读书笔记】可执行文件的装载与进程

    系列文章目录 [<程序员的自我修养-链接装载于库>读书笔记]初探ELF [<程序员的自我修养-链接装载于库>读书笔记]windows PE/COFF [<程序员的自我修养 ...

  4. 阿龙的学习笔记---《程序员自我修养-链接、装载与库》读书笔记(一)

    记录笔记,因为看了好久还没看完-真的是,但是虽然后面的没看完,但我前面的页快忘完了呀,记录一下吧还是. 一. 温故而知新 从计算机组成原理之类的开始讲,说明这部分还是蛮重要的,虽然也快忘完了. 讲到操 ...

  5. 程序员自我修养之链接

    我最近在看PE文件,稍后可能需要dll这些所以顺带看看链接.太久不看这些书,你问我链接是干什么的,我可能会说就是分模块时候用啊,因为一个项目有很多模块,不能写在同一个文件下,所以要把它们链接起来,链接 ...

  6. 程序员自我修养》系统调用与API

    什么是系统调用 在现代的操作系统里,程序运行的时候,本身是没有权利访问多少系统资源的.由于系统有限的资源有可能被多个不同的应用程序同时访问,因此,如果不加以保护,那么各个应用程序难免产生冲突.所以现代 ...

  7. 程序员自我修养的那些事儿

    本篇博客主要是:程序员的自我修养-链接.装载与库的一些学习笔记与心得. 1.首先得注意最大的坑:这本书基于32位系统讲解,因此跟着书本的例子操作一遍的时候,记得要在32位的系统上进行,否则可能出现以下 ...

  8. 一个Java工程师的自我修养_程序员自我修养

    毕业N年,每个人在能力跑道上,有了或大或小的差距.有些人一直在重复的劳动,有些人却能从中总结和解决问题.通过成长日活动,我们或许可以探讨下,怎样共同成长.共同前行,跟"勤奋战术掩盖下的战略懒 ...

  9. 程序员自我修养-总结 (2)

    Segment 是从装载的角度重新划分了 ELF 的各个段,在将目标文件链接成可执行文件的时候,链接器会尽量把相同权限属性的段分配在同一空间.比如可读可执行的段都放一起,如代码段.系统正是按 Segm ...

最新文章

  1. ELASTIC的备份与恢复
  2. conda init 关闭和重启shell_TP5实战源码 通过shell建立PHP守护程序
  3. Vivado ILA无法触发,点Stop Trigger提示There are no armed ILAs
  4. anki 插入表格_Anki之导出卡牌组到Excel文件
  5. 《从零开始学keras之神经风格迁移
  6. (34)FPGA原语设计(BUFGMUX)
  7. shell学习笔记 (9.1)
  8. s和jquery设置disabled属性为true使按钮失效
  9. python基础笔记(六)_数据清洗及建模
  10. 微信读书 iOS 性能优化总结
  11. 脉冲耦合神经网络(PCNN)的python实现
  12. Android多媒体详解
  13. 关于前辈RPC学习的经验分享:我的DedSec RPC
  14. 东芝笔记本出现w ndows,夏日白色清新范 13.3英寸东芝L830评测
  15. 解决ios手机vue H5页面输入键盘收起后页面回弹到顶部问题
  16. 地理生物结业考_不到30天,初二学年地理、生物结业考试开考,老师们说……...
  17. 用python输出沙漏_2018-2019寒假作业 其一 打印沙漏
  18. leetcode 1884-鸡蛋掉落-两枚鸡蛋
  19. UI设计培训技术教程之字体排版规则
  20. 移动通信第六章,多址技术

热门文章

  1. 硬件PM系列(二):硬件产品经理需要熟知的设计流程
  2. 利用随机森林对特征重要性进行评估 方法一
  3. 音频传输之Jitter Buffer设计与实现
  4. The last packet successfully received from the server was 1,072 milliseconds ago. The last packet s
  5. 湖北省专科计算机竞赛,NOI信息学竞赛2019年湖北省队名单
  6. 2021必看,今日教学:RestTemplate-结合-Ribbon-使用
  7. Orleans----Grain(Grain Lifecycle)
  8. QUECTEL上海移远4G通讯CAT4模组EC20CEFAG模块串口调试指南之【05EC20模组TCP/IP模块AT指令说明】
  9. 记录一下大三暑假来广州的实习生活
  10. 背书吧 2021.1.10日记