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

链接时出现Small data重定位错误,尝试读取栈内存

链接器报错:Small data relocation against an object not in a named small data section(符号__CPU_STACK)

我现在要实现一个从栈内存地址读取值的功能,通过引用链接脚本里定义的外部符号__CPU_STACK来获取栈地址,但编译构建时链接器抛出了这个错误,我对Small data相关知识不了解,查资料也没找到这个错误的明确定义。

代码片段

extern uint32 __CPU_STACK;

uint32* core1_stackHighAddress = (uint32*) __CPU_STACK;

boolean expected_value =  (PREDEFINED_VALUE == *(stack_lowAddress));

问题

  1. 这个错误到底是什么意思?
  2. 应该从哪些方面排查问题?
  3. 我猜测会不会是因为后台运行嵌入式OS,用户函数无权读取该内存地址?

错误含义解释

这个错误是链接器的小数据区(Small Data Section)机制导致的:

  • 很多嵌入式编译器(比如ARM系的RVCT、GCC的-mshort-data选项)会把小尺寸全局变量放到专门的小数据段(比如.sdata/.sbss),用短偏移寻址(比如16位偏移)提升访问效率。
  • 链接器检测到你试图用小数据段的寻址方式去访问__CPU_STACK这个符号,但该符号并不在任何标记为小数据的段里,因此抛出冲突错误。

排查方向

  • 检查链接脚本中__CPU_STACK的定义:确认这个符号是栈的起始/结束地址(通常是地址常量,不是变量),比如是不是用PROVIDE(__CPU_STACK = ORIGIN(STACK) + LENGTH(STACK));这类方式定义的。地址常量不能直接当作变量引用,得用指针形式声明。
  • 修正代码的符号引用方式:把extern uint32 __CPU_STACK;改成extern uint32 __CPU_STACK[];,直接取地址而非把符号值当作变量。正确写法示例:
    extern uint32 __CPU_STACK[];
    uint32* core1_stackHighAddress = (uint32*)__CPU_STACK;
    
    如果__CPU_STACK是栈起始地址常量,也可以写成:
    extern uint32 __CPU_STACK;
    uint32* core1_stackHighAddress = &__CPU_STACK;
    
  • 检查编译器/链接器的小数据相关选项:比如有没有开启-mshort-data、-msdata这类强制小数据段的选项,若不需要可尝试关闭;或者手动将__CPU_STACK归入小数据段(但栈地址通常是全局常量,不适合这么做)。
  • 关于嵌入式OS权限的猜测:这个错误是链接阶段的问题,和运行时权限无关——如果是权限问题,会在运行时触发内存访问错误(比如HardFault),不会在链接时报错,所以可以排除这个猜测。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 11:13:18