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

ELF文件格式解析

ELF文件格式解析

文件类型与目标、段/节的运行时含义、DWARF/符号表的重要性、如何用 readelf / gdb 快速诊断、以及写作时的要点与截图/命令推荐。

TL;DR(快速结论)

  • 程序代码在 Flash(0x08000000); 数据和 BSS 在 RAM(0x2000xxxx)。
  • 大文件体积来自 DWARF(.debug_* 节);调试时保留 DWARF,发布时 strip。
  • 如果要用 core 恢复变量,core 必须包含 RAM 的 PT_LOAD(p_vaddr 对应 0x2000xxxx)。

在这里插入图片描述

在这里插入图片描述

为什么要关心 ELF 文件结构?

当你在嵌入式设备上遇到崩溃、要调试现场问题或从 core 恢复现场时,ELF(尤其是带符号的 AXF)决定了 GDB 能恢复多少信息:是否有源代码行号、变量名、内存映射是否能对应到运行时地址等。


1) 文件是什么

  • 格式:ELF32(小端)、Target = ARM。就是典型的 arm-none-eabi 链接产物。
  • 类型:EXEC(可执行镜像),常作为开发时的 AXF(带符号)使用。
  • 编译约定:e_flags 表明这是 EABI v5,使用软浮点约定——调试/反汇编时要匹配这些约定。

2) 段(Program Header)与节(Section)有什么不同?

  • 节(section)像是源码层面的“文件小片段”:.text, .data, .bss, .debug_* 等。
  • 段(segment / PT_LOAD)是运行时/加载器关心的单位:loader 把 PT_LOAD 映射到内存。
  • 简单说:节是链接器的世界,段是加载器和运行时的世界。

3) 运行时到底放哪儿?

  • ER_IROM1(Addr = 0x08000000)→ 在 Flash,放代码与只读常量,运行时直接从 Flash 执行或读取。
  • RW_IRAM1 PROGBITS(Addr = 0x20000000)→ 在 ELF 中存放已初始化的数据(Filesz > 0),启动时拷贝到 RAM 的 0x2000xxxx。
  • RW_IRAM1 NOBITS(Addr = 0x200000e4)→ BSS(Filesz = 0,但 memsize > 0),运行时占 RAM,启动时清零。

4) DWARF 和符号表

  • .debug_* 提供变量名、类型、函数到源码行的映射(就是 GDB 能显示源码和变量的原因)。
  • .symtab 提供符号地址与名字(函数/全局变量),用于回溯、地址转名字。
  • 体积问题:DWARF 很肥,会把 AXF 变大;发布镜像通常 strip 掉 DWARF,但保留一份带 DWARF 的 AXF 作为符号文件。

常见故障诊断工作流(实战步骤)

下面的步骤可以直接复制到 PowerShell(或类 Unix 终端):

  1. 快速看概要
readelf -h lora.axf     # ELF header
readelf -l lora.axf     # program headers (段)
readelf -S lora.axf     # section headers (节)
  1. 看符号/调试信息
readelf -s lora.axf     # 符号表
readelf --sections --wide lora.axf | Select-String "debug_" -Context 0,1  # 查 debug 节
  1. 用 gdb 加载 core(宿主机)
arm-none-eabi-gdb C:/path/to/lora.axf -c coredump.elf
# gdb: info files; bt full; info registers; x/i $pc; info variables
  1. 如果 gdb 看不到变量值,检查 core 是否包含 RAM 的 PT_LOAD
readelf -l coredump.elf | Select-String "PT_LOAD" -Context 0,2
# 注意查看每个 PT_LOAD 的 p_vaddr 是否落在 0x2000xxxx

解释:如果 core 没有将 RAM 段写入,那么即便 AXF 有符号表,GDB 也无法读取运行时变量的内存内容。

在这份 lora.axf 中,链接器把可执行代码放在名为 ER_IROM1 的节里,该节的运行时地址是 0x08000000(典型的 MCU Flash 起始地址)。初始化数据(.data)被放在 RW_IRAM1 PROGBITS,链接器在 ELF 中为它写入初始值;启动代码在上电后会把这些初始值从 Flash 拷贝到 RAM(0x2000xxxx)。未初始化的内存(.bss)以 NOBITS 形式存在,ELF 文件中没有占用空间,但运行时会在 RAM 中分配并清零。


http://www.dtcms.com/a/364163.html

相关文章:

  • 【代码随想录day 22】 力扣 131.分割回文串
  • 数据结构——树(03二叉树,与路径有关的问题,代码练习)
  • MySQL-表的约束(上)
  • 英伟达Jetson Orin NX-YOLOv8s目标检测模型耗时分析
  • 写论文先卡骨架再卡内容?一周出初稿爽翻!AI 帮我把骨架搭得明明白白,填内容超顺
  • 零样本视觉模型(DINOv3)
  • 从静态到智能:用函数式接口替代传统工具类
  • 作物改良中的综合生物技术与人工智能创新--文献精读160
  • github添加SSH密钥
  • 使用 Python 的 SymPy 进行符号计算
  • XMind2025(思维导图)下载安装教程
  • Linux 内核定时器实验
  • 2025年IT行业大学生证书选择指南
  • 机器学习:从技术原理到实践应用的深度解析
  • Steam开发者上架游戏完整指南(含具体技术细节)
  • 代码随想录---动态规划篇
  • 如何解决pip安装报错ModuleNotFoundError: No module named ‘black’问题
  • Java 大视界 --Java 大数据在智能教育学习资源整合与知识图谱构建中的深度应用(406)
  • 从Win10强制升级到Win11
  • 【数据结构探秘】手把手用单链表实现增删查改:一篇面向 C 程序员的实战指南
  • 【数通那些事】Vlan基础
  • 2025年- H109-Lc217--658. 找到 K 个最接近的元素(双指针+二分)--Java版
  • 当合规成为主旋律,PSP 如何推动链上消费市场迈向新蓝海?
  • 9月2日
  • Scikit-learn从入门到实践
  • Xcode 编译速度慢是什么原因?如何提高编译速度?
  • 英伟达Jetson Orin NX-YOLOv8n图像分类模型耗时分析
  • 《浪浪山小妖怪》知识竞赛来袭!测测你是几级影迷?
  • Java试题-选择题(29)
  • 天心:天下为公的君子之道