You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

readelf显示未初始化基础类型静态变量大小为0的原因及解决方法

问题:未初始化基础类型静态变量在readelf中Size显示为0的原因及解决方法

我使用TI CCS 12.3工具链生成ELF输出文件,希望通过readelf工具获取应用中所有全局变量与静态变量的名称、大小及地址信息。

测试代码

typedef struct
{
    uint32_t ui32;
    uint16_t ui16;
    uint8_t  ui8;
} T_TEST_STRUCT;

uint8_t Test_ui8_glob;
uint8_t Test_ui8_glob_init = 0;
static uint8_t Test_ui8_stat;
static uint8_t Test_ui8_stat_init = 0;

uint16_t Test_ui16_glob;
uint16_t Test_ui16_glob_init = 0;
static uint16_t Test_ui16_stat;
static uint16_t Test_ui16_stat_init = 0;

uint32_t Test_ui32_glob;
uint32_t Test_ui32_glob_init = 0;
static uint32_t Test_ui32_stat;
static uint32_t Test_ui32_stat_init = 0;

T_TEST_STRUCT Test_struct_glob;
T_TEST_STRUCT Test_struct_glob_init = { 0, 0, 0 };
static T_TEST_STRUCT Test_struct_stat;
static T_TEST_STRUCT Test_struct_stat_init = { 0, 0, 0 };

readelf输出结果(部分)

Num:    Value  Size Type    Bind   Vis      Ndx Name
...
    77: 2000fed8     0 OBJECT  LOCAL  HIDDEN    14 Test_ui8_stat
    78: 20010745     1 OBJECT  LOCAL  HIDDEN    13 Test_ui8_stat_init
    79: 2000feda     0 OBJECT  LOCAL  HIDDEN    14 Test_ui16_stat
    80: 20010748     2 OBJECT  LOCAL  HIDDEN    13 Test_ui16_stat_init
    81: 2000fedc     0 OBJECT  LOCAL  HIDDEN    14 Test_ui32_stat
    82: 20010750     4 OBJECT  LOCAL  HIDDEN    13 Test_ui32_stat_init
    83: 2001008c     8 OBJECT  LOCAL  HIDDEN    14 Test_struct_stat
    84: 20010838     8 OBJECT  LOCAL  HIDDEN    13 Test_struct_stat_init
...
 25329: 20010123     1 COMMON  GLOBAL HIDDEN    14 Test_ui8_glob
 25330: 2001011e     2 COMMON  GLOBAL HIDDEN    14 Test_ui16_glob
 25331: 200100cc     4 COMMON  GLOBAL HIDDEN    14 Test_ui32_glob
 25332: 200100ac     8 COMMON  GLOBAL HIDDEN    14 Test_struct_glob
...
 25334: 20010830     8 OBJECT  GLOBAL HIDDEN    13 Test_struct_glob_init
...
 25339: 20010744     1 OBJECT  GLOBAL HIDDEN    13 Test_ui8_glob_init
...
 25341: 20010746     2 OBJECT  GLOBAL HIDDEN    13 Test_ui16_glob_init
 25342: 2001074c     4 OBJECT  GLOBAL HIDDEN    13 Test_ui32_glob_init

可以看到,未初始化的基础类型静态变量Size显示为0,但未初始化的静态结构体变量及其他变量大小均正常。请问该现象的原因是什么,以及如何获取这些未初始化静态变量的正确大小?


原因分析

这是TI GCC编译器的优化行为导致的:

  • 对于未初始化的基础类型静态变量,编译器会将它们合并到.bss段(零初始化段)的连续空间中,为了节省符号表空间,不会在符号条目中单独记录每个变量的Size,而是依赖段的整体信息管理。
  • 结构体类型因存在内存对齐要求,编译器无法随意合并这类变量,因此会在符号表中保留其实际大小。
  • 从输出中的Ndx字段也能验证:这些Size为0的变量都指向14号段,也就是.bss段。

解决方法

1. 使用nm工具获取准确大小

运行以下命令,nm会从调试或类型信息中解析出变量的实际大小:

nm -S --size-sort mytest.out

该命令会按大小排序显示符号的地址、大小和名称,能正确展示所有变量的真实大小。

2. 禁用编译器的合并优化

在TI CCS的编译选项中添加-fno-common参数,强制编译器为每个未初始化的静态变量分配独立的符号条目并记录正确大小。不过此选项可能会轻微增加.bss段的占用空间,因为变量无法再被合并。

3. 通过段信息手动计算大小

运行readelf -S mytest.out获取.bss段的起始地址和总大小,再结合符号的Value(地址)字段,通过相邻同类型变量的地址差计算单个变量的大小。比如Test_ui8_stat地址为2000fed8,下一个静态变量Test_ui16_stat地址为2000feda,地址差为2,对应Test_ui8_stat的大小为1字节(因为Test_ui16_stat是uint16_t类型占2字节)。这种方法需要手动计算,适合临时验证。


内容的提问来源于stack exchange,提问作者Arjan Oskam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 19:59:52