Linux:ELF 可执行文件的解析与其加载的原理

文章目录

  • ELF 可执行文件
    • 需要的前置知识
    • ELF 可执行文件的程序头部表
  • 加载可执行目标文件
  • QA
    • 加载器如何工作?
  • 参考

ELF 可执行文件

我们已经看到链接器如何将多个目标文件合并成一个可执行目标文件。我们的 C程序,开始时是一组 ASCII 文本文件,现在已经被转化为一个二进制文件,且这个二进制文件包含加载程序到内存并运行它所需的所有信息。
图 7-13 概括了一个典型的 ELF 可执行文件中的各类信息。
在这里插入图片描述

可执行目标文件的格式类似于可重定位目标文件的格式。

ELF 头描述文件的总体格式。它还包括程序的入口点(entry point),也就是当程序运行时要执行的第一条指令的地址。

.text、.rodata和.data 节与可重定位目标文件中的节是相似的,除了这些节已经被重定位到它们最终的运行时内存地址以外。.init 节定义了一个小函数,叫做 init,程序的初始化代码会调用它。因为可执行文件是完全链接的(已被重定位),所以它不再需要rel节。

需要的前置知识

看到这里,脑海里面没有相关概念的朋友可以先看看相关的前置篇:

计算机的目标文件是什么? 在程序中充当什么角色?

什么是静态链接?有什么用?

ELF 可执行文件的程序头部表

ELF 可执行文件被设计得很容易加载到内存,可执行文件的连续的片(chunk)被映射到连续的内存段。程序头部表(program header table)描述了这种映射关系。图 7-14 展示了可执行文件 prog 的程序头部表,是由 OBJDUMP 显示的。
在这里插入图片描述

加载可执行目标文件

要运行可执行目标文件 prog,我们可以在 Linux shell 的命令行中输入它的名字:

linux> ./prog

因为 prog 不是一个内置的 shell 命令,所以 shell 会认为 prog 是一个可执行目标文件,通过调用某个驻留在存储器中称为加载器(lader)的操作系统代码来运行它。任何Linux程序都可以通过调用execve 函数来调用加载器。

加载器将可执行目标文件中的代码和数据从磁盘复制到内存中,然后通过跳转到程序的第一条指令或入口点来运行该程序。这个将程序复制到内存并运行的过程叫做加载。每个 Linux程序都有一个运行时内存映像,类似于图7-15 中所示。
在这里插入图片描述

在 Linux x86-64系统中,代码段总是从地址 0x400000 处开始,后面是数据段。运行时堆在数据段之后通过调用 malloc 库往上增长。
堆后面的区域是为共享模块保留的。
用户栈总是从最大的合法用户地址(2的48次方-1)开始,向较小内存地址增长。栈上的区域,从地址 2的48次方开始,是为内核(kernel)中的代码和数据保留的,所谓内核就是操作系统驻留在内存的部分。

为了简洁,我们把堆、数据和代码段画得彼此相邻,并且把栈顶放在了最大的合法用户地址处。实际上,由于.data 段有对齐要求,所以代码段和数据段之间是有间隙的。

同时,在分配栈、共享库和堆段运行时地址的时候,链接器还会使用地址空间布局随机化(ASLR)。虽然每次程序运行时这些区域的地址都会改变,它们的相对位置是不变的。

当加载器运行时,它创建类似于图 7-15 所示的内存映像。在程序头部表的引导下加载器将可执行文件的片(chunk)复制到代码段和数据段。接下来,加载器跳转到程序的入口点,也就是 _start 函数的地址。这个函数是在系统目标文件 ctrl.o 中定义的,对所有的C程序都是一样的。_start 函数调用系统启动函数 __libc_start_main,该函数定义在 iibc.so中。它初始化执行环境,调用用户层的 main 函数,处理main 函数的返回值,并且在需要的时候把控制返回给内核。

QA

加载器如何工作?

下面是关于加载实际是如何工作的一个概述:

Linux 系统中的每个程序都运行在一个进程上下文中,有自己的虚拟地址空间。当 shell 运行一个程序时,父 shell 进程生成一个子进程,它是父进程的一个复制。子进程通过 execve 系统调用启动加载器。

加载器删除子进程现有的虚拟内存段,并创建一组新的代码、数据、堆和栈段。新的栈和堆段被初始化为零。

通过将虚拟地址空间中的页映射到可执行文件的页大小的片(chunk),新的代码和数据段被初始化为可执行文件的内容。

最后,加载器跳转到 start地址,它最终会调用应用程序的 main 函数。除了一些头部信息,在加载过程中没有任何从磁盘到内存的数据复制。直到 CPU 引用一个被映射的虚拟页时才会进行复制,此时,操作系统利用它的页面调度机制自动将页面从磁盘传送到内存。

参考

深入理解计算机系统(原书第三版)

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

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

相关文章

实验4.3 动态路由RIPv2协议的配置

实验4.3 动态路由RIPv2协议的配置 一、任务描述二、任务分析三、具体要求四、实验拓扑五、任务实施1.配置交换机和路由器的接口的IP地址等参数。2.配置动态路由RIPv2协议,实现全网互通。 六、任务验收七、任务小结八、知识链接1.RIP协议简介2&#xff0e…

Linux开发工具——vim篇

vim开发工具的使用 文章目录 vim开发工具的使用认识vimvim常用三种模式vim正常模式命令集模式切换移动光标删除文字赋值替换撤销上一次操作更改跳到指定的行 vim末行模式命令集列出行号跳到文件中的某一行:保存文件离开vim查找字符: 总结题外话&#xff…

spring之面向切面:AOP(2)

学习的最大理由是想摆脱平庸,早一天就多一份人生的精彩;迟一天就多一天平庸的困扰。各位小伙伴,如果您: 想系统/深入学习某技术知识点… 一个人摸索学习很难坚持,想组团高效学习… 想写博客但无从下手,急需…

递归算法:二叉树前序、中序、后序遍历解析与递归思想深度剖析

🎬 鸽芷咕:个人主页 🔥 个人专栏: 《linux深造日志》 《高效算法》 ⛺️生活的理想,就是为了理想的生活! 文章目录 一、二叉树的遍历1.1 链式结构二叉树的创建1.1 二叉树结构图 二、 前序遍历代码演示:2.1 前序遍历递…

万兆网络之疑难杂症(二)

症状:测线仪8芯全亮,网速只有百兆 某台计算机测速发现只有90多M/s速度,关于iperf测速可以参考之前的文章 万兆网络之线路测速 Win11系统查看网络属性为1000Mbps,还是扯皮的装修方,4个工位只布了2条线,还…

智慧安防视频监控EasyCVR如何通过回调接口向第三方平台推送RTSP视频通道离线通知

安防视频监控系统EasyCVR能在局域网、公网、专网等复杂的网络环境中部署,可支持4G、5G、WiFi、有线等方式进行视频的接入与传输、处理和分发。平台能将接入的视频流进行汇聚、转码、多格式输出和分发,具体包括:RTMP、RTSP、HTTP-FLV、WebSock…

海康威视IP网络对讲广播系统命令执行漏洞(CVE-2023-6895)

漏洞介绍 海康威视IP网络对讲广播系统采用领先的IPAudio™技术,将音频信号以数据包形式在局域网和广域网上进行传送,是一套纯数字传输系统。 Hikvision Intercom Broadcasting System 3.0.3_20201113_RELEASE(HIK)版本存在操作系统命令注入漏洞,该漏洞源于文件/ph…

Linux网络编程(一):网络基础(下)

参考引用 UNIX 环境高级编程 (第3版)黑马程序员-Linux 网络编程 1. 协议的概念 1.1 什么是协议 从应用的角度出发,协议可理解为 “规则”,是数据传输和数据解释的规则 假设,A、B双方欲传输文件,规定: 第一次&#xff…

【Redis】五、Redis持久化、RDB和AOF

文章目录 Redis持久化一、RDB(Redis DataBase)触发机制如何恢复rdb文件 二、AOF(Append Only File)三、扩展 Redis持久化 面试和工作,持久化都是重点! Redis 是内存数据库,如果不将内存中的数据…

网络安全知识图谱 图数据库介绍及语法

本体构建: 资产: 系统,软件 威胁: 攻击: 建模: 3个本体 5个实体类型 CWE漏洞库 http://cwe.mitre.org/data/downloads.html CPECP攻击模式分类库 http://capec.mitre.org/data/downloads.html CPE通用组件库 http:…

计算机基础:网络基础

目录 ​​​​​​​一.网线制作 1.制作所需要工具 网线制作标准 ​编辑 2.水晶头使用 3.网线钳使用 4.视频教学 二.集线器、交换机介绍 1.OSI七层模型 2.TCP/IP四层参考模型 3.集线器、交换机。路由器介绍 集线器 交换机 路由器 区别 三.路由器的配置 1.路由器设…

vscode配置node.js调试环境

node.js基于VSCode的开发环境的搭建非常简单。 说明:本文的前置条件是已安装好node.js(具体安装不再赘述,如有需要可评论区留言)。 阅读本文可掌握: 方便地进行js单步调试;方便地查看内置的对象或属性; 安装插件 C…

写了这么久的vue,Vue中组件和插件有什么区别?

一、组件是什么 回顾以前对组件的定义: 组件就是把图形、非图形的各种逻辑均抽象为一个统一的概念(组件)来实现开发的模式,在Vue中每一个.vue文件都可以视为一个组件 组件的优势 降低整个系统的耦合度,在保持接口不…

python-dlib实现人脸提取和分割

效果 → 参考资料和资源 GitHub - Onwaier/SegfaceAndAlignByDlib: 用dlib实现脸部分割和人脸对齐 shape_predictor_68_face_landmarks.dat 下载地址_shape_predictor_68_face_landmarks.dat下载-CSDN博客 未运行的参考资料 dlib实现脸部分割与人脸对齐 - 知乎 py代码 &…

opencv入门到精通——图像的基本操作

目录 目标 访问和修改像素值 访问图像属性 图像感兴趣区域ROI 拆分和合并图像通道 为图像设置边框(填充) 目标 学会: 访问像素值并修改它们 访问图像属性 设置感兴趣区域(ROI) 分割和合并图像 本节中的几乎所有操作都主要与Numpy相…

spring使用@Autowired @Lazy 注解 解决循环依赖

今天在启动项目时报错:org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name ‘colorController’: Unsatisfied dependency expressed through field ‘projectService’; nested exception is org.springframework.…

Java中字符串/数字左右填充“0”

目录 1、String.format 2、NumberFormat.getInstance() 3、StringUtils.leftPad 4、自定义方法 append拼接 1、String.format %06d的定义: 0代表前面要补的字符 6代表字符串长度 d表示参数为整数类型 //左边加0 String str String.format("%06d", 1…

[最后一个月征稿、ACM独立出版】第三届密码学、网络安全和通信技术国际会议(CNSCT 2024)

第三届密码学、网络安全和通信技术国际会议(CNSCT 2024) 2024 3rd International Conference on Cryptography, Network Security and Communication Technology 一、大会简介 随着互联网和网络应用的不断发展,网络安全在计算机科学中的地…

论文解读:SwinTransformer-减少Q、K、V的运算规模

概述以及要解决的问题 什么是Bankbone:不论什么模型,用这个backbone提特征,效果大概率非常好 直接套用在各种下游任务中 要解决的问题: 一个block要完成的任务 整体网络架构 H*W*3卷积->还是H*w*3->对应H*w的特征图的,取…

创建基于 GBASE南大通用数据源的数据连接

此章节主要介绍如何在 Visual Studio 开发工具的‚服务器资源管理器‛窗口中创建基于 GBASE南大通用数据源的数据连接。如果‚服务器资源管理器‛在 Visual Studio 开发工具打开后没有激活,可以选择‚视图‛菜单中的‚服务器资源管理器‛,如下图 9-1 所示…
最新文章