阿龙的学习笔记---《程序员自我修养-链接、装载与库》读书笔记(三)
六、动态链接
动态链接
- 静态链接可以让模块单独开发测试,但是每个程序内部都需要包含所有的模块,占用空间很大;如果两个程序都需要同一个模块,那么静态链接会有两个重复的模块都在内存中;再者,程序中模块更新,程序就要重新链接发布。
- 动态链接同样也是将程序分模块,但是不再静态链接在一起,而是在运行时才链接在一起。
- 动态链接还有一个特点是:可以在运行时动态选择加载各种程序模块。动态链接还可以加强程序的兼容性,在两个机器上printf()不同,那么只需要加载不同的运行库,而不是编译两套程序。
基本实现
- 一个小例子: 将lib.c文件编译为共享对象文件(Linux下动态链接文件,windows下叫动态链接库),调用库中的foobar()函数。
- 编译过程如下:
- 我们可以看到,上面Lib.c独立编译链接成了Lib.so,而好像Program1.o在链接的时候也用到了Lib.so,这是怎么回事呢?是因为在这一步,普通的静态链接会将地址等重定位,而他需要确定foobar()是一个动态链接的函数(在Lib.so中定义了foobar的符号),而标记为一个动态链接符号,在运行前装载时再确定地址。
- 动态链接so文件也是ELF文件,起始地址是0x00000000,是无效的,所以说明最终装载地址在编译时是不确定的。
- 一个小例子: 将lib.c文件编译为共享对象文件(Linux下动态链接文件,windows下叫动态链接库),调用库中的foobar()函数。
地址无关代码
- 共享对象的装载地址,很早以前是固定的,很多弊端。现在是会被分配到不同地址。而可执行文件基本可以确定自己在进程虚拟空间的起始位置(这里不是很明白),因为可执行文件往往是第一个被加载的文件,它可以选择一个固定空闲的地址,比如 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。
阿龙的学习笔记---《程序员自我修养-链接、装载与库》读书笔记(三)相关推荐
- 《程序员自我修养》第七章读书笔记
书还是接上回,本篇主要对第七章的相关内容进行总结.第七章主要对动态链接的相关内容进行分析. 7.1 为什么要动态链接 既然要对动态链接进行分析,首先应对动态链接出现的原因进行一个简单的分析.动态链接从 ...
- 《程序员的自我修养-链接-装载与库》第三章 目标文件里有什么(1)
目录 0.引言 1.目标文件的格式 1.1 目标文件的格式及ELF文件格式的文件的分类 1.2 目标文件与可执行文件格式的小历史 2.目标文件是什么样的 2.1 程序与目标文件简介 2.2 BSS历史 ...
- 【《程序员的自我修养---链接装载于库》读书笔记】可执行文件的装载与进程
系列文章目录 [<程序员的自我修养-链接装载于库>读书笔记]初探ELF [<程序员的自我修养-链接装载于库>读书笔记]windows PE/COFF [<程序员的自我修养 ...
- 阿龙的学习笔记---《程序员自我修养-链接、装载与库》读书笔记(一)
记录笔记,因为看了好久还没看完-真的是,但是虽然后面的没看完,但我前面的页快忘完了呀,记录一下吧还是. 一. 温故而知新 从计算机组成原理之类的开始讲,说明这部分还是蛮重要的,虽然也快忘完了. 讲到操 ...
- 程序员自我修养之链接
我最近在看PE文件,稍后可能需要dll这些所以顺带看看链接.太久不看这些书,你问我链接是干什么的,我可能会说就是分模块时候用啊,因为一个项目有很多模块,不能写在同一个文件下,所以要把它们链接起来,链接 ...
- 程序员自我修养》系统调用与API
什么是系统调用 在现代的操作系统里,程序运行的时候,本身是没有权利访问多少系统资源的.由于系统有限的资源有可能被多个不同的应用程序同时访问,因此,如果不加以保护,那么各个应用程序难免产生冲突.所以现代 ...
- 程序员自我修养的那些事儿
本篇博客主要是:程序员的自我修养-链接.装载与库的一些学习笔记与心得. 1.首先得注意最大的坑:这本书基于32位系统讲解,因此跟着书本的例子操作一遍的时候,记得要在32位的系统上进行,否则可能出现以下 ...
- 一个Java工程师的自我修养_程序员自我修养
毕业N年,每个人在能力跑道上,有了或大或小的差距.有些人一直在重复的劳动,有些人却能从中总结和解决问题.通过成长日活动,我们或许可以探讨下,怎样共同成长.共同前行,跟"勤奋战术掩盖下的战略懒 ...
- 程序员自我修养-总结 (2)
Segment 是从装载的角度重新划分了 ELF 的各个段,在将目标文件链接成可执行文件的时候,链接器会尽量把相同权限属性的段分配在同一空间.比如可读可执行的段都放一起,如代码段.系统正是按 Segm ...
最新文章
- ELASTIC的备份与恢复
- conda init 关闭和重启shell_TP5实战源码 通过shell建立PHP守护程序
- Vivado ILA无法触发,点Stop Trigger提示There are no armed ILAs
- anki 插入表格_Anki之导出卡牌组到Excel文件
- 《从零开始学keras之神经风格迁移
- (34)FPGA原语设计(BUFGMUX)
- shell学习笔记 (9.1)
- s和jquery设置disabled属性为true使按钮失效
- python基础笔记(六)_数据清洗及建模
- 微信读书 iOS 性能优化总结
- 脉冲耦合神经网络(PCNN)的python实现
- Android多媒体详解
- 关于前辈RPC学习的经验分享:我的DedSec RPC
- 东芝笔记本出现w ndows,夏日白色清新范 13.3英寸东芝L830评测
- 解决ios手机vue H5页面输入键盘收起后页面回弹到顶部问题
- 地理生物结业考_不到30天,初二学年地理、生物结业考试开考,老师们说……...
- 用python输出沙漏_2018-2019寒假作业 其一 打印沙漏
- leetcode 1884-鸡蛋掉落-两枚鸡蛋
- UI设计培训技术教程之字体排版规则
- 移动通信第六章,多址技术
热门文章
- 硬件PM系列(二):硬件产品经理需要熟知的设计流程
- 利用随机森林对特征重要性进行评估 方法一
- 音频传输之Jitter Buffer设计与实现
- The last packet successfully received from the server was 1,072 milliseconds ago. The last packet s
- 湖北省专科计算机竞赛,NOI信息学竞赛2019年湖北省队名单
- 2021必看,今日教学:RestTemplate-结合-Ribbon-使用
- Orleans----Grain(Grain Lifecycle)
- QUECTEL上海移远4G通讯CAT4模组EC20CEFAG模块串口调试指南之【05EC20模组TCP/IP模块AT指令说明】
- 记录一下大三暑假来广州的实习生活
- 背书吧 2021.1.10日记