【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. 程序的加载

还有额外的预备知识~

动态库的加载:

我们的动态库编译好之后和可执行程序基本是一样的,也有自己的地址。
,只不过没有main的地址罢了。
在这里插入图片描述

先来画一个图。
假设我们的代码中有一个调用库中的代码Add。
在这里插入图片描述

当我们执行到Add时,此时我们的动态库还没加载,那么当然就需要将动态库也加载到内存,同时映射到虚拟地址空间。
在这里插入图片描述

这里有一个细节,我们程序加载到内存映射到地址空间时,只有一个虚拟地址,直接就是二进制程序提供的。可是此时我们的虚拟地址有两份,一个是库中我们要调的函数的地址,一个是mm_struct中动态库的地址。

实际上库中的函数地址就是库函数地址为0的偏移量,当想要访问到库函数时,我们就需要知道他的地址,他的地址就是两者的相加:0x5555+0x1111=0x6666。
所以有了地址我们就可以动态库的函数了,也就是跳转到共享区,执行完毕再跳回来。

所以这个地址被映射到虚拟地址空间的那个位置重要吗?
并不重要,所以制作动态库时需要-fPIC,叫做与地址无关码!


可是我们加动态库时怎么知道有没有被加载?
同时动态库还要存在多份。

所以就需要管理:所以就要有对应的描述结构体与组织他的数据结构(比如链表)。
当我们加载时先遍历一遍观察是否已经加载,有的话直接映射,没有的话就加载…

到此完毕~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/713862.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

PHP在线生成查询产品防伪证书系统源码

源码介绍 PHP在线生成查询产品防伪证书系统源码,源码自带90套授权证书模板,带PSD公章模板,证书PSD源文件。 环境要求:PHPMYSQL,PHP 版本请使用PHP5.1 ~5.3。 图片截图 源码安装说明 1.上传所有文件至你的空间服务器…

学会python——显示进度条(python实例五)

目录 1、认识Python 2、环境与工具 2.1 python环境 2.2 Visual Studio Code编译 3、进度条显示 3.1 代码构思 3.2 代码示例 3.3 运行结果 4、总结 1、认识Python Python 是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。 Python 的设计具有很强的可读…

从零到爆款:用ChatGPT写出让人停不下来的短视频文案

一、前言 在自媒体的浪潮中,精彩的短视频文案对内容传播至关重要。众多辅助工具之中,凭借强大的语言处理能力和广泛的应用场景,ChatGPT成为了内容创作者的重要助力。接下来,我将介绍如何借助ChatGPT编写引人入胜的短视频文案&…

积木搭建游戏-第13届蓝桥杯省赛Python真题精选

[导读]:超平老师的Scratch蓝桥杯真题解读系列在推出之后,受到了广大老师和家长的好评,非常感谢各位的认可和厚爱。作为回馈,超平老师计划推出《Python蓝桥杯真题解析100讲》,这是解读系列的第83讲。 积木搭建游戏&…

Windows10 利用QT搭建SOEM开发环境

文章目录 一. SOEM库简介二. 安装WinPcap三. SOEM(1.4)库安装(1) 编译32位库(2) 编译64位库 四. 运行SOEM示例代码五. WIN10下利用QT构建SOEM开发环境 一. SOEM库简介 SOEM(Scalable Open EtherCAT Master 或 Simple Open EtherCAT Master)是一个开源的…

【OrangePiKunPengPro】 linux下编译、安装Boa服务器

OrangePiKunPengPro | linux下编译、安装Boa服务器 时间:2024年6月7日21:41:01 1.参考 1.boa- CSDN搜索 2.Boa服务器 | Ubuntu下编译、安装Boa_ubuntu安装boa-CSDN博客 3.i.MX6ULL—ElfBoard Elf1板卡 移植boa服务器的方法 (qq.com) 2.实践 2-1下载代码 [fly752fa…

python将数据保存到文件的多种实现方式

🌈所属专栏:【python】✨作者主页: Mr.Zwq✔️个人简介:一个正在努力学技术的Python领域创作者,擅长爬虫,逆向,全栈方向,专注基础和实战分享,欢迎咨询! 您的…

EasyRecovery2024数据恢复神器#电脑必备良品

EasyRecovery数据恢复软件,让你的数据重见天日! 大家好!今天我要给大家种草一个非常实用的软件——EasyRecovery数据恢复软件!你是不是也曾经遇到过不小心删除了重要的文件,或者电脑突然崩溃导致数据丢失的尴尬情况呢&…

手机照片免费数据恢复软件EasyRecovery2024免费版下载

大家好!今天我要给大家推荐一款非常棒的软件——EasyRecovery。相信大家都知道,电脑中的重要文件一旦丢失,对我们的工作和学习都会产生很大的影响。 而EasyRecovery软件就是专门解决这个问题的利器!它能够帮助我们快速、有效地恢…

第三篇—基于黑白样本的webshell检测

本篇为webshell检测的第三篇,主要讲的是基于黑白样本的webshell预测,从样本收集、特征提取、模型训练,最后模型评估这四步,实现一个简单的黑白样本预测模型。   若有误之处,望大佬们指出 Ⅰ 基本实现步骤 样本收集&…

Unity中的伽马(Gamma)空间和线性(Linear)空间

伽马空间定义:通常用于描述图像在存储和显示时的颜色空间。在伽马空间中,图像的保存通常经过伽马转换,使图片看起来更亮。 gamma并不是色彩空间,它其实只是如何对色彩进行采样的一种方式 为什么需要Gamma: 在游戏业…

53. QT插件开发--插件(动态库so)的调用与加载

1. 说明 在使用QT进行插件库的开发之后,还需要将这个插件库程序生成的so动态链接库加载到主程序框架中进行使用,才能达到主程序的模块化开发的效果。在前一篇文章插件创建中介绍了如何在QT中开发插件库,并提供外部接口调用。本篇博客的主要作用是模拟在主程序框架中加载动态…

诊断丢帧:发送端连续帧发送过快,导致接收端丢帧

项目场景: 在项目开发过程中,对于报文的接收/发送,一般来说,通信量大,选择Polling(轮询)处理模式;通信量小,选择Interrupt(中断)处理模式。具体选择没有优劣之分。结合项目的实际情况,选择适合项目的方式就好。小编将分享一个Polling模式下出现的丢帧现象。 1576…

Docker镜像技术剖析

目录 1、概述1.1 什么是镜像?1.2 联合文件系统UnionFS1.3 bootfs和rootfs1.4 镜像结构1.5 镜像的主要技术特点1.5.1 镜像分层技术1.5.2 写时复制(copy-on-write)策略1.5.3 内容寻址存储(content-addressable storage)机制1.5.4 联合挂载(union mount)技术 2.机制原理…

C# WPF入门学习主线篇(十五)—— DockPanel布局容器

C# WPF入门学习主线篇(十五)—— DockPanel布局容器 欢迎来到C# WPF入门学习系列的第十五篇。在前几篇文章中,我们探讨了 Canvas、StackPanel 和 WrapPanel 布局容器及其使用方法。本篇博客将介绍另一种强大且常用的布局容器——DockPanel。…

打造成功的人力RPO项目:赢得市场赚取利润

人力资源外包(RPO)项目是当今企业在招聘和人才管理方面越来越倾向的选择。想要通过人力RPO项目赚钱,以下是一些关键的策略和步骤,帮助您进入这个市场并取得成功。 1. 建立专业的人力RPO服务 首先,要想在人力RPO项目中赚钱,必须建立…

HCIA11 网络安全之本地 AAA 配置实验

AAA 提供 Authentication(认证)、Authorization(授权)和 Accounting(计费)三种安全功能。 • 认证:验证用户是否可以获得网络访问权。 • 授权:授权用户可以使用哪些服务。 •…

AOP切面加自定义注解,实现日志记录

AOP切面加自定义注解,实现日志记录 一、AOP二、准备工作三、添加AOP,把日志保存到数据库 一、AOP 在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实…

debug调试高级功能 断点、布局 及Android Studio常用快捷按键使用详情

文章目录 debug断点篇:打临时断点(只用一次):alt断点条件断点:在断点上,点击右键,在Condition那里,设置我们需要的值,循环就会自动停到我们设置的那个值那里依赖断点&…

Markdown如何分页操作

Markdown导出分页操作 在平时的文档导出过程中Markdown过程中会出现因为不能分页导致的排版问题。 排版问题在将Markdown文档导出为PDF或其他格式时尤为明显。当文档内容超过一页时,无法自动调整页面布局,导致内容不连续,甚至导致图片或表格…