You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

将两个32位汇编文件链接为32位动态库时遇重定位错误求解

问题描述

我在32位环境下工作,通过基于LLVM后端的自制编译器生成了两个32位.s汇编文件。尝试执行以下命令将它们链接为动态库时出现错误:

clang++ -m32 test1.s test2.s -shared -fPIC -o test.so

报错信息:

/usr/bin/ld: /tmp/test1-5ff028.o: relocation R_386_GOTOFF against undefined symbol `stdout@@GLIBC_2.0' can not be used when making a shared object
/usr/bin/ld: final link failed: bad value
clang: error: linker command failed with exit code 1 (use -v to see invocation)

这些.s文件是通过llc -march=x86 xxx.ll --relocation-model=pic生成的,且/usr/lib/i386-linux-gnu/libc.so.6中存在glibc2.0。另外,不加-shared参数执行clang++ -m32 test1.s test2.s -o test.out可正常生成可执行文件并运行。

开发环境:

OS: WSL2 Ubuntu22.04 x86_64
clang: 13
llvm: 13
gcc-multilib/g++-multilib: installed

我尝试添加-lc -lm -ldl -lstdc++等参数,但均未解决问题,请问该如何修复?


解决方案

1. 修正stdout的引用方式

R_386_GOTOFF重定位依赖符号的绝对偏移,不适用于加载地址可变的动态库。问题核心是汇编中对stdout的引用方式错误:

  • 32位glibc中stdout并非直接全局符号,而是__iob_func()返回的文件指针数组的第2个元素(索引1,每个元素占4字节)。手动修改.s文件中的引用逻辑:
    # 替换原有的GOTOFF引用代码:
    movl stdout@GOTOFF(%ebx), %eax
    # 改为间接调用__iob_func的方式:
    call __iob_func
    movl 4(%eax), %eax  # 取数组第2个元素(stdout)的地址
    

2. 调整LLC代码生成参数

除--relocation-model=pic外,添加32位动态库适配参数重新生成汇编:

llc -march=x86 xxx.ll --relocation-model=pic --code-model=small --enable-machine-outliner=false -o test.s
  • --code-model=small:确保生成适配32位小地址空间的代码
  • --enable-machine-outliner=false:禁用代码大纲化,避免触发异常重定位

3. 修改链接命令的库与链接器指定

显式指定32位动态链接器和库路径,强制clang使用正确的32位链接逻辑:

clang++ -m32 test1.s test2.s -shared -fPIC -o test.so -dynamic-linker /lib/ld-linux.so.2 -L/usr/lib/i386-linux-gnu -lc
  • -dynamic-linker /lib/ld-linux.so.2:指定32位glibc的动态链接器
  • -L/usr/lib/i386-linux-gnu:强制优先查找32位系统库

4. 检查自制编译器的IR生成逻辑

确保编译器生成的LLVM IR对stdout的引用符合动态库要求:

  • IR中需声明@stdout = external global i8*,并通过load i8*, i8** @stdout访问,而非硬编码绝对地址或偏移
  • 避免生成直接绑定到符号绝对位置的IR指令

5. 尝试用gcc替代clang链接

如果clang的链接逻辑存在兼容性问题,改用gcc链接:

gcc -m32 test1.s test2.s -shared -fPIC -o test.so

若gcc链接成功,可通过添加-v参数对比两者的链接命令细节,定位clang的参数传递问题。


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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 15:45:23