NCEPUwiki NCEPUwiki
首页
分类
  • 常用账号与默认密码
  • 常用网站
  • 常用电话
  • 教室借用
  • 常用公众号
  • 学生组织与社团名单
  • 电动自行车管理
学习资料 (opens new window)
GitHub (opens new window)
首页
分类
  • 常用账号与默认密码
  • 常用网站
  • 常用电话
  • 教室借用
  • 常用公众号
  • 学生组织与社团名单
  • 电动自行车管理
学习资料 (opens new window)
GitHub (opens new window)
  • Python配置
  • VisualStudio安装与卸载
  • Git教程
  • GNU⧸Linux文件系统层级结构
  • ELF文件格式
    • ELF文件格式
      • 参考资料
      • ELF文件类型
    • ELF文件内部结构
      • ELF header
      • Program Header Table
      • Section header table
      • Sections
    • GNU Binutils
      • readelf
      • objdump
      • objcopy
  • 计算机知识专题
NCEPUwiki-Group
2026-06-06
目录

ELF文件格式

ELF文件格式

可执行与可链接格式(ELF,Executable and Linkable Format)

此前的写法是Extensible Linking Format,常被称为ELF格式

ELF格式是用于可执行文件、目标代码、共享库和核心转储的标准文件格式,用于类Unix系统(Unix-like)

参考资料

ELF标准官方网站:https://gabi.xinuos.com/ (opens new window)

Linux基金会参考规范:https://refspecs.linuxfoundation.org/ (opens new window)

参考视频链接:https://www.bilibili.com/video/BV1mR4y1g7s1/ (opens new window)

参考书籍:《程序员的自我修养——链接、装载与库》

ELF文件类型

中文名 英文名 后缀名 来源 功能
可重定位文件 Relocatable Files .o/.a 编译器,汇编器 包含代码与数据,但地址未定,需要与其他目标文件链接才能形成可执行文件
可执行文件 Executable File 链接器 可直接加载到内存并运行的程序
共享目标文件 Shared Object File .so 动态库文件,在程序运行时被动态加载和链接
核心转储文件 Core Dump File core 操作系统 程序崩溃时内存映像,用于事后调试

ELF文件内部结构

ELF文件内部四大组成部分

英文名 中文名 内容概述 用途
ELF Header ELF文件头 ELF文件基本信息
Program Header Table 程序头表 描述系统应如何创建进程的内存映像
运行时加载
Section Header Table 节/段头表 描述Sections的位置,大小,类型,链接信息 链接时处理
Sections 节/段 实际代码,数据,符号等信息

备注

  • ELF Header必须位于文件最开始,其中包含Program Header Table和Section Header Table在ELF文件中偏移量用于寻址。因此其他部分在文件中的顺序不是绝对固定的,可通过ELF文件头中的字段找到各段的偏移量。

  • 寻址关系:

    • ELF Header --> Program Header Table和Section Header Table
    • Section Header Table --> 各个Sections
  • 程序头表,Program Header Table简写为PHT

  • 节/段头表,Section Header Table简写为SHT


ELF文件类型与ELF内部四大组成部分的包含关系

文件类型 ELF头 PHT SHT Sections
可重定位文件 必须 无 必须 必须
可执行文件 必须 必须 可选 可选
共享目标文件 必须 必须 可选 可选
核心转储文件 必须 必须 无 无

Q & A

  1. 为什么可执行文件和共享目标文件的SHT和Sections是可选的?而PHT是必须的?
  • Section Header Table定义了Sections大小和位置,没有Section Header Table也就无法对应、区分各个Sections
  • 但Sections并未消失,只是换了一种形式存在与ELF文件中
    对于可执行文件或共享库,链接完成后通常会用strip工具移除Section Header Table,以减小文件体积;但Sections对应的数据仍然存在于文件中,通过Program Header Table映射到内存段,用于程序变为进程加载到内存。
  • 可执行文件和共享目标文件SHT和Sections也可以保留以方便调试
  1. 为什么可重定位文件的SHT和Sections是必须的?而不需要PHT?
  • 可重定位文件只有一个任务就是链接,链接需要若干可重定位文件的SHT和Sections提供各个段的详细信息以便将Sections合并为Segment
  • 可重定位文件不需要也不能加载到内存中执行,不需要PHT

ELF header

ELF header首段16Bytes

image

‍

英文名 中文名 概述
Magic Number 魔数 最开始的4个字节是7f 45 4c 46,用于标识这是ELF文件
Class 文件类型 ELF32(32 位)/ELF64(64 位)
Data 数据编码 字节序,LSB(小端序),MSB(大端序)
Version ELF版本
通常是 1
OS/ABI 操作系统/ABI 目标操作系统和ABI
ABI Version ABI版本 ABI的版本
Type 文件类型 标识文件的具体类型
ET_REL:可重定位文件(.o)
ET_EXEC:可执行文件
ET_DYN:共享目标文件(.so)/位置无关可执行文件(PIE)
ET_CORE:核心转储文件
Machine 机器类型 目标指令集架构
x86_64,ARM,MIPS,RISC-V
Entry point address 入口点地址 程序开始执行的虚拟内存地址
对于可执行文件,这是 _start 函数的地址
(通常由C运行时库crt0.o提供)
Start of program headers 程序头表偏移 程序头表(Program Header Table)在文件中的起始位置
Start of section headers 节头表偏移 节头表(Section Header Table)在文件中的起始位置
Flags 标志 与特定处理器架构相关的标志
Size of this header ELF 头大小
Size of program headers 程序头表条目大小
Number of program headers 程序头表条目数量
Size of section headers 节头表条目大小
Number of section headers 节头表条目数量
Section header string table index 节名字符串表索引 指向.shstrtab 节的索引,该节存储了所有节名称的字符串。

Program Header Table

程序头表(PHT,Program Header Table)

运行时必需:描述了如何将文件的段(Segments)加载到内存,包括段的类型(如可加载段LOAD、动态链接段DYNAMIC)、在文件中的偏移、虚拟地址和内存中的对齐要求。操作系统用它来创建进程的内存映像。

将多个Sections组合成运行时的Segment

Section header table

节头表(SHT,Section Header Table)

链接时必需:提供合并和重定位的所有信息,指导链接器将多个.o文件组装成可执行文件或共享库。

输出表格中的关键字段

英文名 概述 备注
Name 节区名称
Type 节区的类型
Address 节区加载到内存时的虚拟地址
Off 节区在 ELF 文件中的偏移量
Size 节区的总大小
ES 条目大小(Entry Size)
Flg 定义该节区的访问权限和属性
A (ALLOC):该节区在进程运行时需要占用内存。
X (EXEC):该节区的内容是可执行的,通常指代码。
W (WRITE):该节区在运行时内容是可修改的。
Lk 链接(Link)
Inf 额外信息(Info)
Al 对齐(Alignment)

‍

Sections

节/段(Sections)

概述作用:包含程序的实际代码、数据、符号表、重定位信息、调试信息等。节是链接器 (ld ) 在编译链接阶段主要操作的对象。链接器将不同目标文件中的同名节(如 .text, .data) 合并,解析符号引用,进行重定位等。

常见Sections

Sections 功能 英文名 中文名
.text 程序机器指令代码
.data 已初始化全局变量,静态变量
.bss 未初始化的静态变量,初始化为0的全局变量和静态变量
只是占位符,不占据实际空间,当程序运行时,会在内存中分配这些变量,并初始化为0
记忆口诀:(bss,Better Save Space,更好节省空间)
.rodata 只读数据(const常量,字符串)
.comment 编译工具信息 注释信息节
.symtab 存储函数和全局变量的信息 Symbol Table 符号表
.strtab 存储.symtab 中符号名称的字符串 String Table 字符串表
.dynsym 动态链接所需的符号子集 动态符号表
.dynstr 存储.dynsym 中符号名称的字符串 动态字符串表
.debug 调试信息
.line 原始C程序的行号和.text section中机器指令之间的映射
.rel.text .text节中需要重定位的位置信息
用于静态链接的目标文件
Relocation Table 代码重定位表
.rel.data data 节中需要重定位的位置信息
用于静态链接的目标文件
数据重定位表
.rel.dyn 用于动态链接的运行时重定位信息 动态重定位表
.rel.plt 用于动态链接的运行时重定位信息 PLT 重定位表
.dynamic 包含动态链接器所需的关键信息 动态信息节
.got 动态链接时存储外部变量地址。 Global Offset Table 全局偏移表
.plt 用于动态链接时调用外部函数。包含跳转到动态链接器解析地址的存根代码。 Procedure Linkage Table 过程链接表
.init 包含程序初始化时(在main之前)执行的代码 初始化代码节
.fini
包含程序退出时(在main返回后)执行的代码 终止代码节
.ctors 指向全局构造函数(C++ 全局对象构造器,C 的 __attribute__((constructor)) 函数)的指针数组。 构造函数指针表
.dtors 指向全局析构函数(C++ 全局对象析构器,C 的 __attribute__((destructor)) 函数)的指针数组。 析构函数指针表
.shstrtab 存储所有节名称的字符串
由ELF头的e_shstrndx字段索引
节名称字符串表

‍

GNU Binutils

GNU Binutils是用来处理许多格式的目标文件(包括elf文件)一整套的编程语言工具程序

常见工具如下表

工具名称 说明
as GNU汇编器
ld GNU链接器
ar 归档工具(.o文件和.a文件转换)
stripe 去除符号表与调试信息
nm 列出目标文件中的符号表
objcopy 转换成二进制代码
objdump 反汇编
readelf 显示ELF文件详细信息
string 提取文件中的可打印字符串

其他工具

ldd:列出可执行文件或共享库所依赖的共享库

readelf

readelf -h 查看ELF header

readelf -h 查看程序头表(Program Header Table)

readelf -SW 查看节头表(Section Header Table)

readelf -s 显示符号表 (.symtab/.dynsym)

readelf -d 显示动态段 (.dynamic)

示例

#查看ELF header
readelf -h main.o
#输出
ELF Header:
  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 
  Class:                             ELF32
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              REL (Relocatable file)
  Machine:                           ARM
  Version:                           0x1
  Entry point address:               0x0
  Start of program headers:          0 (bytes into file)
  Start of section headers:          720 (bytes into file)
  Flags:                             0x5000000, Version5 EABI
  Size of this header:               52 (bytes)
  Size of program headers:           0 (bytes)
  Number of program headers:         0
  Size of section headers:           40 (bytes)
  Number of section headers:         11
  Section header string table index: 10
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#使用 -W (--wide) 参数,每行显示完整信息,避免截断
readelf -SW rmpc
#输出
There are 35 section headers, starting at offset 0xff6bc0:

Section Headers:
  [Nr] Name              Type            Address          Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            0000000000000000 000000 000000 00      0   0  0
  [ 1] .note.gnu.build-id NOTE            0000000000000350 000350 000024 00   A  0   0  4
  [ 2] .init             PROGBITS        0000000000000374 000374 00001b 00  AX  0   0  4
  [ 3] .plt              PROGBITS        0000000000000390 000390 000040 10  AX  0   0 16
  [ 4] .text             PROGBITS        00000000000003d0 0003d0 9661a2 00  AX  0   0 16
  [ 5] .fini             PROGBITS        0000000000966574 966574 00000d 00  AX  0   0  4
  [ 6] .interp           PROGBITS        0000000000967000 967000 00001c 00   A  0   0  1
  [ 7] .gnu.hash         GNU_HASH        0000000000967020 967020 00001c 00   A  8   0  8
  [ 8] .dynsym           DYNSYM          0000000000967040 967040 000fa8 18   A  9   1  8
  [ 9] .dynstr           STRTAB          0000000000967fe8 967fe8 00091b 00   A  0   0  1
  [10] .gnu.version      VERSYM          0000000000968904 968904 00014e 02   A  8   0  2
  [11] .gnu.version_r    VERNEED         0000000000968a58 968a58 0001f0 00   A  9   4  8
  [12] .rela.dyn         RELA            0000000000968c48 968c48 091428 18   A  8   0  8
  [13] .rela.plt         RELA            00000000009fa070 9fa070 000048 18  AI  8  26  8
  [14] .rodata           PROGBITS        00000000009fa100 9fa100 12512c 00   A  0   0 128
  [15] .eh_frame_hdr     PROGBITS        0000000000b1f22c b1f22c 0212a4 00   A  0   0  4
  [16] .eh_frame         PROGBITS        0000000000b404d0 b404d0 0f3d94 00   A  0   0  8
  [17] .gcc_except_table PROGBITS        0000000000c34264 c34264 0562dc 00   A  0   0  4
  [18] .note.gnu.property NOTE            0000000000c8a540 c8a540 000020 00   A  0   0  8
  [19] .note.ABI-tag     NOTE            0000000000c8a560 c8a560 000020 00   A  0   0  4
  [20] .tdata            PROGBITS        0000000000c8ba10 c8aa10 000028 00 WAT  0   0  8
  [21] .tbss             NOBITS          0000000000c8ba38 c8aa38 000258 00 WAT  0   0  8
  [22] .init_array       INIT_ARRAY      0000000000c8ba38 c8aa38 000010 08 WAo  0   0  8
  [23] .fini_array       FINI_ARRAY      0000000000c8ba48 c8aa48 000008 08  WA  0   0  8
  [24] .data.rel.ro      PROGBITS        0000000000c8ba50 c8aa50 0709b8 00  WA  0   0  8
  [25] .dynamic          DYNAMIC         0000000000cfc408 cfb408 000220 10  WA  9   0  8
  [26] .got              PROGBITS        0000000000cfc628 cfb628 0039d8 08  WA  0   0  8
  [27] .data             PROGBITS        0000000000d00000 cff000 000ed8 00  WA  0   0  8
  [28] .bss              NOBITS          0000000000d00f00 cffed8 002410 00  WA  0   0 128
  [29] .comment          PROGBITS        0000000000000000 cffed8 00009f 01  MS  0   0  1
  [30] .annobin.notes    PROGBITS        0000000000000000 cfff77 0000f7 01  MS  0   0  1
  [31] .gnu.build.attributes NOTE            0000000000d05310 d00070 000144 00      0   0  4
  [32] .symtab           SYMTAB          0000000000000000 d001b8 0bf568 18     33 21048  8
  [33] .strtab           STRTAB          0000000000000000 dbf720 23733d 00      0   0  1
  [34] .shstrtab         STRTAB          0000000000000000 ff6a5d 00015e 00      0   0  1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
  L (link order), O (extra OS processing required), G (group), T (TLS),
  C (compressed), x (unknown), o (OS specific), E (exclude),
  D (mbind), l (large), p (processor specific)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

objdump

objdump -d 反汇编所有可执行的Section(通常是.text)

objdump -S 混合显示源代码和反汇编(要求编译时带-g调试信息)

objcopy

objcopy -O binary input.elf output.bin ELF文件转为纯二进制bin文件

#Linux
上次更新: 2026/06/06, 14:52:32
GNU⧸Linux文件系统层级结构

← GNU⧸Linux文件系统层级结构

最近更新
01
留学指南
05-31
02
日语等级考试
05-09
03
驾照
05-09
更多文章>
Theme by Vdoing | Copyright © 2025-2026 NCEPUwiki-Group | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式