动态链接
程序的链接:把对应的不同文件内的代码段,合并到一起,成为最后的可执行文件。让我们在写代码的时候做到了“复用”。
作用:同样的功能代码只要写一次,然后提供给很多不同的程序进行链接就行了
缺点:有很多个程序都要通过装载器装载到内存里面,链接好的同样的功能代码,需要再装载一遍,再占一遍内存空间。
动态链接:需要链接的代码加载到内存中的共享库
在Windows下,这些共享库文件就是.dll文件(Dynamic-Link Libary,动态链接库)
在Linux下,这些共享库文件就是.so文件(Shared Object)
共享代码要求:地址无关(这段代码,无论加载在哪个内存地址,都能够正常执行)
问题:共享库用的是同一段物理内存地址,但在不同应用程序里,它所在的虚拟地址是不同的
解决:通过全局偏移表(GOT,Global Offset Table)
GOT是位于共享库自己的数据段里 (在我们加载一个个共享库的时候写进去的。)
虽然共享库的代码部分的物理内存是共享的,但链接共享库的应用程序的数据部分是不同的
需要引用当前共享库外部的地址的指令,都会查询GOT,来找到当前运行程序的虚拟内存里的对应位置。
不同的进程,调用同样的lib.so,各自GOT里面指向最终加载的动态链接库里面的虚拟内存地址是不同的。
不同的程序调用的同样的动态库,各自的内存地址是独立的,调用的又都是同一个动态库,但是不需要去修改动态库里面的代码所使用的地址,而是各个程序各自维护好自己的GOT,能够找到对应的动态库就好了