为什么需要动态链接?

问题

不同的程序中,有可能存在调用相同的基础库,内存加载程序的时候是否把这些共享库都加载一次?

动态链接

上次说到的各种内存处理技术:虚拟内存、内存交换、内存分页等等都是为了解决内存不足的情况。

多个程序通过装载器装载到内存里面,链接好的同样功能的代码,不会去多次加载,通过动态链接来解决这种问题。

静态链接(Static Link):之前提到的合并代码段的方法。

动态链接(Dynamic Link):加载到内存中的共享库(Shared Libraries),会被很多个程序的指令调用到。

在 Windows 下,这些共享库文件就是.dll 文件,也就是 Dynamic-Link Libary(DLL,动态链接库)。在 Linux 下,这些共享库文件就是.so 文件,也就是 Shared Object(一般我们也称之为动态链接库)。

编译出来的共享库文件的指令代码,是地址无关码(Position-Independent Code)。

这段代码,无论加载在哪个内存地址,都能够正常执行。

对于所有动态链接共享库的程序来讲,虽然我们的共享库用的都是同一段物理内存地址,但是在不同的应用程序里,它所在的虚拟内存地址是不同的。

PLT 和 GOT,动态链接的解决方案

要实现动态链接共享库,和前面的静态链接里的符号表和重定向表类似。

PLT:程序链接表(Procedure Link Table)

GOT:全局偏移表(Global Offset Table)

共享库的代码部分的物理内存是共享的,但是数据部分是各个动态链接它的应用程序里面各加载一份的。

我们的 GOT 表位于共享库自己的数据段里。GOT 表在内存里和对应的代码段位置之间的偏移量,始终是确定的。这样,我们的共享库就是地址无关的代码,对应的各个程序只需要在物理内存里面加载同一份代码。而我们又要通过各个可执行程序在加载时,生成的各不相同的 GOT 表,来找到它需要调用到的外部变量和函数的地址。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20200614A0K2EL00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券