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 终端):
- 快速看概要
readelf -h lora.axf # ELF header
readelf -l lora.axf # program headers (段)
readelf -S lora.axf # section headers (节)
- 看符号/调试信息
readelf -s lora.axf # 符号表
readelf --sections --wide lora.axf | Select-String "debug_" -Context 0,1 # 查 debug 节
- 用 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
- 如果 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 中分配并清零。