TI ARM Clang为何降级自定义入口点且丢弃汇编段?
ARM R5F裸机启动代码链接异常问题排查与解决
环境信息
- 目标处理器:ARM R5F
- IDE:德州仪器Code Composer Version 12.0
- 编译器/链接器:TI ARM Clang 3.2.2
- 操作系统:Windows 11
问题描述
为ARM R5F内核编写自定义裸机C运行时启动代码时,遇到以下链接器异常:
- 汇编文件定义的入口标签
my_r5f_c_int00,通过链接器脚本--entry_point=my_r5f_c_int00指定入口点,却收到警告option -e demoted to -u for symbol my_r5f_c_int00;修改标签名会触发链接错误,说明链接器能识别该标签但将其降级为未定义符号。 - 汇编代码中定义的
.my_r5f_vectors和.my_r5f_startup段未出现在映射文件中,但段内标签my_reset_vectors、my_r5f_c_int00却在映射文件里,且地址均为0(未解析符号的默认地址)。 - 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 ... }
问题分析与解决
核心原因
- 入口点降级:链接器无法找到
my_r5f_c_int00的有效内存地址——其所在的.my_r5f_startup段被未使用段优化(--unused_section_elimination=on)移除,导致--entry_point指令无法生效,只能降级为-u强制符号为未定义。 - 汇编段消失:
--retain选项位置错误(放在了MEMORY/SECTIONS之后),TI链接器未优先处理保留指令,导致段被优化;同时run =仅指定运行地址未明确加载地址,段未被正确分配到内存区域。 - 标签地址为0:段被丢弃后,符号无对应内存地址,链接器默认将未解析符号地址设为0。
- C段正常:C段被代码直接引用,未被未使用段优化移除。
修复步骤
- 调整
--retain位置:将--retain移到MEMORY和SECTIONS块之前,确保链接器优先处理:--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 ... } - 修改段内存分配语法:用
>替代run =,同时指定加载与运行地址(裸机场景下两者一致),确保段被正确分配。 - 验证段属性:确认汇编中
.section的"x"(可执行)属性正确,ARM R5F要求向量表段具备可执行属性。
验证方法
- 用
tiarmobjdump.exe -x my_startup.o确认目标文件的段和符号存在; - 查看映射文件,确认
.my_r5f_vectors和.my_r5f_startup段已出现在指定地址,且my_r5f_c_int00地址非0。
内容的提问来源于stack exchange,提问作者user4574




