You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

TI ARM Clang为何降级自定义入口点且丢弃汇编段?

ARM R5F裸机启动代码链接异常问题排查与解决

环境信息

  • 目标处理器:ARM R5F
  • IDE:德州仪器Code Composer Version 12.0
  • 编译器/链接器:TI ARM Clang 3.2.2
  • 操作系统:Windows 11

问题描述

为ARM R5F内核编写自定义裸机C运行时启动代码时,遇到以下链接器异常:

  1. 汇编文件定义的入口标签my_r5f_c_int00,通过链接器脚本--entry_point=my_r5f_c_int00指定入口点,却收到警告option -e demoted to -u for symbol my_r5f_c_int00;修改标签名会触发链接错误,说明链接器能识别该标签但将其降级为未定义符号。
  2. 汇编代码中定义的.my_r5f_vectors.my_r5f_startup段未出现在映射文件中,但段内标签my_reset_vectorsmy_r5f_c_int00却在映射文件里,且地址均为0(未解析符号的默认地址)。
  3. C代码定义的自定义段均可正常显示在映射文件的正确地址,仅汇编文件的段异常;通过tiarmobjdump.exe可确认my_startup.o目标文件包含正确的标签与汇编指令。

代码片段

汇编代码(my_startup.S)

//my_startup.S
.arch armv7-r
.code 32
.cpu  cortex-r5

.section .my_r5f_vectors, "x"
.align 2
.global my_reset_vectors
my_reset_vectors:
  b my_r5f_c_int00
.size my_reset_vectors, . - my_reset_vectors

.section .my_r5f_startup, "x"
.align 2
.global my_r5f_c_int00
my_r5f_c_int00:
//startup code is here
.size my_r5f_c_int00, . - my_r5f_c_int00

链接器脚本

--unused_section_elimination=on
--entry_point=my_r5f_c_int00 
--retain=my_startup.o(.my_r5f_vectors)
--retain=my_startup.o(.my_r5f_startup)
MEMORY{
   SRAM_VECTORS (RWX) : origin = 0x00000000, length = 0x0040
   SRAM         (RWX) : origin = 0x00000040, length = 0xFFC0
}
SECTIONS{
   .my_r5f_vectors : {my_startup.o(.my_r5f_vectors)} run = SRAM_VECTORS 
   .my_r5f_startup : {my_startup.o(.my_r5f_startup)} run = SRAM
   
   //other sections like .text, .stack, .bss, etc
   ...
}

问题分析与解决

核心原因

  1. 入口点降级:链接器无法找到my_r5f_c_int00的有效内存地址——其所在的.my_r5f_startup段被未使用段优化(--unused_section_elimination=on)移除,导致--entry_point指令无法生效,只能降级为-u强制符号为未定义。
  2. 汇编段消失--retain选项位置错误(放在了MEMORY/SECTIONS之后),TI链接器未优先处理保留指令,导致段被优化;同时run =仅指定运行地址未明确加载地址,段未被正确分配到内存区域。
  3. 标签地址为0:段被丢弃后,符号无对应内存地址,链接器默认将未解析符号地址设为0。
  4. C段正常:C段被代码直接引用,未被未使用段优化移除。

修复步骤

  1. 调整--retain位置:将--retain移到MEMORYSECTIONS块之前,确保链接器优先处理:
    --unused_section_elimination=on
    --retain=my_startup.o(.my_r5f_vectors)
    --retain=my_startup.o(.my_r5f_startup)
    --entry_point=my_r5f_c_int00 
    MEMORY{
       SRAM_VECTORS (RWX) : origin = 0x00000000, length = 0x0040
       SRAM         (RWX) : origin = 0x00000040, length = 0xFFC0
    }
    SECTIONS{
       .my_r5f_vectors : {my_startup.o(.my_r5f_vectors)} > SRAM_VECTORS 
       .my_r5f_startup : {my_startup.o(.my_r5f_startup)} > SRAM
       
       //other sections like .text, .stack, .bss, etc
       ...
    }
    
  2. 修改段内存分配语法:用>替代run =,同时指定加载与运行地址(裸机场景下两者一致),确保段被正确分配。
  3. 验证段属性:确认汇编中.section"x"(可执行)属性正确,ARM R5F要求向量表段具备可执行属性。

验证方法

  • tiarmobjdump.exe -x my_startup.o确认目标文件的段和符号存在;
  • 查看映射文件,确认.my_r5f_vectors.my_r5f_startup段已出现在指定地址,且my_r5f_c_int00地址非0。

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

火山引擎 最新活动