26(下).库的理解与加载

把加载后的库映射到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找到动态库,就能把动态库加载进来建立起映射关系

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

相关推荐
别动我齐刘海1 小时前
C++ 工程化学习
java·linux·前端·c++·学习·机器学习·机器人
wewowilling3 小时前
认识微服务
java·运维·微服务·springcloud
玖石书3 小时前
Ubuntu 24.04 UFW 全命令攻略:从入门到端口开放实战
linux·运维·ubuntu
xiaoqiMikko3 小时前
Linux 实战(七):useradd、sudoers、umask、SGID、软链 —— 三台真机实测
linux·centos
weifont5 小时前
自动化抓取和上架商品:能不动手,就少动手
运维·前端·自动化
拂拉氏5 小时前
【知识讲解】 Linux之动静态库的了解
linux·运维·服务器·动静态库
Fcy6485 小时前
Linux下 五种IO模型的认识与⾮阻塞IO的实现
linux·服务器·io
Mikko76 小时前
Linux 重启后日志没了?进程被 OOM 杀了去哪看?logrotate 之后日志还往旧文件写?三台真机实测日志与性能排查
linux·运维·centos
书生执笔画浮沉6 小时前
分享一个开源小工具CAdapt
linux·c·gnu·glibc·kernel·升级·灵感
光依旧6 小时前
发版就掉请求?Spring Boot优雅停机的四步
运维·spring boot·nginx·高可用·优雅停机·mcp server