LinuxELF文件格式详解--Linux进程的管理与调度(十二)

ELF文件解析和加载(附代码) 目录:1. elf文件基本概念2. elf文件结构3. elf文件装载4. 代码实现1.elf文件基本概念elf文件是一种目标文件格式,用于定义不同类型目标文件以什么样的格式,都放了些什么东西。主要 用于linux平台。windows下是PE/COFF格式。 可执行文件、可重定位文件(.o)、共享目标文件(.so)、核心转储文件都是以elf文件格式存... 阅读详情

对象文件格式
对象文件

首先,你需要知道的是所谓对象文件(Object files)有三个种类: 

  1. 可重定位的对象文件(Relocatable file) 
  2. 可执行的对象文件(Executable file) 
  3. 可被共享的对象文件(Shared object file)
  • 可重定位的对象文件(Relocatable file)

适于链接的可重定位文件(relocatable file),包含二进制代码和数据,能与其他可重定位对象文件在编译时合并创建出一个可执行文件。

这是由汇编器汇编生成的 .o 文件。后面的链接器(link editor)拿一个或一些 Relocatable object files 作为输入,经链接处理后,生成一个可执行的对象文件 (Executable file) 或者一个可被共享的对象文件(Shared object file)。我们可以使用 ar 工具将众多的 .o Relocatable object files 归档(archive)成 .a 静态库文件。如何产生 Relocatable file,你应该很熟悉了,请参见我们相关的基本概念文章和JulWiki。另外,可以预先告诉大家的是我们的内核可加载模块 .ko 文件也是 Relocatable object file。

  • 可执行的对象文件(Executable file)

适于执行的可执行文件(executable file),包含可以直接拷贝进行内存执行的二进制代码和数据。用于提供程序的进程映像,加载的内存执行。

这我们见的多了。文本编辑器vi、调式用的工具gdb、播放mp3歌曲的软件mplayer等等都是Executable object file。你应该已经知道,在我们的 Linux 系统里面,存在两种可执行的东西。除了这里说的 Executable object file,另外一种就是可执行的脚本(如shell脚本)。注意这些脚本不是 Executable object file,它们只是文本文件,但是执行这些脚本所用的解释器就是 Executable object file,比如 bash shell 程序。

  • 可被共享的对象文件(Shared object file)

共享目标文件(shared object file),一种特殊的可重定位对象文件,能在加载时或运行时,装载进内存进行动态链接。连接器可将它与其它可重定位文件和共享目标文件连接成其它的目标文件,动态连接器又可将它与可执行文件和其它共享目标文件结合起来创建一个进程映像。

这些就是所谓的动态库文件,也即 .so 文件。如果拿前面的静态库来生成可执行程序,那每个生成的可执行程序中都会有一份库代码的拷贝。如果在磁盘中存储这些可执行程序,那就会占用额外的磁盘空间;另外如果拿它们放到Linux系统上一起运行,也会浪费掉宝贵的物理内存。如果将静态库换成动态库,那么这些问题都不会出现。动态库在发挥作用的过程中,必须经过两个步骤:

  1. 链接编辑器(link editor)拿它和其他Relocatable object file以及其他shared object file作为输入,经链接处理后,生存另外的 shared object file 或者 executable file。
  2. 在运行时,动态链接器(dynamic linker)拿它和一个Executable file以及另外一些 Shared object file 来一起处理,在Linux系统里面创建一个进程映像。

文件格式

本质上,对象文件只是保存在磁盘文件中的一串字节,每个系统的文件格式都不尽相同:

  1. Bell实验室的第一个Unix系统使用 a.out格式。
  2. System V Unix的早期版本使用 Common Object File Format(COFF)。
  3. Windows NT使用COFF的变种,叫做 Portable Executable(PE)。
  4. 现代Unix系统,包括Linux、新版System V、BSD变种、Solaris都使用 Executable and Linkable Format(ELF)。

ELF对象文件格式

ELF(Executable and Linking Format)是一种对象文件的格式,用于定义不同类型的对象文件(Object files)中都放了什么东西、以及都以什么样的格式去放这些东西。它自最早在 System V 系统上出现后,被 xNIX 世界所广泛接受,作为缺省的二进制文件格式来使用。可以说,ELF是构成众多xNIX系统的基础之一。

ELF代表Executable and Linkable Format。他是一种对可执行文件、目标文件和库使用的文件格式。

他在Linux下成为标准格式已经很长时间, 代替了早年的a.out格式。ELF一个特别的优点在于, 同一文件格式可以用于内核支持的几乎所有体系结构上, 这不仅简化了用户空间工具程序的创建, 也简化了内核自身的程序设计。例如, 在必须为可执行文件生成装载程序例程时。

但是文件格式相同并不意味着不同系统上的程序之间存在二进制兼容性, 例如, FreeBSD和Linux都使用ELF作为二进制格式。尽管二者在文件中组织数据的方式相同。但在系统调用机制以及系统调用的语义方面, 仍然有差别。这也是在没有中间仿真层的情况下, FreeBSD程序不能在linux下运行的原因(反过来同样是如此)。

有一点是可以理解的, 二进制程序不能在不同体系结构交换(例如, 为Alpha CPU编译的Linux二进制程序不能在Sparc Linux上执行), 因为底层的体系结构是完全不同的。但是由于ELF的存在, 对所有体系结构而言, 程序本身的相关信息以及程序的各个部分在二进制文件中编码的方式都是相同的。

Linux不仅将ELF用于用户空间程序和库, 还用于构建模块。内核本身也是ELF格式。

ELF文件标准历史

ELF是一种开放格式, 其规范可以自由获取。

在ELF格式出来之后,TISC(Tool Interface Standard Committee)委员会定义了一套ELF标准。你可以从这里(http://refspecs.freestandards.org/elf/)找到详细的标准文档

20世纪90年代,一些厂商联合成立了一个委员会(TISC委员会),起草并发布了一个ELF文件格式标准供公开使用,并且希望所有人能够遵循这项标准并且从中获益。1993年,委员会发布了ELF文件标准。当时参与该委员会的有来自于编译器的厂商,如Watcom和Borland;来自CPU的厂商如IBM和Intel;来自操作系统的厂商如IBM和Microsoft。1995年,委员会发布了ELF 1.2标准,自此委员会完成了自己的使命,不久就解散了。所以ELF文件格式标准的最新版本为1.2。

文件类型 e_type成员表示ELF文件类型,即前面提到过的3种ELF文件类型,每个文件类型对应一个常量。系统通过这个常量来判断ELF的真正文件类型,而不是通过文件的扩展名。相关常量以“ET_”开头,

TISC委员会前后出了两个版本,v1.1和v1.2。两个版本内容上差不多,但就可读性上来讲,我还是推荐你读 v1.2的。因为在v1.2版本中,TISC重新组织原本在v1.1版本中的内容,将它们分成为三个部分(books): 
a) Book I 
介绍了通用的适用于所有32位架构处理器的ELF相关内容 
b) Book II 
介绍了处理器特定的ELF相关内容,这里是以Intel x86 架构处理器作为例子介绍 
c) Book III 
介绍了操作系统特定的ELF相关内容,这里是以运行在x86上面的 UNIX System V.4 作为例子介绍

值得一说的是,虽然TISC是以x86为例子介绍ELF规范的,但是如果你是想知道非x86下面的ELF实现情况,那也可以在http://refspecs.freestandards.org/elf/中找到特定处理器相关的Supplment文档。比方ARM相关的,或者MIPS相关的等等。另外,相比较UNIX系统的另外一个分支BSD Unix,Linux系统更靠近 System V 系统。所以关于操作系统特定的ELF内容,你可以直接参考v1.2标准中的内容。
 

本文所使用的测试程序结构


add.c

#include <stdio.h>
#include <stdlib.h>

// 不指定寄存器实现两个整数相加
int Add(int a, int b)
{
    __asm__ __volatile__
    (
        //"lock;\n"
        "addl %1,%0;\n"
        : "=m"(a)
        : "r"(b), "m"(a)
      //  :
    );

    return a;
}

sub.c
 

#include <stdio.h>
#include <stdlib.h>

// 不指定寄存器实现两个参数相减
int Sub(int a, int b)
{
    __asm__ __volatile__
    (
        "subl %1, %0;"
        : "=m"(a)
        : "r"(b), "m"(a)
 //       :
    );

    return a;
}

testelf.c
 

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    int a = 3, b = 5;

    printf("%d + %d = %d\n", a, b, Add(a, b));
    printf("%d - %d = %d\n", a, b, Sub(a, b));


    return EXIT_SUCCESS;
}

Makefile
 

target=testelf_normal testelf_dynamic testelf_static

MAIN_OBJS=testelf.o
SUBS_OBJS=add.o sub.o

DYNA_FILE=libtestelf.so
STAT_FILE=libtestelf.a

all:$(target)

%.o : %.c
    $(CC) -c $^ -o $@

clean :
    rm -rf $(MAIN_OBJS) $(SUBS_OBJS)
    rm -rf $(DYNA_FILE) $(STAT_FILE)
    rm -rf $(target)


# Complie the execute
testelf_normal:$(MAIN_OBJS) $(SUBS_OBJS)
    gcc $^ -o $@

testelf_dynamic:$(MAIN_OBJS) $(DYNA_FILE)
    gcc  $^ -o $@ -L./ -ltestelf

testelf_static:$(MAIN_OBJS) $(STAT_FILE)
    gcc  testelf.o -o $@ -static -L./ -ltestelf

# Complie the Dynamic Link Library libtestelf.so
libtestelf.so:$(SUBS_OBJS)
    gcc -fPCI -shared $^ -o $@

# Complie the Static Link Library libtestelf.so
libtestelf.a:$(SUBS_OBJS)
    ar -r $@ $^

我们编写了两个库函数分别实现add和sub的功能, 然后编写了一个测试代码testelf.c调用了Add和Sub.

然后我们的Mmakefile为测试程序编写了3分程序

  1. 普通的程序testelf_normal, 由add.o sub.o 和testelf.o直接链接生成
  2. 动态链接程序testelf_dynamic, 将add.o和sub.o先链接成动态链接库libtestelf.so, 然后再动态链接生成testelf_dynamic
  3. 静态链接程序testelf_static, 将add.o和sub.o先静态链接成静态库libtestelf.a, 然后再静态链接生成可执行程序testelf_staticke

我们在源代码目录执行make后会完成编译, 编译完成后

  • add.o, sub.o和testelf.o是可重定位的对象文件(Relocatable file)
  • libtestelf.so是可被共享的对象文件(Shared object file)
  • testelf_normal, testelf_dynamic和testelf_static是可执行的对象文件(Executable file)

如下图所示
对象æä»¶

ELF可执行与链接文件格式详解


布局和结构

ELF文件由各个部分组成。

为了方便和高效,ELF文件内容有两个平行的视角:一个是程序连接角度,另一个是程序运行角度

elfæä»¶çå¸å±åç»æ

首先图的左边部分,它是以链接视图来看待elf文件的, 从左边可以看出,包含了一个ELF头部,它描绘了整个文件的组织结构。它还包括很多节区(section)。这些节有的是系统定义好的,有些是用户在文件在通过.section命令自定义的,链接器会将多个输入目标文件中的相同的节合并。节区部分包含链接视图的大量信息:指令、数据、符号表、重定位信息等等。除此之外,还包含程序头部表(可选)和节区 头部表,程序头部表,告诉系统如何创建进程映像。用来构造进程映像的目标文件必须具有程序头部表,可重定位文件不需要这个表。而节区头部表(Section Heade Table)包含了描述文件节区的信息,每个节区在表中都有一项,每一项给出诸如节区名称、节区大小这类信息。用于链接的目标文件必须包含节区头部表,其他目标文件可以有,也可以没有这个表。

需要注意地是:尽管图中显示的各个组成部分是有顺序的,实际上除了 ELF 头部表以外,其他节区和段都没有规定的顺序。

右半图是以程序执行视图来看待的,与左边对应,多了一个段(segment)的概念,编译器在生成目标文件时,通常使用从零开始的相对地址,而在链接过程中,链接器从一个指定的地址开始,根据输入目标文件的顺序,以段(segment)为单位将它们拼装起来。其中每个段可以包括很多个节(section)。

elf头部

除了用于标识ELF文件的几个字节外, ELF头还包含了有关文件类型和大小的有关信息, 以及文件加载后程序执行的入口点信息

  • 程序头表(program header table)

程序头表向系统提供了可执行文件的数据在进程虚拟地址空间中组织文件的相关信息。他还表示了文件可能包含的段数据、段的位置和用途

  • 段segment

各个段保存了与文件爱你相关的各种形式的数据, 例如,符号表、实际的二进制码、固定值(如字符串)活程序使用的数值常数

  • 节头表section

包含了与各段相关的附加信息。

 

 

bin、hex、exe、elf文件类型到底有何区别?如何解读hex文件和elf文件?...相关内容都在这里! 详细的解释常见的bin、hex、elf等文件格式,分享bin和hex的互转工具,详细解读readelf的用法等等内容!!开发必备基础知识!! 阅读详情

相关推荐

剖析ELF文件格式的内容———文件头,段表,符号....(第三章)

目录 1.extern "C" 1.编译阶段——取名 2.链接阶段——找对应的名 参考: 2.extern变量名 1.extern "C" 在阅读代码的时候,常常会看到下面的代码片段: #ifdef __cplusplus extern "C" { #endif // 写例如dll导出函数的定义 #ifdef __cplusplus } #endif 这是一...

u012138730的专栏 8389

ELF文件详解

一、ELF概述 1、ELF的定义 ELF(Executable and Linkable Format)文件是一种目标文件格式,常见的ELF格式文件包括:可执行文件、可重定位文件(.o)、共享目标文件(.so)、核心转储文件等。 ELF主要用于Linux平台,Windows下是PE/COFF格式。 2、ELF文件的结构 一个完整的ELF文件一般会包括如下几个内容:ELF头、Section头、Segment头和Section。 其中由Section头组成的集合称为Section头表,...

PeakJin的博客 2万+

ELF文件格式详解(中文)

详细介绍了ELF文件结构,基于 ELF 规范 v1.2 版本 ,作者:赵凤阳,比较详细,不可多得。

ELF文件格式解析

ELF格式分析

夏天Alex 5444

ELF文件格式规范1.2

Executable and Linking Format Specification 1.2

手把手教你用EG2153搭建开关电源:SOP-8封装驱动芯片的5个设计技巧

本文详细介绍了使用EG2153自振荡半桥驱动芯片搭建开关电源的五个核心设计技巧。内容涵盖从深入理解芯片工作机制、频率编程计算误区、SOP-8封装的热管理方案,到死区时间评估与外部保护电路设计,以及实战调试与故障排查指南,旨在帮助工程师实现稳定可靠的小功率电源设计。

weixin_29200485的博客 376

ELF文件介绍

https://blog.csdn.net/GrayOnDream/article/details/124564129

二进制模----细微行动改变影响世界 5817

Shopee商品详情页反爬实战:手把手逆向x-sap-Ri和x-sap-Sec参数(附完整调试过程)

本文详细解析了Shopee商品详情页反爬机制中的x-sap-Ri和x-sap-Sec参数逆向过程。通过JS逆向技术,从环境数据采集到多层哈希运算,完整拆解了这两个关键参数的生成逻辑,并提供了实战技巧和Node.js实现方案,帮助开发者应对Shopee的动态加密挑战。

weixin_33701251的博客 1595

(全网最细)ELF文件详解

ELF文件解析

wardenjohn的博客 9152

利用Civil3D装配设计器(SAC)建设高度形状自适应挡土墙

之前的模型都是点线,最后加一个形状,形成面。再根据现场测得的挡土墙的墙脚的点生成中心线(alignment),在中心线的基础上生成在现有地面(existing ground level)的高程(profile)。简单的说,该墙的墙趾啊,墙踵啊,基底下面那个把儿啊,都是随着高度变化的,而高度是随着下面这个高程图变化的。接着出现角度和Y的文本框,角度92,y 值随便写一个,然后重要的是,高程目标选路面(优先于Y值)。意思是P2的高度,也就是路面的高程,减去P10,墙脚高程,再减去墙脚埋进地里的深度0.8m。

测量老覃 的博客 1126

《寻秦OL》.ani动画逆向解析:二进制结构与Unity重实现

动画文件格式是游戏资源逆向的核心入口,其本质是一组按特定规则组织的二进制数据流。理解魔数识别、字节序、字段对齐与差分编码等底层原理,是解析非标准格式的关键前提。技术价值在于绕过黑盒协议,直接从静态客户端提取可验证的原始语义;典型应用场景包括老游戏复刻、美术资产抢救、引擎跨平台迁移及教学级逆向训练。本文以《寻秦OL》的`.ani`文件为实例,深入剖析其C风格结构布局、GB2312中文命名、16位定点数旋转表示及帧主序差分存储机制,并基于C#在Unity中完成从字节流到AnimationClip的端到端重建,覆

weixin_30368981的博客 639

ELF文件格式简介

  简单了解下ELF文件的格式。 1 简介   可执行与可链接格式 (Executable and Linkable Format,ELF),常被称为 ELF格式,是一种用于可执行文件、目标代码、共享库和核心转储(core dump)的标准文件格式,一般用于类Unix系统,比如Linux,Macox等。ELF 格式灵活性高、可扩展,并且跨平台。比如它支持不同的字节序和地址范围,所以它不会不兼容某一特别的 CPU 或指令架构。这也使得 ELF 格式能够被运行于众多不同平台的各种操作系统所广泛采纳。   E.

梦的灰色边沿... 1万+

《数据分析岗笔试高频题:字节常用的SQL与AB测试考题解析》

• 核心考点:用RANK()/DENSE_RANK()/ROW_NUMBER()排序,SUM() OVER()计算累积值。◦ 用公式n=2*(Zα/2+Zβ)^2*σ²/δ²,取α=0.05,β=0.2,计算得每组需260人;◦ 关注字节技术公众号“字节跳动数据团队”,学习真实AB测试案例(如“推荐算法优化实验”)。• 题型分布:SQL编程题(40%)、AB测试方案设计(30%)、数据洞察题(30%);◦ 牛客网“字节跳动SQL真题”(如“统计用户7日留存”“广告投放ROI计算”)。

2501_91651594的博客 1107

ELF 格式详解

可重定位的目标文件(Relocatable)也就是通常称的目标文件,后缀为.o可执行文件(Executable)共享库(Shared Object)共享文件:也就是通常称的库文件,后缀为.so注1: Linux中的readelf命令可以查看ELF文件的详细信息注2:ELF文件只能在操作系统环境下运行,裸机环境运行的是BIN文件;编译器默认输出的文件格式是ELF格式,可以使用objcopy命令转化为BIN文件:将name.elf转化为name.bin文件armbinary。

kunkliu的博客 7117

【Python进阶】VSCode Python开发完全指南:从环境配置到高效调试

本文通过15个实战案例,系统讲解VSCode进行Python开发的环境配置、编码技巧、调试方法及性能优化,帮助初学者快速构建专业开发环境。

赶紧的博客 3724

搭建一个简单的 Django + Vue 项目

在本文中,我将为您详细介绍如何搭建一个简单的 Django + Vue 项目。Django 是一个使用 Python 编写的高级 Web 框架,而 Vue 是一个流行的 JavaScript 框架,用于构建用户界面。通过结合 Django 和 Vue,我们可以创建强大的全栈 Web 应用程序。创建 Django 项目设置 Django 后端创建 Vue 前端连接 Django 和 Vue让我们开始吧!

JfpBlockchain的博客 350

计算机原理系列之二 -------- 详解ELF文件

欢迎访问我的个人博客: luomuxiaoxiao.com 一、ELF文件类型 二、ELF文件结构 ELF Header Section Section Header Table Program Header Table 三、实践 四、总结 五、参考阅读 下面我们介绍一种文件格式:ELF格式,全名为可执行和可链接格式(Executable and Linkable Format)。维基百科中...

luomuxiaoxiao98的专栏 1719

【YOLOv8改进-注意力机制】BRA(bi-level routing attention ):双层路由注意力

【YOLOv8改进-注意力机制】BRA(bi-level routing attention ):双层路由注意力我们提出了一种新颖的动态稀疏注意力机制,通过双层路由实现更加灵活且具有内容感知的计算分配。

专注于图像领域,主要研究内容包括计算机视觉和深度学习,特别是在图像分类、目标检测和图像生成等方面有深入的研究和实践经验。 3166

可执行文件格式:ELF

linux可执行文件格式ELF

海里卖咸鱼的博客 3276

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

Linux系统:ELF文件的定义与加载以及动静态链接

ELF(Executable and Linkable Format)是类Unix系统中的标准二进制文件格式,用于存储可执行程序、目标文件和共享库。其结构包括ELF头、程序头表、节头表和数据区域,分别描述文件属性、内存布局、逻辑划分和实际内容。ELF文件的形成经历编译、汇编和链接阶段,链接器负责合并节、分配虚拟地址并修正符号引用。程序加载时,内核解析程序头表,通过mmap将段映射到进程虚拟地址空间,并利用缺页异常机制动态分配物理内存。动态链接通过地址无关代码(PIC)和全局偏移表(GOT)实现库的灵活加

yue_2899799318的博客 1872

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

ELF(Executable and Linking Format)文件结构描述

ELF文件(Executable and Linking Format)是用在Linux系统下的一种目标文件(object file)存储格式。典型的目标文件有如下3类: 可重定向文件(relocatable file)可重定向文件里面包含了代码和数据,用于和其他可重定向文件一起链接形成一个可执行文件或者动态库。 可执行文件(executable file) 可执行文件里面...

海棠花的博客 3263

ELF文件详解—初步认识

讲解ELF文件格式,目标文件再不同的系统或平台上具有不同的命名格式,在Unix和X86-64 Linux上称为ELF(Executable and Linkable Format, ELF)。 ELF文件格式提供了两种不同的视角,在汇编器和链接器看来,ELF文件是由Section Header Table描述的一系列Section的集合,而执行一个ELF文件时,在加载器(Loader)看来它是由Program Header Table描述的一系列Segment的集合

daide2012的博客 9万+

ELF文件

ELF是一种用于二进制文件、可执行文件、目标代码、共享库和核心转储的标准文件格式。 1.ELF文件类型 ELF的文件类型主要有三种,可重定位的目标文件、可执行的目标文件、可被共享的目标文件。 (1)可重定位的目标文件 由汇编器生成的.o文件,链接器拿一个或者一些可重定位的目标文件作为输入,经过链接处理后,生成一个可执行的目标文件或者一个可被共享的对象文件.so,可以使用ar

烟花易冷 1139
上一篇: JAVA 学习好的网站 --- 加油 2019.11.07开启JAVA的学习
下一篇: java自学经历分享
废言Pro
博客等级 码龄16年 1092粉丝 142原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值