我们每天敲下 gcc hello.c -o hello,再执行 ./hello,这中间发生了什么?Linux 是怎么“看懂”这个程序的?答案,就藏在 ELF 里。一、ELF 是什么?
ELF(Executable and Linkable Format,可执行与可链接格式) 是 Linux / Unix 世界里最核心的一种二进制文件格式。
简单说:
ELF 是操作系统、编译器、链接器之间的“通用语言”。
只要是:
可执行程序(a.out、ls)
目标文件(.o)
动态库(.so)
几乎清一色都是 ELF。
ELF 主要解决了 3 件事:
程序怎么存(代码、数据、符号在哪)
程序怎么连(函数、变量如何被链接)
程序怎么跑(加载到内存后如何执行)
三、ELF 文件整体结构
ELF Header 在文件最前面,告诉系统:
这是不是 ELF?
32 位还是 64 位?
大端还是小端?
给 x86、ARM 还是 RISC-V 用?
程序入口地址在哪?
五、Program Header:给内核看的内存“地图”
执行 ./hello 时:
Shell 调用 execve()
内核读取 Program Header
按说明映射内存
典型映射:
.text:程序代码(CPU 执行的指令)
.data:已初始化的全局变量
.bss:未初始化的全局变量(不占文件空间)
.rodata:只读数据(字符串、常量)
.symtab:符号表(函数、变量名)
.strtab:字符串表
用 objdump 看反汇编
用 readelf 查段信息
用 nm 查符号
用 strip 精简固件
readelf -h a.out # 看 ELF Headerreadelf -S a.out # 看 Sectionreadelf -l a.out # 看 Program Headerobjdump -d a.out # 反汇编nm a.out # 查看符号表
在嵌入式和内核开发中:
ELF = 调试、裁剪、启动分析的基础工具箱
ELF 连接了编译、链接、加载、运行的全过程,是程序与操作系统对话的“通用语言”。