Linux 基础io_ELF_虚拟物理地址_动态库加载

1.可执行程序格式 ELF

[wws@hcss-ecs-178e myshell]$ ll
total 56
-rw-rw-r-- 1 wws wws    92 Oct 17 19:14 file
-rw-rw-r-- 1 wws wws    82 Oct 12 16:51 makefile
-rw-r--r-- 1 wws wws    90 Oct 17 19:13 myfile
-rwxrwxr-x 1 wws wws 20128 Oct 16 21:02 myshell
-rw-rw-r-- 1 wws wws  7627 Oct 16 21:16 myshell.cc
[wws@hcss-ecs-178e myshell]$ file myshell
myshell: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=285576a85c296a5f746e5570999a6c447128bd52, not stripped
[wws@hcss-ecs-178e myshell]$ size myshelltext    data     bss     dec     hex filename9159     900    3192   13251    33c3 myshell

file 查看文件的基本情况 size查看可执行程序的结构情况,text数据段大小 data初始化数据大小 bss未初始化数据大小  dec10进制总大小 hex16进制总大小 filename名称

前两个部分是系统在加载时用到的,中间黄色部分Section 每一个小框就是一个节 不同的节存储不同的内容 比如

text节

存储程序的机器代码,也就是可执行指令。

data节

存储初始化的全局和静态变量。这些变量在程序启动时会被加载到内存中。

bss节

存储未初始化的全局和静态变量。

...

最后一个部分Section Header Table 它的作用是保存每个节的偏移量和大小...,通过节的偏移量和大小,可以计算出每个节在ELF文件中的范围。

2.重谈地址空间(可执行程序 加载)

我们知道每一个进程都有对应的mm_struct虚拟地址空间,它通过页表与物理内存建立映射关系。每次访问虚拟地址时,系统会通过页表查找相应的物理地址。

现在有几个问题

1.可执行性程序在加载到内存前有地址吗?

在加载到内存之前,可执行程序确实具有地址,但这些地址主要是虚拟地址,而非物理地址。我们在编译时就可以看到地址,但这些地址其实是虚拟地址。

从这张图就可以看出在加载到物理内存前,可执行程序就有程序自己生成的逻辑地址了,之前不说说虚拟地址吗?逻辑地址是什么?逻辑地址=起始地址+偏移量(平坦模式下起始地址==0)知道一条指令的地址+它的长度=下一个指令的地址  逻辑地址在数字层面上就和虚拟地址一样了  只不过在磁盘ELF中一般说逻辑地址 加载到内存时说虚拟地址

2.mm_struct由谁初始化的?

我们知道可执行程序加载到内存前就有虚拟地址,每个节的起始的虚拟地址也知道(节偏移+节大小) 

程序内部进行函数跳转也是用的虚拟地址。

每个节的虚拟地址的范围就是mm_struct中每个区域的起始范围。

3.现在可执行程序加载到内存,虚拟地址空间也通过页表跟内存建立映射关系,接下来CPU怎么开始调度呢?

将 PC 寄存器设置为入口点地址,要从ELF的ELF Header中读取

但这是一个虚拟地址,CPU怎么找对应的物理地址呢?

PC:程序计数器是一个指向下一条将要执行的指令的内存地址的寄存器

EIP:用于指向当前正在执行的指令。保存了下一条要执行的指令的地址,并且在程序执行过程中会自动更新。

MMU硬件:是负责虚拟地址到物理地址转换的硬件模块。

CR3:存储页表的物理地址

现在pc中有第一条指令的虚拟地址,再根据MUU+CR3找到对应的物理地址,再把该物理地址里面的内容(指令+虚拟地址)读入到EIP,最后根据读入的虚拟地址+指令长度=下一个指令的虚拟地址更新PC。形成闭环

所以虚拟地址是CPU 操作系统 编译器 共同协助下的产物。

为什么要有虚拟地址空间?

有了虚拟地址空间,编译器在编址的时候就不用考虑物理内存的情况,直接在平坦模式下从0000开始不断生成地址,完成编译器与操作系统的解耦。

3.重谈区域划分

现在我们知道了mm_struct里面代码段 数据段是根据可执行程序ELF格式中的Section(text节 data节...)的虚拟地址的范围划分的。但里面栈区 堆区 共享区的范围怎么划分的?又怎么对它们进行管理?

其实在mm_struct中有struct vm_area_struct结构体,vm_area_struct是 Linux 内核中用于管理虚拟内存区域的结构体。里面存有该区域的起始位置

struct vm_area_struct {struct mm_struct *vm_mm;        // 指向该虚拟内存区域所属的内存管理结构unsigned long vm_start;          // 虚拟内存区域的起始地址unsigned long vm_end;            // 虚拟内存区域的结束地址struct vm_area_struct *vm_next;  // 指向下一个虚拟内存区域的指针pgprot_t vm_page_prot;           // 页的保护属性unsigned long vm_flags;          // 该虚拟内存区域的标志struct file *vm_file;            // 如果是映射文件,该指针指向文件结构unsigned long vm_pgoff;          // 在映射文件时的偏移// 可能还有其他字段
};

每一个区域都有自己的vm_area_struct,并通过链表的形式相互连接。

4.加载动态库

我们知道动态库也是ELF结构,对里面函数方式进行编址,也是按照基址0+偏移量 进行的。(库名:偏移量 库名会变成地址)

库加载到内存也需要被管理,struct libso 里面记录了加载到内存中的库的信息,引用计数,指针

#include <stddef.h>  // for size_t// 定义共享库结构体
struct libso {char *name;               // 库的名称char *path;               // 库的路径void *handle;             // 库的句柄size_t size;              // 库的大小int ref_count;            // 引用计数struct libso *next;       // 指向下一个 libso 结构体的指针
};

库映射到mm_struct。知道库在物理内存占据的空间大小,以及物理地址起始位置。通过页表建立映射关系,映射到mm_struct的位置由系统找等大小的虚拟地址空间。并在vm_area_struct的链表中链接自己的vm_area_struct(虚拟地址的起始位置)

所以正文代码中怎么找到库函数呢?

库名:偏移量 库名会变成地址 当系统找到等大的虚拟地址空间分配给库,库就有了虚拟起始地址,此时把库名改成 库的虚拟起始地址 再加上偏移量,就能找到库函数的虚拟地址了。

正文代码段是不能修改的,也就不能把库名该为 库的虚拟起始地址。

其实在ELF中的节有一个是GOT全局偏移表,它里面存放的就是库函数的虚拟地址(库名:偏移量)。

代码区找库函数时是这样写的 call GOT虚拟地址:目标库函数的下标

GOT的虚拟地址在加载到内存前就已经编址好了。通过call GOT虚拟地址:目标库函数的下标 就可以找到目标库函数的虚拟地址需要等系统分配好虚拟地址 才能找到库的虚拟起始地址 进而通过偏移量找到库函数虚拟地址)

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java如何实现PDF转高质量图片

大家好&#xff0c;我是 V 哥。在Java中&#xff0c;将PDF文件转换为高质量的图片可以使用不同的库&#xff0c;其中最常用的库之一是 Apache PDFBox。通过该库&#xff0c;你可以读取PDF文件&#xff0c;并将每一页转换为图像文件。为了提高图像的质量&#xff0c;你可以指定分…

【HarmonyOS NEXT】使用 Navigation 对折叠屏设备页面进行分栏展示,优化 UI 交互

关键词&#xff1a;折叠屏、navigation、router、路由、分栏、UI 随着科技的发展&#xff0c;手机设备形态也由一面屏向多面屏进行发展&#xff0c;那么软件的UI适配也面临着问题&#xff0c;本篇文章主要解决大屏设备的页面 UI 适配问题&#xff0c;如折叠屏&#xff0c;平板&…

Coppelia Sim (v-REP)仿真 机器人3D相机手眼标定与实时视觉追踪 (二)

coppelia sim[V-REP]仿真实现 机器人于3D相机手眼标定与实时视觉追踪 二 zmq API接口python调用python获取3D相机的数据获取彩色相机的数据获取深度相机的数据用matpolit显示 python控制机器人运动直接控制轴的位置用IK运动学直接移动到末端姿态 相机内参的标定记录拍照点的位置…

Linux 安装nacos

1.下载版本 https://github.com/alibaba/nacos/tags 2.解压压缩包&#xff0c;启动 (1)将压缩包放到/usr/local目录下&#xff0c;解压 tar -xvf nacos-server-2.0.0-BETA.tar.gz(2)删除压缩包 rm -f nacos-server-2.0.0-BETA.tar.gz(3) 找到nacos的mysql的数据库脚本,在数…

sqoop问题汇总记录

此篇博客仅记录在使用sqoop时遇到的各种问题。持续更新&#xff0c;有问题评论区一起探讨&#xff0c;写得有不足之处见谅。 Oracle_to_hive 1. main ERROR Could not register mbeans java.security.AccessControlException: access denied ("javax.management.MBeanTr…

基于微信小程序的小区管理系统设计与实现(lw+演示+源码+运行)

摘 要 社会发展日新月异&#xff0c;用计算机应用实现数据管理功能已经算是很完善的了&#xff0c;但是随着移动互联网的到来&#xff0c;处理信息不再受制于地理位置的限制&#xff0c;处理信息及时高效&#xff0c;备受人们的喜爱。所以各大互联网厂商都瞄准移动互联网这个潮…

window11使用wsl2安装Ubuntu22.04

目录 1、快速了解wsl2 安装子系统linux流程&#xff08;B站视频&#xff09; 2、wsl2常用命令 3、windows与子系统Linux文件访问方法 4、子系统linux使用windows网络代理、网络配置&#xff08;镜像网络&#xff0c;非NAT&#xff09; 5、wsl2 Ubuntu miniconda 安装 6、…

【K8S系列】Kubernetes 中 NodePort 类型的 Service 无法访问的问题【已解决】

在 Kubernetes 中&#xff0c;NodePort 类型的 Service 允许用户通过每个节点的 IP 地址和指定的端口访问应用程序。如果 NodePort 类型的 Service 无法通过节点的 IP 地址和指定端口进行访问&#xff0c;可能会导致用户无法访问应用。本文将详细分析该问题的常见原因及其解决方…

Cyber​​Panel filemanager/upload 远程命令执行漏洞复现

0x01 产品简介 CyberPanel是一个开源的Web控制面板,它提供了一个用户友好的界面,用于管理网站、电子邮件、数据库、FTP账户等。CyberPanel旨在简化网站管理任务,使非技术用户也能轻松管理自己的在线资源。 0x02 漏洞概述 该漏洞源于filemanager/upload接口未做身份验证和…

(C#面向初学者的 .NET 的生成 AI) 第 2 部分-什么是 AI 和 ML?

从本部分开始Luis Quintanilla介绍AI和机器学习&#xff0c;需要学习的一些东西是什么是AI和ML&#xff1f;作为一名.net开发人员如何学习使用AI和ML。 1、首先什么是AI 和 ML&#xff1f; 你可以把它看作是基本相同事物的不同层次。 在顶层的是AI&#xff08;人工智能&#xf…

Swarm-LIO: Decentralized Swarm LiDAR-inertial Odometry论文翻译

文章目录 前言一、介绍二、相关工作三、方法A. 问题表述B. 框架概述C. 群体系统的初始化D. 去中心化激光雷达-惯性状态估计 四. 实验A. 室内飞行B. 退化环境飞行C. 去中心化部署 五. 结论和未来工作 前言 原文&#xff1a;原文 准确的自我状态和相对状态估计是完成群体任务的关…

wsl 使用docker 部署oracle11g数据库

wsl 使用docker 部署oracle11g数据库 1. 下载oracle11g sudo docker pull registry.cn-hangzhou.aliyuncs.com/helowin/oracle_11g2. 运行oracle11g容器&#xff08;docker-compose&#xff09; services:oracle-1.0:container_name: oracle11gimage: oracle11g:1.0restart:…

IDEA集成JProfiler

目录 下载并安装JProfiler下载安装包管理员身份运行配置许可证邮箱复制注册码配置永久许可证选择IDE集成 在IDEA中下载并安装JProfiler插件启动并使用JProfiler进行性能分析启动Java应用程序&#xff1a;自动运行JProfiler 知识扩充功能 下载并安装JProfiler 下载安装包 官网…

Tomcat 和 Docker部署Java项目的区别

在 Java 项目部署中&#xff0c;Tomcat 和 Docker 是两种常见的选择。虽然它们都可以用来运行 Java 应用&#xff0c;但它们在定位、部署方式、依赖环境、资源隔离、扩展性和适用场景等方面有显著区别。 1. 功能定位 1.1 Tomcat Apache Tomcat 是一种轻量级的 Java 应用服务器…

AI-基本概念-多层感知器模型/CNN/RNN/自注意力模型

1 需求 神经网络 …… 深度学习 …… 深度学习包含哪些神经网络&#xff1a; 全连接神经网络卷积神经网络循环神经网络基于注意力机制的神经网络 2 接口 3 CNN 在这个示例中&#xff1a; 首先定义了一个简单的卷积神经网络SimpleCNN&#xff0c;它包含两个卷积层、两个池…

Leaflet查询矢量瓦片偏移的问题

1、问题现象 使用Leaflet绘制工具查询出来的结果有偏移 2、问题排查 1&#xff09;Leaflet中latLngToContainerPoint和latLngToLayerPoint的区别 2&#xff09;使用Leaflet查询需要使用像素坐标 3&#xff09;经排查发现&#xff0c;container获取的坐标是地图容器坐标&…

Vue生成名片二维码带logo并支持下载

一、需求 生成一张名片&#xff0c;名片上有用户信息以及二维码&#xff0c;名片支持下载功能&#xff08;背景样式可更换&#xff0c;忽略本文章样图样式&#xff09;。 二、参考文章 这不是我自己找官网自己摸索出来的&#xff0c;是借鉴各位前辈的&#xff0c;学以致用&am…

如何利用网站进行仿牌运营?

对于很多人来说&#xff0c;仿牌网站的运营是一项充满挑战的任务&#xff0c;很多初学者对如何开始感到困惑&#xff0c;甚至不清楚仿牌网站的运作机制。此外&#xff0c;搜索引擎对新网站的审核期也使得许多站长倍感压力。那么&#xff0c;如何才能在这一过程中有效地进行SEO优…

数字IC开发:布局布线

数字IC开发&#xff1a;布局布线 前端经过DFT&#xff0c;综合后输出网表文件给后端&#xff0c;由后端通过布局布线&#xff0c;将网表转换为GDSII文件&#xff1b;网表文件只包含单元器件及其连接等信息&#xff0c;GDS文件则包含其物理位置&#xff0c;具体的走线&#xff1…

传智杯 第六届-复赛-C

题目描述&#xff1a; 小红有一个数组&#xff0c;她每次可以选择数组的一个元素 xxx &#xff0c;将这个元素分成两个元素 aaa 和 bbb &#xff0c;使得 abxabxabx。请问小红最少需要操作多少次才可以使得数组的所有元素都相等。 输入描述: 第一行输入一个整数 n(1≤n≤10^5)…