使用ld.lld链接RISC-V ELF文件时遇__divdi3未定义符号错误求助
解决RISC-V链接时
__divdi3未定义错误 问题详情
链接RISC-V ELF文件时触发ld.lld错误:
ld.lld: error: undefined symbol: __divdi3
使用的编译/链接指令如下:
/usr/local/Cellar/llvm/15.0.6/bin/clang --target=riscv64 -march=rv64i -fno-builtin -nostdlib -ffreestanding -Wall -Wextra -Wwrite-strings -Wstrict-prototypes -pedantic -c -o build/main.o bios/main.c riscv64-unknown-elf-as -march=rv64i -o build/start.o src/start.S /usr/local/Cellar/llvm/15.0.6/bin/ld.lld -T link.ld -O2 -nostdlib --oformat=binary -o output.bin build/main.o build/start.o
当前使用的Clang库目录仅包含Darwin平台相关文件,缺少RISC-V架构所需的算术辅助函数库。
可行解决方案
1. 切换至完整RISC-V交叉编译工具链
当前Clang是Darwin发行版,未附带RISC-V运行时库。安装官方riscv64-unknown-elf-gcc交叉工具链,其自带libgcc.a,包含__divdi3这类辅助函数:
- 安装后,直接使用
riscv64-unknown-elf-ld作为链接器,或通过riscv64-unknown-elf-gcc作为链接前端,自动引入所需库。
2. 手动编译RISC-V版Compiler-RT库
若坚持使用现有Clang/ld.lld,需单独编译RISC-V架构的Compiler-RT:
- 从LLVM源码编译时,指定
--targets=RISCV参数,生成libclang_rt.builtins-riscv64.a - 链接时将该库加入指令:
/usr/local/Cellar/llvm/15.0.6/bin/ld.lld -T link.ld -O2 -nostdlib --oformat=binary -o output.bin build/main.o build/start.o /path/to/libclang_rt.builtins-riscv64.a
3. 手动实现__divdi3函数
RV64I指令集无硬件除法指令,可自行编写64位有符号除法的软件实现:
long long __divdi3(long long a, long long b) { const int sign = ((a < 0) ^ (b < 0)) ? -1 : 1; unsigned long long ua = a < 0 ? (unsigned long long)-a : (unsigned long long)a; unsigned long long ub = b < 0 ? (unsigned long long)-b : (unsigned long long)b; unsigned long long result = 0; for (int i = 63; i >= 0; --i) { if ((ua >> i) >= ub) { result |= 1ULL << i; ua -= ub << i; } } return (long long)(sign * result); }
将这段代码编译为目标文件后,添加到链接指令中即可。
4. 移除不必要的64位除法操作
检查代码中是否存在未必要的64位除法逻辑,若可删除则直接移除,避免对该辅助函数的依赖。
内容的提问来源于stack exchange,提问作者Cyao
相关产品推荐
相关产品推荐

