
把加载后的库映射到A进程地址空间里,A就可以用这个动态库了,加载到B,B也能用了。
所以动态库也叫共享库。动态库是如何与我们的可执行程序(即运行中的进程)建立关联的?答案是:通过进程的虚拟地址空间进行关联的。
动态库是如何加载的。
库映射到堆栈之间的共享区。


"动态链接器 (Dynamic Linker) 的核心职责,是在程序运行期间将依赖的动态库加载到内存中。
具体流程是这样的:正如我们刚才所说,程序启动后,它所依赖的动态库也必须被同步加载。这个加载动作是由谁触发的呢?
当操作系统把你的程序跑起来时,最先执行的并不是
main函数,而是程序的底层入口_start函数。在这个启动阶段,程序会自动去调用系统提供的动态加载器(在 Linux 中通常是ld-linux.so)。由这个加载器接管控制权,去硬盘上找到你程序所需的动态库,并把它们加载映射到进程的虚拟地址空间里。完成这些准备工作后,才会真正开始执行你写的业务代码。"


"好,我们来总结一下。动态库里的函数,其在库内部的编址方式全部都是相对偏移量。
这与我们的可执行程序主体 是不同的。传统的可执行程序在加载到虚拟地址空间时,往往有一个固定的加载基址(讲师为了简化模型,比喻为0号地址)。因为它的位置是固定的,所以它内部的函数可以直接使用写死的绝对地址,刚好与虚拟地址直接吻合。
但是,动态库不能固定位置。它会被操作系统动态映射到虚拟地址空间'共享区'的任意空闲位置。> 那么我们怎么访问动态库里的函数呢?非常简单:无论动态库被映射到了哪个位置,它都会获得一个起始虚拟地址(基址) 。我们只需要拿这个起始地址 + 目标方法在库里的偏移量,就能算出这个函数在当前进程中的绝对物理/虚拟地址了。
结论就是:因为使用了偏移量,动态库在地址空间里可以随便映射。只要运行时能获取到它的起始基址,我们就能准确无误地调用库当中的任何方法了。"

可执行程序不是从0开始,静态链接是直接填,动态链接都要算
静态链接之后就不是从零开始,动态链接之后。so还是从0开始
从0开始也就相当于偏移量,映射到物理内存直接加上基地址就是虚拟地址
当前进程加载时候,进程初始化,加载时候 ,把进程代码数据先加载进来,执行------start需要执行动态连接器的方法,识别到程序依赖c标准库,所以要访问c标准库了,就要先找到这个库,肯定能找到,elf内符号表会记录我这个库依赖的路径,所以编译链接 所以要告诉-I -L -l 要告诉编译时库得的路径,在编译时指定,指定之后,程序就知道了,路径也知道了,就能打开库,根据struct file找到dentry inode datablock 把动态库加载到内存,嘉爱进来之后,动态库内的方法也是采用绝对编制的,我们当成库中方法偏移量,库因为有大小,我们现在要映射到内存地址空间,创建vmstruct把这个节点插入链表当中,用库大小初始化start end,库映射到地址空间后,就一定能得到库的虚拟地址,加上所有方法偏移量就能访问库。
vmsttruc内有个指针指向文件,就能通过path找到dentry就有目录结构,就找到inode就鞥能找到iblock找到动态库,就能把动态库加载进来建立起映射关系


库名字用起始地址家偏移量替换掉,就完成了


