动态装载简介

动态装载包括两个功能,一个是应用程序和系统的分离,第二个是动态库和内核模块的支持,两者机制相似

动态装载有两个特点:

  • 位置无关码
  • 进程间共享代码段,而又有独立的数据段

其中,位置无关比较容易实现,而有独立的数据段需要硬件支持才行

1.位置无关码的实现
首先,位置无关码通过引入.GOT.PLT来实现对 外部全局变量 或者 外部函数的引用,在访问.GOT.PLT时用的都是相对跳转,然后再.GOT中使用绝对跳转,其中.GOT是在loader装载时完成的填充。由于对.GOT.PLT的访问都是相对跳转,所以这里称之为位置无关码。其实位置相关的工作由loader在装载的时候做了。

2.共用代码段,独立数据段的实现(如果代码段有修改,怎么处理,如何共享)
无论是应用程序还是动态库都面临这个问题。对于应用程序,当两个进程运行同一个应用程序时,可以共享代码段,独立数据段。对于动态库,当两个应用程序都链接这个动态库时,也可以共享代码段,独立数据段。对于位置无关码,前面说了,会借助.GOT.PLT来访问外部全局变量 或者 外部函数,该过程是利用的相对寻址,而且.GOT本身就是数据段的内容,对于动态库,所有链接到动态库的进程都要有一份动态库对应的数据段(包含.GOT表),那么问题来了,我们说代码段共享,而且访问.GOT又是相对跳转,那么基于共享的代码段利用相对跳转,那跳转之后的.GOT不应该都是一个吗?如何实现拥有独立的数据段,这里就需要硬件支持了。

1) 对于拥有MMU的处理器来说,我们将分配出连续的虚拟页给.so的代码段和数据段,这样就能保证相对跳转能够找到.GOT。对于SylixOS系统,不同进程会得到不同的虚拟页地址,对于Linux系统,可能一样也可能不一样,因为每个进程都有自己独立的地址空间。以SylixOS为例,对于两个进程来讲,.so代码段和数据段拥有的虚拟地址空间是连续的,这样就能保证完成.GOT的相对跳转,对于代码段,两个进程映射到相同的物理页面,而数据段映射到不同的物理页面。这样,就能保证代码段共享,数据段独立(无论是全局变量还是.GOT
2) 对于没有MMU平台,比如说C6000系列,为了支持动态加载。引入了DSBT模型


                                        +------------+
                                        |    .so     | index 1
                                        +------------+
                                        |   .text    |
                                        +------------+
                                        |   .data FP |
                                        +--+------+--+
                                           |      |
                                           |      |
                                           |      |
                                           |      |
              +-----------+                |      |                  +-----------+
              |  PROCESS 0|                |      |                  |  PROCESS 1|
  +-----+-----------------+                |      |                  +-----------+
  |     |     |  index 0  |                |      |                  |  index 0  |
  |     |     +-----------+                |      |                  +-----------+
  |     v     |  index 1  <--+-------------+      +---------------+-->  index 1  |
  |    DSBT   +-----------+  |                                    |  +-----------+
  v     ^     |  index ...|  |                                    |  |  index ...|
.DATA   |     +-----------+  |                                    |  +-----------+
.BSS    |     |  index 64 |  |                                    |  |  index 64 |
  ^     +-----------------+  |                                    |  +-----------+
  |           |           |  |                                    |  |           |
  |           |  .....    |  |                                    |  |  .....    |
  |           |           |  |                                    |  |           |
  +-----------+-----------+  |  .so_process 0     .so_process 1   |  +-----------+
                             |  +-----------+     +-----------+   |
                             +-->   .DATA   |     |   .DATA   <---+
                                +-----------+     +-----------+
                                |   .BSS    |     |   .BSS    |
                                +-----------+     +-----------+

通过在进程0 和 进程1 的数据段前加入了.DSBT数据段,该段里面每一个索引项指向了一个数据缓冲区(利用这种方法独立数据段),其中index 1代表了相应的 .so,所有进程的.DSBT中索引位置是一样的,也就是说一个.so对应索引对于所有进程都是相同的,当PROCESS 0 调用 .so中的函数时,.so中的函数会切换DP指针,根据自身索引在PROCESS 0的DSBT表中位置,取出该值并切换DP指针(.so_process 0),此后对数据的访问都是基于DP指针。DP其实就是个数据段的基地址。同理,当PROCESS 1调用.so中的函数,也会切换DP指针,此时DP会指向PROCESS 1中DSBT中index 1的位置,这样DP就会指向PROCESS 1为.so分配出的独立数据段(.so_process 1),这样也实现了数据段的独立。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值