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

再次认识虚拟地址空间 可执行程序的加载 ─── linux第21课

目录

1.可执行程序的格式

2.链接过程

ELF加载

  加载可执行程序的步骤

虚拟地址空间

动态库的加载(类似可执行程序的加载)

多进程间看待动态库

与地址无关 =GOT+函数在库中的偏移量


1.可执行程序的格式

2.链接过程

  • 可见linux下的可执行程序的格式是ELF格式  ,例如代码区放在section1 数据区放在是section2 
  • 其实动态库/静态库  , .o文件 ,可执行程序这三类都是ELF结构
  • 链接就是将一个一个相同属性的section合并  ,所以命名时不能有重名
  • 生成可执行程序的本质就是将.c文件变成.o文件 ,再将全部的.o文件链接成可执行程序

补充:文件是一个大型的一维的数组 ,想要找到某个区域 ,只需要找到偏移量和区域大小即可

ELF加载

        我们前面学习了进程地址空间中存储的是虚拟地址

        ⼀个ELF会有多种不同的Section,在加载到内存的时候,也会进⾏Section合并,形成segment

问题:

  • ⼀个ELF程序,在没有被加载到内存的时候,有没有地址呢?
  • 进程mm_struct、vm_area_struct在进程刚刚创建的时候,初始化数据从哪⾥来的?

答案:

        ⼀个ELF程序,在没有被加载到内存的时候,本来就有地址,当代计算机工作的时候,都采⽤"平坦 模式"进行工作。所以也要求ELF对⾃⼰的代码和数据进行统⼀编址,下面是 objdump -S 反汇编之后的代码

最左侧的就是ELF的虚拟地址,其实,严格意义上应该叫做逻辑地址(起始地址+偏移量), 但是我们 认为起始地址是0. 也就是说,其实虚拟地址在我们的程序还没有加载到内存的时候,就已经把可执行程序进行统⼀编址了.

        进程mm_struct、vm_area_struct在进程刚刚创建的时候,初始化数据从哪里来的?

        从ELF各个 segment来,每个segment有自己的起始地址和自己的长度,⽤来初始化内核结构中的[start, end] 等范围数据,另外在用详细地址,填充页表

结论: 虚拟地址是编译器 操作系统 磁盘三方的共同产物

          磁盘ELF中的逻辑地址 == 内存中的虚拟地址(在数值上相同 ,可以将两者看为一个东西)

  加载可执行程序的步骤

        可执行程序生成时就会产生虚拟地址(逻辑地址)存储在磁盘上 , 将可执行程序加载到物理内存中,每条指令占据了内存空间 ,每条指令产生了自己的物理内存地址 ,现在每条指令都有虚拟地址和物理内存地址 , 页表将每个指令的物理内存地址和虚拟地址进行映射

         cpu运行可执行时 ,拿到的是可执行程序虚拟地址的起始地址 ,通过页表拿到对应物理内存地址, 进而拿到指令内容 , 加载到cpu中进行执行 , 执行完这一指令 ,根据此指令的长度+此指令虚拟地址的起始地址 = 下一条指令的虚拟地址 , 拿到下一个指令的虚拟地址 , 通过页表拿到物理内存地址 , 将下一条指令的内容加载到cpu ,以此类推 ,执行可执行程序

虚拟地址空间

        进程的虚拟地址空间其实是一段一段的 ,每个段都有特定的用途和属性,例如代码段、数据段、堆、栈等  每一段都是vm_area_struct的对象

        动态库加载 ,从磁盘加载到内存后 ,建立vm_area_struct 链入到mm_struct中.

动态库的加载(类似可执行程序的加载)

        1.系统层面: 会创建struct libso的数据结构 ,系统只需要管理结构体就可以管理动态库,多一个进程链接这个动态库,这个动态库中的引用计数就++.

        2.进程层面: 将动态库的虚拟地址和物理内存地址映射在页表 ,创建vm_area_struct 用动态库的虚拟地址的开始和结束地址初始化vm_area_struct ,将vm_area_struct链入到整个进程虚拟地址空间的共享区.

        3.还有一步操作可以看成(因为正文代码只能读,通过ELF中GOT实现下面的操作)  在进程正文代码处进行修改 ,将使用到的动态库函数换成动态库函数的虚拟地址  (动态库的虚拟起始地址+库函数在此库中的偏移量) ,用了多少动态库函数就改多少.

多进程间看待动态库

注意: 

        一个库映射在不同进程中的虚拟地址的起始地址可能不同 ,因为动态库也是vm_area_struct链到mm_struct中的

        找函数实现时,用对应进程的地址空间中动态库的虚拟地址的起始地址+函数偏移量

与地址无关 =GOT+函数在库中的偏移量

让代码通过查表的方式找到库中的方法,执行完返回

相关文章:

  • 极限网关六个企业级应用场景
  • 微信小程序状态管理与计算属性同时使用:miniprogram-computed 和 mobx-miniprogram
  • vcenter 虚机共享盘笔记
  • 锦华新材业绩波动明显:偿债能力偏弱,大额分红引关注
  • 20250320在荣品的PRO-RK3566开发板的buildroot系统下使用J27口的OTG0口接鼠标
  • AI社交的服务走向
  • 【力扣刷题实战】只出现一次的数字III
  • CVPR2025 | 蚂蚁浙大提出MP-GUI算法:全方位增强MLLM的GUI理解能力
  • VLAN的处理机制
  • 爬虫——playwright获取亚马逊数据
  • Web爬虫利器FireCrawl:全方位助力AI训练与高效数据抓取
  • 服务器部署Kong和Konga过程
  • vue路由去掉#
  • 07. 面向对象高级(2)_设计模式
  • 基于ssm的在线点歌系统(全套)
  • 电源电路篇
  • python:AI+ music21 构建LSTM模型生成爵士风格音乐
  • Liunx安装elasaticsearch、ik分词器、kibana
  • 批处理文件:用gifsicle删除gif文件中的奇数帧
  • 【快递分拣员-Git介绍】
  • 使用网站/怎么查询最新网站
  • 有那些做自媒体短视频的网站/营销策划书格式及范文
  • wordpress主题样式/最优化方法
  • 关于设计的网站有哪些/seo查询seo优化
  • 淘宝网站建设可行性分析报告/合肥seo建站
  • 网址提交大全/百度搜索优化怎么做