readelf -h 可直接确认ELF文件的位数(Class: ELF32/ELF64)、字节序(Data: little/big endian)、目标架构(Machine)、ABI类型(OS/ABI)等关键架构信息,是诊断兼容性问题的首要命令。

readelf -h 查看ELF文件架构信息
直接用 readelf -h 能快速确认目标文件是 32 位还是 64 位、小端还是大端、ABI 版本、目标架构(如 EM_X86_64、EM_AARCH64)等关键元数据。
常见误判点:只看文件名或后缀(比如 libfoo.so)无法判断架构;交叉编译产物尤其容易混淆。必须依赖 readelf -h 输出里的 Class(ELF32/ELF64)、Data(2's complement, little endian)、Machine(如 Advanced Micro Devices X86-64)三行。
- 若输出中
Machine显示ARM但你预期是AARCH64,说明可能是 32 位 ARM 编译产物,需检查构建环境是否启用了-march=armv8-a或--target=aarch64-linux-gnu -
OS/ABI字段为UNIX - System V是常规情况;若为GNU/Linux,通常表示启用了 GNU 扩展(如.note.gnu.build-id),不影响运行但影响符号调试行为
readelf -S 列出所有节区及其属性
readelf -S 展示每个节区(section)的名称、地址、大小、标志(如 A 可分配、W 可写、X 可执行)、对齐等。这是分析二进制布局、定位代码/数据/只读段的核心命令。
关键注意:节区名不等于段(segment)——.text 属于 LOAD 段,但 .comment 或 .note 通常不加载到内存。混淆二者会导致误判内存映射行为。
- 检查代码是否被 strip:若
.text存在但.symtab和.strtab缺失,说明符号表已被移除;此时readelf -s会报错Section '.symtab' has no symbols -
.init_array和.fini_array的Flags应含A(可分配)且Type为SHT_INIT_ARRAY,否则全局构造函数可能不被执行 - 若发现
.data节有W但无A,说明该节未被链接器分配到可加载段中——大概率是链接脚本误配置或--gc-sections过度裁剪
如何结合 -h 和 -S 快速诊断兼容性问题
当程序在目标机器上提示 cannot execute binary file: Exec format error,本质是 ELF 头描述的架构与 CPU 不匹配。此时不能只看 file 命令输出,因为某些交叉工具链生成的文件可能有误导性 MIME 类型。
标准排查流程就是先 readelf -h 确认 Class + Machine,再用 readelf -S 看是否有异常节区(如 x86_64 二进制里出现 .ARM.attributes,说明混入了 ARM 目标代码)。
- 在 aarch64 机器上运行 x86_64 二进制时,
readelf -h的Machine显示Advanced Micro Devices X86-64,而系统uname -m返回aarch64—— 匹配失败原因一目了然 - 若
readelf -S中.dynamic节缺失或Size为 0,说明不是动态链接可执行文件,ldd将失效,需改用readelf -d查看动态段 - 某些嵌入式工具链会把
.text放到高位地址(如0x80000000),而标准 Linux 用户空间默认从0x400000开始映射——这时readelf -S的Addr列能暴露地址空间冲突风险
readelf 不是万能的:什么情况下它帮不上忙
readelf 只解析 ELF 文件结构,不模拟加载过程,也不验证指令合法性。它告诉你“这个节存在”,但不保证“这段代码能在当前 CPU 上跑”。
例如:一个标记为 EM_X86_64 的文件,若内部混用了 AVX-512 指令,readelf -h 完全不会报警;只有运行时报 Illegal instruction 才暴露问题。类似地,readelf -S 显示 .rodata 有 A 标志,但实际运行时是否真的只读,取决于内核 mmap 时传的 PROT_READ 参数和 MMU 配置。
真正关键的边界常藏在细节里:节区对齐值(Align 列)是否满足硬件要求(如 ARMv8 异常向量表强制 2KB 对齐)、.dynamic 中 DT_RUNPATH 路径是否存在、.interp 指定的解释器(如 /lib64/ld-linux-x86-64.so.2)是否适配当前 glibc 版本——这些都得配合 readelf -d 和手动验证,readelf -S 和 -h 只是起点。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











