如何确定交叉编译环境下基础数据类型字节数及ELF头大小?
交叉编译环境下基础类型字节数确定及ELF头结构体大小差异分析
一、不用sizeof确定交叉编译环境中基础类型的字节数
1. 利用预处理器输出宏定义
直接通过交叉编译工具的预处理器,输出系统预定义的类型大小宏,命令如下:
arm-none-eabi-gcc -E -dM -x c /dev/null | grep -E '(SIZEOF_INT|SIZEOF_LONG|SIZEOF_SHORT|INT_MAX|LONG_MAX|SHORT_MAX)'
执行后会直接得到类似#define SIZEOF_INT 4、#define SIZEOF_LONG 4的结果,清晰对应各类型的字节数。
2. 查看工具链头文件
交叉编译工具链的sysroot目录下,stdint.h或limits.h文件会明确标注类型的宽度。先通过以下命令找到sysroot路径:
arm-none-eabi-gcc -print-sysroot
然后进入该路径下的include目录,查看stdint.h,里面的typedef定义(如typedef unsigned int uint32_t)可以反推出对应基础类型的字节数。
3. 编写测试程序并反汇编
写一个简单的测试代码,比如:
int test_int; long test_long; short test_short;
用交叉编译工具生成汇编文件:
arm-none-eabi-gcc -S test.c -o test.s
查看生成的test.s,ARM汇编中.word对应4字节(int、long),.hword对应2字节(short),从变量的定义指令就能直接判断类型大小。
4. 参考工具链的ABI规范
arm-none-eabi工具链遵循ARM EABI规范,其中明确规定:
short为2字节int为4字节long为4字节(32位环境),64位环境下long为8字节
只要工具链是标准发行版,直接参考规范即可。
二、ELF头结构体大小与计算值不符的原因
你计算的Elf_Internal_Ehdr大小和实际ELF头52字节不符,大概率是以下两个原因:
- 结构体的条件编译差异:readelf源码中的
Elf_Internal_Ehdr会根据目标架构(32位/64位)通过宏定义(如ELFCLASS32/ELFCLASS64)切换结构体成员类型。比如64位环境下Elf_Addr、Elf_Off是8字节的long long,结构体总大小为64字节;而你的目标文件是32位ELF,对应的结构体成员是4字节类型,总大小为52字节。你可能误看了64位版本的结构体定义。 - 内存对齐的误解:ELF头的结构体是严格和文件二进制布局一一对应的,不存在额外的内存填充(因为要直接映射文件内容)。如果你的计算有误,可能是漏算、错算某个成员的类型,比如
e_flags是4字节的Elf_Word,而非2字节;或者把e_ident的长度(16字节)算错了。
内容的提问来源于stack exchange,提问作者jack wen
相关产品推荐
相关产品推荐

