Linux:ELF

news2024/9/24 23:32:24

文章目录

  • 前置知识
    • 从文本文件到可执行文件经历的阶段
    • 编译器gcc
    • 目标文件
  • ELF
    • Section(节)
    • Segment(段)
    • 从链接角度和从程序角度看ELF文件
      • 1. Section Header Table:
      • 2. Program Header Table:
  • 参考

前置知识

从文本文件到可执行文件经历的阶段

一个用C语言编写的高级语言程序从编写到打包、再到编译执行的基本过程如下:
在这里插入图片描述

编写 - 预处理 - 编译 - 汇编 - 链接 。
其中,编译和汇编可以合并成一步,称为编译。

  1. 编写程序:使用任意文本编辑器,如Notepad、Sublime Text、Visual Studio等。

  2. 预处理:使用预处理器对程序进行处理,例如宏替换、头文件包含等。使用预处理器,通常是C语言编译器的一部分,例如gcc、clang等。预处理器处理的文件是源代码文件,生成的文件通常是.i后缀的中间文件,例如hello.i。

  3. 编译:使用编译器将程序转换为汇编语言。使用编译器,例如gcc、clang等。编译器处理的文件是预处理器生成的.i文件,生成的文件通常是.s后缀的汇编代码文件,例如hello.s。

  4. 汇编:使用汇编器将汇编代码转换成机器码。使用汇编器,例如gas、nasm等。处理的文件是编译器生成的.s文件,生成的文件通常是.o后缀的目标文件,例如hello.o。

  5. 链接:使用链接器将程序中的不同模块连接起来,并生成可执行文件。使用链接器,例如ld、gcc等。处理的文件是目标文件(.o文件),可以链接多个目标文件,生成可执行文件。 可执行文件通常是没有后缀的,例如hello。

  6. 打包:使用压缩工具,例如tar、zip等。打包的文件通常是可执行文件和相关依赖文件,文件名可以自定义,例如hello.tar.gz或hello.zip。

在整个编译过程中,涉及到的文件可以分为源代码文件(.c文件)、预处理生成的文件(.i文件)、编译器生成的文件(.s文件、.o文件)和链接器生成的文件(可执行文件)。

因此在本示例中,文件名可以为hello.c、hello.i、hello.s、hello.o、hello等。

编译器gcc

gcc是GNU Compiler Collection的缩写,是一款开源的C编译器,支持多种操作系统和CPU架构。它由许多不同的编译器组成,包括C、C ++、Objective-C、Fortran、Ada和其他语言的编译器,并支持众多的开源项目。gcc是GNU工程的一部分,由自由软件基金会(FSF)维护。由于它的灵活性和可移植性,gcc被广泛应用于编译开源项目和商业软件。

目标文件

目标文件(Object File)是编译源代码后生成的中间文件,其中包含了编译器产生的机器代码、符号表、重定位信息等。目标文件的主要作用是在链接阶段将多个目标文件合并成一个可执行文件或者库文件。

目标文件的命名约定和后缀可以因编译器和操作系统而异。在Unix/Linux系统中,通常使用".o"作为目标文件的后缀,例如example.o。在Windows系统中,常见的目标文件后缀包括".obj"等。

目标文件是编译过程中的一个重要中间产物,通过链接器将多个目标文件合并,最终生成可执行文件或者共享库。

目标文件的详细介绍可以参阅:
计算机的目标文件是什么? 在程序中充当什么角色?

ELF

ELF(Executable and Linkable Format)是一种通用的二进制文件格式,用于可执行文件、目标文件、共享库等在Unix和类Unix系统中。ELF格式是一种规范,定义了二进制文件的结构,使得不同的编译器、链接器和操作系统能够共同使用这种格式的文件。

ELF文件包含了以下主要部分:

  1. 文件头(ELF Header): 包含了文件的基本信息,如文件类型、架构、入口点地址等。

  2. 程序头表(Program Header Table): 描述了可执行文件的段(段包含可执行代码、数据、BSS等),以及这些段在内存中的加载位置和属性。

  3. 节头表(Section Header Table): 描述了目标文件的各个节(sections),包括代码段、数据段、符号表、字符串表等。每个节都有自己的类型、大小、偏移量等属性。

  4. 数据节(Sections): 包含实际的数据,例如代码、数据、符号表等。

  5. 重定位信息: 描述了需要在链接时进行重定位的位置,以便正确地将不同目标文件的代码和数据链接在一起。

  6. 符号表(Symbol Table): 记录了各种符号(函数、变量等)的信息,包括名称、类型、地址等。

ELF格式的设计提供了灵活性和可扩展性,使得不同的操作系统和硬件架构能够支持这一格式。在Linux和许多其他类Unix系统中,可执行文件和共享库通常采用ELF格式。

Section(节)

Section(段)是在汇编和链接中用于组织和描述不同类型数据的一个概念。在汇编程序中,.section指令用于声明一个Section。每个Section都包含特定类型的数据,比如代码、数据、符号表、字符串表等。

以下是一些常见的Section类型:

  1. 代码段(.text): 包含可执行的机器代码。

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

  3. BSS段: 包含未初始化的全局和静态变量。BSS是"Block Started by Symbol"的缩写。

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

  5. 字符串表段(.strtab): 包含字符串表,存储了符号表中的字符串。

  6. 重定位表段(.rel.text、.rel.data等): 包含重定位信息,记录了需要在链接时进行重定位的位置。

每个Section都有一个名称和一组属性,这些属性描述了Section的内容和用途。在链接过程中,多个目标文件中的相同类型的Section会被合并成一个更大的Section,以便最终生成可执行文件或共享库。

Section在汇编和链接中起到了组织和管理代码、数据以及其他信息的作用,使得程序的各个部分能够被正确地组合在一起。

Segment(段)

Segment(段)是在可执行文件在运行时加载到内存时用于组织和描述内存布局的一个概念。一个Segment通常包含一个或多个相邻的Section,这些Section在运行时被映射到内存中的相邻区域。

ELF文件格式中的Program Header Table描述了可执行文件在内存中的布局,其中的每一项对应一个Segment。Segment的类型和属性决定了在运行时如何加载和使用这一段内存。

常见的Segment类型包括:

  1. 加载可执行代码的Segment: 包含机器代码的Section,通常标记为可执行和可读。在内存中,这一段被映射为可执行的代码段。

  2. 加载可读写数据的Segment: 包含已初始化的全局和静态变量的Section,通常标记为可读和可写。在内存中,这一段被映射为可读写的数据段。

  3. 加载可读写BSS段的Segment: 包含未初始化的全局和静态变量的Section,通常标记为可读和可写。在内存中,这一段被映射为可读写的BSS段。

  4. 加载只读数据的Segment: 包含只读数据的Section,通常标记为只读。在内存中,这一段被映射为只读数据段。

每个Segment都有一个虚拟地址和一个文件偏移量,描述了它在内存中的位置和在文件中的位置。加载器(Loader)使用这些信息来将文件中的Segment映射到内存中的相应位置。

Segment在可执行文件加载时决定了程序在内存中的布局,它通过包含相关的Section来组织和描述内存中的数据和代码。这种设计提供了对内存分布的更高级别的抽象,使得可执行文件能够在不同环境中正确地加载和运行。

从链接角度和从程序角度看ELF文件

ELF文件在汇编器和链接器看来是由Section Header Table描述的一系列Section的集合,而在加载器(Loader)看来是由Program Header Table描述的一系列Segment(段)的集合。这两个表提供了不同的视角,分别对应着文件在链接和加载过程中的不同需求。如图:
在这里插入图片描述

1. Section Header Table:

  • 描述: Section Header Table包含了关于文件中各个Section的信息。每个Section对应于文件中的一部分数据,如代码段、数据段、符号表等。
  • 用途: 汇编器和链接器使用Section信息来组织和管理不同类型的数据。符号表、字符串表、代码段、数据段等都以Section的形式存在。

2. Program Header Table:

  • 描述: Program Header Table描述了可执行文件在内存中的布局,以及如何加载这些Segment。如前面描述的,Segment是一个更高层次的概念,它可能包含多个Section,但是在内存中以更连续的方式存在。
  • 用途: 加载器使用Program Header信息来决定如何加载文件中的Segment,将它们映射到内存中的合适位置,并设置程序的入口点等。

通过这两个表,ELF文件格式在设计上实现了灵活性和可扩展性。Section提供了对文件中不同类型数据的详细描述,而Segment则更侧重于在运行时的内存布局。这样的设计使得ELF文件在不同阶段(编译、链接、加载)都能够提供必要的信息,以便于文件的正确处理和执行。

参考

https://blog.csdn.net/daide2012/article/details/73065204

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

dockerfile,Docker镜像的创建

dockerfile:创建镜像,创建自定义的镜像。包括配置文件,挂载点,对外暴露的端口。设置环境变量。 docker的创建镜像的方式: 1、基于已有镜像进行创建。根据官方提供的镜像源,创建镜像,然后拉起容…

3分钟打造私人微信ChatGPT助手:新手友好指南!

接上文: https://mp.weixin.qq.com/s/RCqX0rx7TEu1gIwHEBBWKQ 本文适用于小白用户,技术大佬勿入! 前言 这里教大家如何快速的拥有一个属于自己的微信GPT助手 我个人其实不是这么部署的,但是为了方便小白用户,探索了一个…

python算法例17 下一个稀疏数

1. 问题描述 如果一个数是稀疏数,则它的二进制表示中没有相邻的1,例如5(二进制表示为101)是稀疏数,但是6(二进制表示为110)不是稀疏数,本例将给出一个n,找出大于或等于n…

记深圳盐田IBM X3550 m4服务器board故障维修一例

故障服务器型号:ibm system x3550 m4 服务器故障问题:无法开机 面板叹号黄灯,小面板board故障亮灯 响应时效:当天工程师带配件到现场检修并恢复操作系统和业务系统 维修过程:工程师经过与用户的交流中大致判定了故障…

Unity与Android交互通信系列(1)

运行于Android平台的原生App直接调用Android接口,可以享受近水楼台先得月的优势,而使用Unity开发的Android应用App则像是二等公民,使用Android原生功能特性就要麻烦得多,比如WiFi、蓝牙等,特别是一些高级功能特性&…

ArrayList集合的两个实例应用,有趣的洗牌算法与杨辉三角

本节课的内容,就让我们来学习一下ArrayList集合的应用,ArrayList的本质就是一个顺序表,那下面一起来学习吧 目录 一、杨辉三角 1.题目详情及链接 2.剖析题目 3.思路及代码 二、洗牌算法 1.创造牌对象 2.创造一副牌 3.洗牌操作 4.发…

大数据笔记(待续)

mysql 缓存技术 数据库和缓存双写数据一致性问题常见的解决方案 常见方案通常情况下,我们使用缓存的主要目的是为了提升查询的性能。大多数情况下,我们是这样使用缓存的: 用户请求过来之后,先查缓存有没有数据,如果有…

学习笔记 -- CAN系统基础

一、CAN物理层 一个双节点CAN网络示意图如下,两颗120Ω终端电阻并联呈现总线电阻60Ω。 A、B两个节点的CAN收发器(Transceiver),只负责电平转换。当总线静默时,收发器内部的2.5V电源经15KΩ电阻把CAN-H和CAN-L都拉到2.…

前端(一):HTML+CSS

参考课程:23最新版web前端开发_哔哩哔哩_bilibili 文档:GitHub - codeNiuMa/HTML-md-file: 学习HTML课程时的资料 目录 1 HTML 1.1 骨架 DOCTYPE html标签 head标签 body标签 title标签 meta标签 1.2 标签标题h1 1.3 段落p 1.4 水平线 1.5 图片img 1.6 …

【Android12】Android Framework系列--AMS启动Activity分析

AMS启动Activity分析 通过ActivityManagerService(AMS)提供的方法,可以启动指定的Activity。比如Launcher中点击应用图标后,调用AMS的startActivity函数启动应用。 AMS提供的服务通过IActivityManager.aidl文件定义。 // frameworks/base/core/java/an…

【AI底层逻辑】——数学与机器学习:优雅的智慧之舞

目录 “宝藏网站” 聊聊数学 “华尔兹” “智慧之舞” 后续的章节我们将迎来新的篇章,新的切入点探索AI的奥秘,通过揭示高数、矩阵、概率论等数学知识与机器学习的关系来深入理解AI的奥秘! “宝藏网站” 开头先给大家上几个宝藏网站&am…

【离散数学】——期末刷题题库(欧拉图和哈密顿图)

🎃个人专栏: 🐬 算法设计与分析:算法设计与分析_IT闫的博客-CSDN博客 🐳Java基础:Java基础_IT闫的博客-CSDN博客 🐋c语言:c语言_IT闫的博客-CSDN博客 🐟MySQL&#xff1a…

java中,用函数对象表示策略

简而言之,函数指针的主要用途就是实现策略(Strategy)模式。 Java没有提供函数指针,但是可以用对象引用实现相同的功能。调用对象上的方法通常是执行该对象上某项操作。 在Java中,使用函数对象(Function Object)表示策…

《数据结构、算法与应用C++语言描述》-机器调度-最长处理时间(LPT)

机器调度 完整可编译运行代码见:Github::Data-Structures-Algorithms-and-Applications/_28LongestProcessingTime 问题描述 一个工厂具有 m台一模一样的机器。我们有n 个任务需要处理。设作业i的处理时间为 t i t_i ti​,这个时间包括把作业放入机器…

Amazon Aurora Limitless Database:数据库管理的全新境界

授权说明:本篇文章授权活动官方亚马逊云科技文章转发、改写权,包括不限于在 亚马逊云科技开发者社区, 知乎,自媒体平台,第三方开发者媒体等亚马逊云科技官方渠道 在当今数亿用户、PB级数据和数百万交易的业务环境中,数…

12.14_黑马数据结构与算法笔记Java

目录 120 二叉搜索树 min max 121 二叉搜索树 put 122 二叉搜索树 前任后任1 123 二叉搜索树 前任后任2 124 二叉搜索树 删除1 125 二叉搜索树 删除2 126 二叉搜索树 删除3 127 二叉搜索树 删除 递归1 128 二叉搜索树 删除 递归2 129 二叉搜索树 范围查询 130 二叉搜…

KUKA机器人如何隐藏程序或程序段?

KUKA机器人如何隐藏程序或程序段? 如下图所示,新建一个示例程序进行说明, 如下图所示,如果红框中的动作指令不想让别人看到,想隐藏起来,如何做到? 如下图所示,在想要隐藏的程序或程序段的前后,分别添加 ;fold 和 endfold指令(这里要注意是英文状态下的输入法), 如…

国标GB28181安防监控系统/磁盘阵列EasyCVR(V.3.4)新亮点:免保活功能

TSINGSEE青犀近日发布了EasyCVR安防管理平台的V.3.4版本,其中一大亮点就是很多朋友都在咨询的“免保活”功能,那么,什么是“免保活”功能?又该如何配置呢? 在EasyCVR平台有个【按需直播】按钮,顾名思义&…

如何部署Portainer容器管理工具+cpolar内网穿透实现公网访问管理界面

文章目录 前言1. 部署Portainer2. 本地访问Portainer3. Linux 安装cpolar4. 配置Portainer 公网访问地址5. 公网远程访问Portainer6. 固定Portainer公网地址 前言 本文主要介绍如何本地安装Portainer并结合内网穿透工具实现任意浏览器远程访问管理界面。Portainer 是一个轻量级…

大象elephant目标检测数据集VOC+YOLO格式2300张

大象是长鼻目象科的哺乳动物,有两个属,是世界上最大的陆生动物。其像柱子一样的四肢和宽厚的脚掌可以稳稳支撑住庞大的身体。巨大的头上长有蒲扇状的大耳朵和长且有弹性的鼻子。象耳上有丰富的血管,可以有效散热。鼻子和上唇合而为一的象鼻由…