【Linux】程序地址空间之动态库的加载

我们先进行一个整体轮廓的了解,随后在深入理解细节。
在动态库加载之前还要说一下程序的加载,因为理解了程序的加载对动态库会有更深的理解。

轮廓:

首先,不管是程序还是动态库刚开始都是在磁盘中的,想要执行对应的可执行程序或者编译都需要一个指定的路径才可以找到。他就像我们现实生活中的地址,当然这些对我们程序地址空间的影响不大,主要是因为路径太重要了,进行一下强调。

在这里插入图片描述
从图中可以比较清晰的看到动态库加载的简略行为,随后在执行到库函数的地方时跳转到共享区,执行完在跳转回来即可。
可是这个库只会被一个进程使用吗?

我们看到一个动态库可能会被多个进程同时使用
在这里插入图片描述
所以当我们由另外的进程时,不需要重新加载动态库了,只要用现成的,直接使用页表映射即可。因为他能被多个库同时使用,所以也叫共享库!

程序的加载:

说在前边,程序的加载需要说一大堆预备的知识,最后才能进行串起来。

我们谈这个之前先想一个问题:我们编译好的程序的二进制代码中会有“地址”吗?
我们验证一下:
在这里插入图片描述
对此文件进行一下objdump -S code(反汇编)
在这里插入图片描述
可以看到其中就已经存在一种类似地址的东西了。

同时我们进行size可以看到这个可执行程序已经分好了各种区域,类似我们mm_struct中的地址空间划分。
在这里插入图片描述
那我们在程序中定义的变量名也理所当然的变为了地址。

至此我们知道了可执行程序中存在地址与空间划分了

linux中生成的可执行程序格式叫做ELF。
这个二进制可执行程序有自己固定的格式,elf可执行程序的头部有着自己的属性。
另外我们的文件经过编译后,有很多的汇编语句,我们已经见到过了,这是什么地址呢?是如何进行编址?

先回答第二个问题
我们在编址时一般有两种:其一是相对编址;其二是绝对编址。

相对编址时,使用起始地址加上对应的偏移量
在这里插入图片描述
绝对编址:
在这里插入图片描述
绝对编址就是我们本身的方式,也叫做平坦模式,所以整体是线性增长的。
同时我们也可以认为这其实就是虚拟地址

所以我们的汇编程序中就已经存在虚拟地址了。

此时我们还需要设计一个东西叫做加载器:
在这里插入图片描述
我们会先把加载器的库加载到内存中,执行库中的方法将可执行程序拷贝到内存,加载器对可执行程序的头部进行解释。可以得到main函数的地址。

所以 ELF + 加载器 = 各个区域中的起始位置与结束位置 + main函数地址。

现在我们基本就将预备知识铺垫的差不多了。

可以进入主线了。
我们常说进程 = 内核数据结构+代码和数据。
那么当我们执行一个程序时是先创建内核数据结构还是先将文件加载到内存中呢?
我们这样想:当你被学校录取后,你是开学到了学校才是这个学校的学生还是当志愿填报结束你得到了被录取的信息才是呢?
答案是显然的,当你收到了录取通知就已经是学校的学生了。

那我们进程也是先有内核数据结构在加载程序。
那我们就要开始创建内核数据结构了。
在这里插入图片描述
我们的mm_struct是一个对象,其中有成员变量,变量的初始值是什么?
我们的可执行程序中就已经提供了对应的分配好了各个地址,就可以去填充了。

所以虚拟地址空间这个概念不是OS独有的,是由OS+编译器+加载器一起构成的。

我们不会提到一个没有用的事物,对于main函数的地址我们该怎么用呢?
我们的CPU中有一个PC指针,他保存的是当前执行指令的下一条虚拟地址。
在最开始的时候就是main的地址。这是很关键的一环。

所以我们要开始加载程序到内存咯。
在这里插入图片描述

尽管我们的程序中有自己的虚拟地址,但是加载到物理内存中仍然会有属于自己的物理地址。

那我们现在就需要将mm_struct与内存进行连接起来,那就是页表!
在这里插入图片描述
我们现在开始运行!
根据PC指针的值去页表中映射对应的物理地址,拿到指令去执行,循环往复就执行起来啦!

这就是程序加载的过程。
我们只要分为两个阶段看就会好一点

  1. 内核数据结构的创建
  2. 程序的加载

还有额外的预备知识~

动态库的加载:

持续更新~

相关推荐

  1. linux动态

    2024-06-12 10:58:07       18 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-06-12 10:58:07       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-06-12 10:58:07       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-06-12 10:58:07       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-06-12 10:58:07       20 阅读

热门阅读

  1. C++算法——埃氏筛

    2024-06-12 10:58:07       7 阅读
  2. 安全通告:NGINX HTTP/3 QUIC 漏洞

    2024-06-12 10:58:07       7 阅读
  3. 切换到root用户的方法和区别

    2024-06-12 10:58:07       9 阅读
  4. Git最全管理详解

    2024-06-12 10:58:07       8 阅读
  5. STM32 UART 错误代码 HAL_UART_ERROR_PE

    2024-06-12 10:58:07       7 阅读
  6. 实现EM算法的主循环

    2024-06-12 10:58:07       7 阅读
  7. go语言接口之http.Handler接口

    2024-06-12 10:58:07       8 阅读
  8. 富格林:活用经验可信提高出金

    2024-06-12 10:58:07       7 阅读
  9. 力扣1146.快照数组

    2024-06-12 10:58:07       11 阅读
  10. C++中的享元模式

    2024-06-12 10:58:07       9 阅读