首页
/ 理解mold链接器中的重复符号问题:以编译器内置函数为例

理解mold链接器中的重复符号问题:以编译器内置函数为例

2025-05-15 05:15:56作者:谭伦延

在软件开发过程中,链接器错误是开发者经常遇到的问题之一。本文将深入分析在使用mold链接器时遇到的重复符号问题,特别是涉及编译器内置函数的情况。

问题背景

在构建Android平台的Rust项目时,开发者遇到了mold链接器报出的重复符号错误。错误信息显示,两个不同的库文件中都定义了相同的符号,包括__divsi3__ashldi3__udivsi3__lshrdi3等编译器内置函数。

技术分析

符号冲突的本质

链接器在合并多个目标文件时,发现两个库文件中都包含了相同符号的定义:

  1. libclang_rt.builtins-arm-android.a中的目标文件
  2. Rust生成的librs.a中的编译器内置函数模块

这些符号都是编译器内置函数,用于处理基本的算术运算,如整数除法和位移操作。

符号强弱关系

深入分析发现,libclang_rt.builtins-arm-android.a中的divsi3.S.o文件包含了对__aeabi_idiv的弱定义(weak definition),而Rust生成的librs.a中的对应文件则包含了强定义(strong definition)。根据链接规则,链接器会优先选择强定义的符号。

问题根源

问题的复杂性在于,divsi3.S.o文件不仅包含__aeabi_idiv的定义,还包含了__divsi3的定义。当链接器选择Rust库中的强定义时,仍然需要从libclang_rt.builtins-arm-android.a中提取divsi3.S.o文件来解析其他符号,这就导致了__divsi3等符号的重复定义。

解决方案

临时解决方案

开发者可以使用链接器选项-Wl,-z,muldefs来允许重复定义,但这只是临时解决方案,不能从根本上解决问题。

根本解决方案

  1. 调整Rust构建配置:避免在Rust库中包含编译器内置函数。由于这是通过-Z build-std特性引入的,可能需要调整构建方式或等待Rust团队修复此问题。

  2. 修改编译器运行时库:确保libclang_rt.builtins-arm-android.a中的符号定义一致性,要么完全不包含某些符号,要么提供强定义。

链接器行为差异

值得注意的是,lld链接器能够处理这种情况而不会报错。这可能是由于不同链接器在处理弱符号和归档文件提取时的策略差异。mold采取了更严格的策略,更早地报告潜在问题。

最佳实践建议

  1. 避免在用户库中包含编译器内置函数
  2. 确保编译器运行时库的符号定义一致性
  3. 在遇到类似问题时,使用-Wl,-repro选项生成重现包以便分析
  4. 理解不同链接器的行为差异,根据项目需求选择合适的链接器

总结

这个案例展示了构建系统中微妙的交互问题,特别是当多个组件都试图提供相同功能时的冲突。理解符号的强弱定义、链接器如何处理归档文件以及不同工具链组件之间的交互,对于解决复杂的构建问题至关重要。开发者应当关注工具链组件的版本兼容性,并在设计库文件时避免包含本应由工具链提供的功能。

登录后查看全文
热门项目推荐
相关项目推荐

热门内容推荐

项目优选

收起
ohos_react_nativeohos_react_native
React Native鸿蒙化仓库
C++
176
261
RuoYi-Vue3RuoYi-Vue3
🎉 (RuoYi)官方仓库 基于SpringBoot,Spring Security,JWT,Vue3 & Vite、Element Plus 的前后端分离权限管理系统
Vue
860
511
ShopXO开源商城ShopXO开源商城
🔥🔥🔥ShopXO企业级免费开源商城系统,可视化DIY拖拽装修、包含PC、H5、多端小程序(微信+支付宝+百度+头条&抖音+QQ+快手)、APP、多仓库、多商户、多门店、IM客服、进销存,遵循MIT开源协议发布、基于ThinkPHP8框架研发
JavaScript
93
15
openGauss-serveropenGauss-server
openGauss kernel ~ openGauss is an open source relational database management system
C++
129
182
openHiTLSopenHiTLS
旨在打造算法先进、性能卓越、高效敏捷、安全可靠的密码套件,通过轻量级、可剪裁的软件技术架构满足各行业不同场景的多样化要求,让密码技术应用更简单,同时探索后量子等先进算法创新实践,构建密码前沿技术底座!
C
259
300
kernelkernel
deepin linux kernel
C
22
5
cherry-studiocherry-studio
🍒 Cherry Studio 是一款支持多个 LLM 提供商的桌面客户端
TypeScript
596
57
CangjieCommunityCangjieCommunity
为仓颉编程语言开发者打造活跃、开放、高质量的社区环境
Markdown
1.07 K
0
HarmonyOS-ExamplesHarmonyOS-Examples
本仓将收集和展示仓颉鸿蒙应用示例代码,欢迎大家投稿,在仓颉鸿蒙社区展现你的妙趣设计!
Cangjie
398
371
Cangjie-ExamplesCangjie-Examples
本仓将收集和展示高质量的仓颉示例代码,欢迎大家投稿,让全世界看到您的妙趣设计,也让更多人通过您的编码理解和喜爱仓颉语言。
Cangjie
332
1.08 K