ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

基本修养实战篇(九) 动态链接之地址无关码【进行中】

2021-10-22 09:01:14  阅读:185  来源: 互联网

标签:定位 实战篇 静态 装载 修养 进程 动态 链接


前面讲了静态链接有一些优化手段可以减少生成目标的体积。但是不同的目标文件中还是始终都会存在同一个静态库文件。这就是比较麻烦的事情了,静态链接至此也无能为力了。另外,如果程序是依赖静态库的,那如果日后静态库一旦更新,整个程序就要重新编译发布。想像一下,王者荣耀那么大的程序,如果每次修复了某个简单的bug, 但是却要你一次动辄下载更新几个G的文件,用户是断然不同意的。这个时候,动态链接的技术就登场了。

动态链接,本质上是把链接器的工作,揽过来由操作系统来做。也就是说,对于现代操作系统,支持动态链接时它的一个基本功能和特性,我们所希望的一个库多个进程共享,这种事情,想想就知道得操作系统来做。

其工作原理是这样的,首先是模块不再被编译成静态库,而是通过 -shared 和 -fPIC选项,告诉编译器我们要编一个动态库。链接器在链接时,发现我们的主程序引用了一个符号,这个符号定义在动态共享对象中(Dynamic Shared Object), 这样链接器就会把它标记成一个动态链接的符号,不对它进行地址重定位,把这个工作留到装载的时候由操作系统来完成。由此可见,这里涉及到了编译器,链接器和操作系统的合作。


 

动态链接程序运行时的地址空间分布:

 

 这个时候,有一个问题浮现了,共享对象在被装载时,如何确定它在进程虚拟地址空间中的位置?

这个时候就需要装载时重定位了。静态链接时的重定位叫做链接时重定位,这里的是装载时重定位。

但是还有一个比较严重的问题,那就是动态链接模块被装载到进程的虚拟空间中后,指令部分是要在多个进程之间共享的(节约空间占用),但是呢装载时重定位如果直接修改指令中重定位的部分,会导致别的进程没办法使用。又或者,一个进程修改了so的某个static的变量,那别的进程也要跟着受到牵连。我们之前做过一个实验,两个程序都去改一个so的某个static变量,发现互不影响,那么这是怎么做到的呢?

这里就要引入一个新概念了,叫做地址无关码。其核心思想是指令部分不变,数据部分,每个进程一个副本。

然后,在一个进程的虚拟地址空间中,我们来看一下其典型的内存布局。

 

 可以看到这个地方用的是映射,不会把系统装载过的库再装载一遍。

 

标签:定位,实战篇,静态,装载,修养,进程,动态,链接
来源: https://www.cnblogs.com/Arnold-Zhang/p/15437110.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有