ARC GNU工具链构建过程中链接器错误分析与解决方案
在构建ARCv3架构的原生工具链(包括arc32-native-uclibc和arc64-snps-native-gnu)时,开发人员遇到了一个典型的链接器错误问题。本文将深入分析该问题的技术背景、产生原因以及解决方案。
问题现象
在工具链构建过程中,链接阶段出现如下关键错误信息:
relocation truncated to fit: R_ARC_S25W_PCREL_PLT against symbol `__cxa_allocate_exception'
这表明链接器在处理位置无关代码(PIC)时,遇到了重定位截断问题——编译器生成的指令无法容纳目标地址的偏移量。
技术背景
-
重定位类型分析:
- R_ARC_S25W_PCREL_PLT是ARC架构特有的重定位类型,表示25位有符号偏移的PC相对PLT跳转
- 这种重定位方式用于支持位置无关的可执行文件(PIE)
-
优化级别影响:
- 在GCC 14版本中,编译器生成的代码体积显著增大
- 默认的-O1优化级别会导致函数间距离超出25位偏移量范围(±16MB)
-
工具链构建特点:
- 原生工具链需要构建完整的运行时库(如libstdc++.a)
- 异常处理机制会引入额外的跳转和符号引用
根本原因
该问题的核心在于:
- 代码体积膨胀导致函数间距离超出重定位范围
- ARC Classic架构的指令集限制(25位偏移)
- 构建脚本中使用了不合适的优化级别(-O1)
解决方案
经过技术分析,我们采取了以下改进措施:
-
优化级别调整:
- 将构建参数从-O1改为-Os(优化代码大小)
- 这种优化级别会:
- 减少生成的代码体积
- 确保函数间距离在重定位范围内
- 保持合理的性能表现
-
GCC补丁修正:
- 针对GCC 14版本中的特定bug提交了修复补丁
- 修正了异常处理相关的代码生成问题
实施效果
经过上述修改后:
- 工具链构建过程顺利完成
- 生成的原生编译器可以正确链接大型C++程序
- 保持了工具链的稳定性和兼容性
经验总结
在构建嵌入式架构的工具链时,需要特别注意:
- 目标架构的指令集限制(如偏移量范围)
- 不同GCC版本间的代码生成差异
- 优化级别对最终二进制的影响
- 原生工具链构建的特殊性(需要自举)
建议开发者在类似场景下:
- 优先考虑-Os优化级别
- 密切关注工具链组件的版本兼容性
- 建立完整的构建验证机制
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



