【Linux系统编程十八】:(基础IO5)--动静态库共享/动静态加载问题(涉及地址空间)

【Linux系统编程十八】:动静态库共享/动静态加载问题(涉及地址空间)

  • 一.可执行程序如何被加载的
    • 1.加载之前
    • 2.加载之后
      • ①如何执行第一条命令
      • ②缺页中断/与地址空间建立联系
  • 二.动态库如何加载的
  • 三.动态库如何实现多进程间共享的

一.可执行程序如何被加载的

1.加载之前

在这里插入图片描述

我们实际在当前的编译,在编译形成可执行的程序的时候。编译器是要考虑加载的问题的。
它不是说啊我随便编一下就完了啊,不是的,它呢是把可执行程序分段给我们编译好的。

那么分段编译好之后呢,然后它上面在编译的时候,那么相关的字段都会有它对应的地址。
这个地址呢我们可以理解成叫做每一个函数它的入口,每一个变量它的定义,相对于零号地址数对应的一个偏移量。
所以这个地址在我们的程序当中已经存在了。
好,那么我们把这种在可执行程序当中的地址呢,我们其实把它叫做逻辑地址,逻辑地址其实它是一种断地址间偏移的一种表述方式。但其实说白了它已经是虚拟地址了啊,或者叫做线性地址了。

所以这样的程序在没有被加载前,已经内部有地址了。
在这里插入图片描述这些指令每一个它都有地址,它将来都是c p u要去执行的。
那么我们c p u它怎么能够帮我去执行这些指令呢?

c p u呢它其实呢已经在自己被制作的时候,就已经内置了很多能够认识这些基础指令的工作。只不过这些指令都是用二进制制作的,所以呢我们把这种数字二进制的,那么可以提前在c p u内部设置好很多的,我们把它称之为叫做指令集的东西。 也就是在cpu里面呢,你向它对应的一些就是寄存器当中写入这种指令集,它是会被被当做指令或者控制指令来看待的,它不会把它当数据处理的。
所以呢你的c p u呢它就能认识你喂给它的各种各样的这样的汇编。那汇编呢连起来一长啊多一多,它就变成了一种具体的动作。

c p u它要能执行指令,它得先识别指令。
c p u它是能区分清楚哪些是指令,哪些是数据的。

2.加载之后

可执行程序它在加载的内存的时候,它的所有的代码的指令呢,包括函数调用,变量等。
那么已经在我们那么可执行程序里面已经按照e l f这样的可执行程序的格式已经给我们编好了。
它内部的函数跳转时或者是变量寻找时都有它对应的地址。
每个进程还有自己的p c d对象,这就叫task_struct。每一个进程还有自己所对应的叫做地址空间啊
未来呢c p u要执行对应的代码和数据,c p u要执行我们定义的代码和数据的时候,那么我们现在程序已经加入了内存了。
那么我们进程数结构也也创建好了,那么下面我们该如何破局呢?

①如何执行第一条命令

在这里插入图片描述
你c p u执行指令的时候啊,那么如何执行第一条指令呢?关键在于我们对应的可行程序形成的时候,它里面包含了一个e n t r y啊,叫做我们的入口地址。他的可行程序在编译形成的时候,他已经在自己的可行程序里,头部呢提前把自己整个程序的入口地址已经写好了。入口地址是逻辑地址啊,在内存里它就叫做虚拟地址。

所以当我们对应的这个可行程序被加载到内存的时候,那么一方面我们把程序加到内存,当然你也可以不加载啊,因为我们曾经讲过,一一定是先形成内核这部分的,也就是内存储结构先有。
然后呢,我们的可行程序要运行的时候,它其实首先要做的就是把我们这个表当中,我们叫做入口地址拿过来。

在这里插入图片描述

所以呢我们直接在读取这个可行程序时,把对应的入口地址直接load到c p u的寄存器当中。
好,那么录录到c p u的寄存器里面的时候,这个地址因为它这个地址已经是在天然编织的时候,就是一个我们对应的虚拟地址。
所以从c p u就开始执行了。
那么当它开始执行的时候,它就需要从经过我们对应的经过我们对应的页表呢来把我们对应的就是这个地址,很明显就是虚拟地址了。读第一条指令,这个先读到的地址就是虚拟地址。
c p u去执行的时候,发现这个页表当中有没有建立对应的内存,就会触发缺页中断。缺页中断后,我们的程序时候就被加载进来了。

②缺页中断/与地址空间建立联系

它加载到内存的时候,它要不要占据我们对应的叫做词呃物理内存当中的空间呢可执行程序加入到内存的时候,要不要占据那个内存的空间啊?它是需要的啊。那么它是不是也一定会同步的存在?
既然它要占物理内存,所以整个代码或者数据呢或者是各种区域呢,每一条呢它都要有自己对应的物理地址。
当你把对应的可执行程序加载到我们对应的内存之后呢。
啊,加载到我们对应的内存之后,那么每条只有天然的就具备了物理地址。
你要访问的是你内部的地址啊,但是你自己这条指令它有自己的物理地址。
那么所以当我们的程序加载到内存的时候,它每一行指令,它都会有两套地址。
一个叫做我们自己内部所采用的,曾经加载内存之前的叫做逻辑地址啊,那么另一个就是加载物理内存时所具备的物理地址。
加粗样式

好,这个道理呢就好比。你在学校里面。每一个人都有自己的学号。这是在全校范围内给我们编好的。那么可是呢当我们坐在一个具体的教室里面的时候,我可能坐在桌子每一张桌子,比如说五十张桌子编号一到五十。我坐在其中的三号桌子上,那么当我坐在那个桌子上的时候,我就叫做从教室外加载到教室内。那么此时我自己内部用的地址,我自己和我的同学啊,我们之间聊的话,我们用的是学号。可是当我们坐在教室里的时候,我们每一个人桌子上也有对应的地址,我们叫做物理地址。

被加载进来之后,刚刚我说了,一旦你被加载,你的程序天然就具备了物理地址。好,加载的具体地址我就知道了。那么这个天然的物理地址和可执行程序内部的逻辑逻辑地址(也就是虚拟地址)就直接建立映射关系了。

对应的页表里就可以立马填上左侧的虚拟地址和右侧的页表的物理地址。
因为加载之后的程序是有两套地址的。
具体到物理地址这个地址初始化页表,这时页表映射关系瞬间建立。
我们在程序内部,在你的程序内部已经编好的这个虚拟地址,我已经给你搞好了,拿过来用就行了。
所以而且你一站在物理内存上,每一条指令都天然就具备了它的,我们可以称之为物理地址。
所以我们的物理列表一填,同学们此时映射关系就建立好了。

c p u不知道这个指令,发现它是一个函数调用,c p u在读到指令时,你的指令内部用到的地址,告诉我这是什么地址。指令也可能要进行我们对应的寻址了,寻找什么函数的地址,而这个函数地址是什么呢?
没错,这个地址它就是逻辑地址即虚拟地址。
所以直接调用,先在虚拟地址空间里找到我们的新地址,再转成物理地址。
最后再从物理地址转成我们所对应的这个我们对应的这个指令处开始进行
CPU从读取程序当中的地址。
到内部分析处理,到我们最后再重新二次继续访问它。整个过程我们凡是读到的这个指令里面的地址都是虚拟地址。
但c p u真正的要找到你,你再怎么给我虚拟,也找不到,真正的数据在物理地址里,所以这也就不需要虚拟地址转换成物理地址了。

可执行程序,其实它有两个地址,编译器编译的时候就已经考虑虚拟地址空间了。进程在设计的时候就已经考虑了你对应的地址空间了。这就是我们编译器和操作系统互相协同的最重要的表现之一。

二.动态库如何加载的

动态库就是一个可执行文件,它的加载与可执行文件的加载是一样的关键问题在于我把这个动态库应该映射到我的共享区里,这个可执行程序里面那么任何地址它都是我们对应已经编译好对应的线性地址。
好,你今天要调的这个地址,那在我看来他也是序列地址喽。那么如果按照序列地址的话,那么共享库加载它在序列地址里必须被加载到这个位置。也就是我在把我们对应的磁盘当中,把对应共享库加载到对应的那么内存里,加到对应的内存映射的时候,必须得把它映射到固定位置处。那这就有点坑爹了。
一个进程在运行时,你的库先加载后加载完完全全料不定了。
因为你的程进程可能要有十几个库,我怎么保证每一个库它都必须得加载到固定位置呢?
那么被加载到我们对应的叫做固定地址空间。固定地址我给占了怎么办?你怎么保证你每一次加的时候,还要让这个库固定的映射到一个位置,那这个成本太高了。
库呢设计成得想办法让他在共享区任意位置加载都可以。我们是采用相对以逻辑地址加偏移量的方式。
我们只以偏移量来标准啊,或者给大家写清楚,我们不要采用绝对地址来编制。只要每个函数在库中的偏移偏移量即可。
好,也就是说呢,我自己动态库啊,我自己在编的时候,我不要太多。你把每一个库它在地址空间里的起始地址,你给我记下来就可以。
我我们在加载时,最后我们来确定加偏量就能访问到它在库当中的绝对地址了。
在这里插入图片描述
这也是为什么在制作动态库时,需要一个东西叫做FPIC与位置无关码了。
我我们在加载时,最后我们来确定加偏量就能访问到它在库当中的绝对地址了。

三.动态库如何实现多进程间共享的

在这里插入图片描述
动态库通过页表映射到进程地址空间的共享区里,只需要第一俄国动态库加载到内存里,后面要是有动态库就直接建立映射关系到共享区里,就可以使用。

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

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

相关文章

怎么调监控清晰度,监控画面不清晰怎么修复?

监控画面不清晰怎么修复,通过调整视频的分辨率可以达到使视频更清晰的目的,另外就是如果是室外的环境下,视频的监控镜头会积累灰尘,擦一下镜头有可能会使得拍摄的视频更清晰一些。另外就是可以通过一些软件将视频分辨率提高&#…

零件更复杂、公差更严格?3D桌面引擎HOOPS助力MBD开发,优化质量流程!

在制造与计量行业,随着零件变得越来越复杂、越来越小并且需要更严格的公差,质量保证比以往任何时候都更加重要。工业4.0使基于3D模型的定义工作流程变得更加普遍,但质量流程仍然严重依赖2D图纸。从MBD数据集手动准备2D绘图非常耗时&#xff0…

mysql之squid代理服务器

(一)squid代理服务器 1、nginx做代理服务器 (1)反向代理(负载均衡) (2)缓存 (3)nginx无法做正向,通过proxy_pass进行反向代理 2、squid&…

010.Springboot之养老院管理系统

《010.Springboot之养老院管理系统》 项目简介 需要源码及数据库的私信… [1]本系统涉及到的技术主要如下: 推荐环境配置:DEA jdk1.8 Maven MySQL 前后端分离; 后台:SpringBootmybatis; 前台:LayuithymeleafjQuery; [2]功能模…

nginx反向代理配置

1.1 安装nginx 本节以安装“nginx-1.7.9”为例讲解nginx的安装方法,请确认已获取了“nginx-1.7.9.tar.gz”包。 步骤 1 以root用户登录服务器。 步骤 2 通过SSH或XFTP等工具将nginx安装包“nginx-1.7.9.tar.gz”上传到Linux服务器的“/tmp”目录下。 步骤 3 进入…

OpenAI暂停ChatGPT Plus新用户注册;迷宫与图神经网络

🦉 AI新闻 🚀 OpenAI暂停ChatGPT Plus新用户注册,考虑用户体验 摘要:OpenAI决定暂停ChatGPT Plus新用户注册,以应对开发日后使用量激增带来的压力,确保每个人都能享受良好的体验。根据调查机构Writerbudd…

LT8711UXD 是一款高性能双通道 Type-C/DP1.4 至 HDMI2.0 转换器

1. 描述 LT8711UXD 是一款高性能双通道 Type-C/DP1.4 至 HDMI2.0 转换器,设计用于将 USB Type-C 源或 DP1.4 源连接至 HDMI2.0 接收器。LT8711UXD 集成了一个 DP1.4 兼容接收器和一个 HDMI2.0 兼容发射器。此外,还包括两个 CC 控制器用于 CC 通信以实现…

【文件上传】empirecms 文件上传 (CVE-2018-18086)

1.1漏洞描述 描述: EmpireCMS(帝国网站管理系统)是一套内容管理系统(CMS)。 EmpireCMS 7.5版本中的e/class/moddofun.php文件的‘LoadInMod’函数存在安全漏洞。可利用该漏洞上传任意文件。 漏洞编号CVE-2018-18086漏洞类型文件…

NFS共享

目录 三种存储类型 作用: FTP文本传输协议 原理 FTP服务状态码 用户认证 常见FTP相关软件 vsftpd 软件介绍 用户和其共享目录 基础操作 安装服务端 客户端连接服务端 登录成功 匿名用户登录 1.服务端配置 2.客户端配置 3.服务端查看 匿名用户下载 删除…

Git 基本操作

目录 创建仓库命令 git init git clone 提交与修改 git add git status git diff git commit git reset git rm git mv git checkout git switch git restore 提交日志 git log git blame 远程操作 git remote git fetch git pull git push Git 的工作就…

C# NAudio 音频库

C# NAudio 音频库 NAudio安装NAudio简述简单示例1录制麦克风录制系统声卡WAV格式播放MP3格式播放AudioFileReader读取播放音频MediaFoundationReader 读取播放音频 NAudio安装 项目>NuGet包管理器 搜索NAudio点击安装,自动安装依赖库。 安装成功后工具箱会新增…

网站安全攻防战:守护数据的钢铁堡垒

在数字化时代,网站的安全性至关重要,因为它不仅关乎用户的隐私信息,还涉及到业务的正常运行。一旦网站受到攻击,可能导致数据泄露、服务中断等问题,因此网站安全应成为企业和个人关注的焦点。本文将探讨网站安全的重要…

GBase8a-GDCA-第一次阶段测试

文章目录 主要内容 总结 主要内容 GBase8a-第一阶段测试答案 总结 以上是今天要讲的内容,GBase8a-GDCA-第一次阶段测试题及答案。

NewStarCTF2023 Week3 Reverse方向 题目STL WP

分析 代码不多&#xff0c;逻辑挺清楚的。 先用Z3解出V7&#xff1a; from z3 import *s Solver() v1, v2, v3, v4, v5, v6 BitVecs(v1 v2 v3 v4 v5 v6, 32) v7, v8, v9, v10, v11 BitVecs(v7 v8 v9 v10 v11, 32)s.add((v1 << 15) ^ v1 0x2882D802120E) s.add((v2 …

Linux_安装docker

安装包管理工具yum-utils&#xff0c;并设置docker储存库&#xff08;如果已有&#xff0c;不用安装&#xff09; # 安装包管理工具 sudo yum install -y yum-utils # 安装docker储存库 sudo yum-config-manager \--add-repo \http://mirrors.aliyun.com/docker-ce/linux/cen…

ERP管理系统为何成为制造业的必备工具

ERP管理系统为何成为制造业的必备工具&#xff1f; 全球化和数字化快速发展&#xff0c;制造业面临着越来越多的挑战和机遇。为了提高生产效率、降低成本、优化资源配置&#xff0c;许多制造业企业开始引入ERP管理系统。那么&#xff0c;为何ERP管理系统成为制造业的必备工具呢…

109. 有序链表转化为二叉搜索树

题目 题解 分治。 class Solution:def getMedian(self, left: ListNode, right: ListNode) -> ListNode:找到链表的中间节点slow fast leftwhile fast ! right and fast.next ! right:slow slow.nextfast fast.next.nextreturn slowdef buildTree(self, left: ListNod…

Python爬虫实战(进阶篇)—7获取每日菜价(附完整代码)

文章目录 专栏导读背景前期准备1、网址&#xff1a;2、分析&#xff1a; 请求url、请求方法、请求参数测试一个完整代码写入Excel视频展示不足&#xff1a;结尾 专栏导读 &#x1f525;&#x1f525;本文已收录于《Python基础篇爬虫》 &#x1f251;&#x1f251;本专栏专门针…

问题汇总20231103

文章目录 前言问题汇总1.所有操作系统在CPU层面上是不是都为时间片轮转的形式处理程序&#xff1f;只是任务调度的调度算法不同&#xff1f;那多线程的本质也是时间片吗&#xff1f;只不过很小&#xff1f;2.Mcu和mpu的本质区别3.下载HAL库步骤4.RAM,ROM,SRAM,SDRAM,DDR内存5.编…

Spring事务和事务的传播机制

目录 Spring中事务的实现 MySQL中的事务使用 Spring 编程式事务 TransactionTemplate 编程式事务 TransactionManager编程式事务 Spring声明式事务 Transactional 参数说明 事务因为程序异常捕获不会自动回滚的解决方案 Transactional 原理 Spring 事务隔离级别 Spring…