当前位置: 首页 > article >正文

【Linux】ELF可执行程序和动态库加载

🔥 个人主页:大耳朵土土垚
🔥 所属专栏:Linux系统编程

这里将会不定期更新有关Linux的内容,欢迎大家点赞,收藏,评论🥳🥳🎉🎉🎉

文章目录

  • 1. 可执行程序格式
  • 2. 可执行程序加载
  • 3. 动态库的加载

1. 可执行程序格式

  Linux操作系统上的可执行文件格式是ELF(Executable and Linkable Format)。ELF是一种灵活的、可扩展的文件格式,用于存储可执行程序、共享库和目标文件等二进制文件。

ELF文件采用分段(Segment)的结构,每个段都有不同的作用和属性。常见的段包括:

  1. 执行段(.text):包含程序的机器代码,用于执行程序的指令。

  2. 数据段(.data):包含程序的已初始化全局变量和静态变量等数据。

  3. 未初始化数据段(.bss):包含程序的未初始化全局变量和静态变量等数据。

  4. 符号表段(.symtab):包含程序的符号表,记录了程序的全局变量、函数、库的引用等信息。

此外,ELF文件格式还定义了一些特殊的节头表(Section Header Table)和程序头表(Program Header Table)来组织文件中的段和节信息。

如下图所示:

因为目标文件.o也是ELF格式,那么将目标文件链接为可执行程序实际上就是将相同属性的section合并:

  在Linux操作系统中,通过elf格式的可执行文件,操作系统可以读取文件中的节和段信息,并加载到内存中执行。这种文件格式的灵活性和可扩展性,使得Linux系统具有较强的兼容性和可移植性。


2. 可执行程序加载

  因为可执行程序在Linux内是以ELF格式呈现的,而ELF包含了程序的虚拟地址信息,所以程序在编译形成的时候其虚拟地址就已经确定好了;进程在运行程序时就会读取程序ELF信息来初始化mm_struct中的信息。
  此外可执行程序ELF中还保存了整个程序的入口地址Entry point address,这样当系统执行程序时,除了将ELF中的虚拟地址加载到mm_struct中,还会将整个程序的入口地址赋给CPUpc指针,(pc指针指向当前执行的命令)这样一个程序就可以执行下去了,所以执行程序使用的地址也是虚拟地址
  程序加载到内存中,是会有物理内存地址的,页表的作用就是将程序物理内存地址与虚拟地址之间进行映射,而CPU中只保存虚拟地址是没办法在物理内存中找到程序的内容的,所以需要借助MMU硬件来将PC指针指向的虚拟地址转化为物理地址给CR3寄存器中,完成类似查表的操作,然后CPU拿到了物理内存地址就可以去物理内存中找到对应的内容,并将该内容保存到CPUEIP中执行,执行完了,PC指针就根据该内容的大小保存下一个内容的虚拟指针(因为程序的虚拟指针都是按顺序递增的,增加的大小就是上一条命令的长度),然后再通过硬件转化为实际物理地址,循环往复,直到执行完所有命令,整个过程如下图所示:


3. 动态库的加载

  动态库的加载与可执行程序类似,但是它并不直接将虚拟地址保存到mm_struct中,而是在程序运行需要用到动态库时加载到内存中,并将自己的虚拟地址保存到一个结构体struct vm_area_struct中,因为动态库加载可能多个也可能不加载,所有Linux使用了一种灵活的数据结构来保存动态库的虚拟地址,该结构体实际上是一个链表,链接在mm_struct中的共享区中。
  程序在调用动态库中的方法时会先将动态库的起始虚拟地址保存起来,然后将调用的方法转化为该方法在动态库中的虚拟地址偏移量,这样就可以根据起始虚拟地址+偏移量的方法找到动态库中该方法的虚拟地址,然后CPU通过查表找到物理内存地址执行命令,过程如下图所示:



http://www.kler.cn/a/393390.html

相关文章:

  • 7. petalinux 根文件系统配置(package group)
  • 表达式语句、复合语句和空语句
  • STM32 高级 谈一下IPV4/默认网关/子网掩码/DNS服务器/MAC
  • 产品初探Devops!以及AI如何赋能Devops?
  • cad学习 day7-9
  • WhisperKit: Android 端测试 Whisper -- Android手机(Qualcomm GPU)部署音频大模型
  • CSS高级技巧_精灵图_字体图标_CSS三角_vertical-align(图像和文字居中在同一行)_溢出文字省略号显示
  • 随机森林(Random Forest)算法Python代码实现
  • 数据量大Excel卡顿严重?选对报表工具提高10倍效率
  • 同三维T85HU HDMI+USB摄像机多路多机位手机直播采集卡
  • 浅析pytorch中的常见函数和方法
  • 128.WEB渗透测试-信息收集-ARL(19)
  • DDE(深度桌面环境) Qt 6.8 适配说明
  • 嵌入式开发套件(golang版本)
  • 昇思大模型平台打卡体验活动:项目6基于MindSpore通过GPT实现情感分类
  • 力扣662:二叉树的最大宽度
  • Java面向对象编程进阶之包装类
  • Python---re模块(正则表达式)
  • 快递鸟快递查询API接口参数代码
  • 字符设备 - The most important !
  • JavaScript 中实例化生成对象的相关探讨
  • JVM 中的完整 GC 流程
  • 电信网关配置管理后台 upload_channels.php 任意文件上传漏洞复现
  • IntelliJ IDEA设置打开文件tab窗口多行展示
  • 使用Cesium for Unreal与Cesium ion构建3D地理空间应用教程
  • PHP运算符