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

含递归函数的.so库编译失败:R_X86_64_PC32重定位错误排查

解决共享库构建时的R_X86_64_PC32重定位错误(递归函数场景)

嘿,我之前在项目里也碰到过完全一样的问题!当时折腾了好一会儿才搞明白,尤其是手写汇编实现递归函数的时候,这个错误特别容易找上门。

先给直接解决方案

你看到的错误提示其实已经点出了核心修复方向:recompile with -fPIC。不过因为你是手写汇编代码,不是依赖C/C++编译器自动生成,所以得手动在汇编里处理位置无关的寻址逻辑。

对于x86_64架构的共享库,所有函数调用、内存引用都必须采用位置无关的方式——这是因为共享库会被加载到进程地址空间的任意位置,位置相关的代码会导致重定位失败。

为什么递归函数会触发这个错误?

你的原始汇编代码里,递归调用factorial时用的是直接符号引用/相对跳转,这种代码属于**位置相关(non-PIC)**类型。而共享库要求代码能在任意地址正常执行,必须用特殊的寻址方式(比如通过全局偏移表GOT)来间接引用函数地址,递归调用自然也得遵循这个规则。

修改后的PIC兼容汇编示例

把你的递归阶乘函数改成符合共享库要求的版本:

.section .text
.globl factorial
.type factorial, STT_FUNC

factorial:
    push %rbp
    mov %rsp, %rbp
    mov 16(%rbp), %rax
    cmp $1, %rax
    je end_factorial

    # 递归调用改为PIC兼容的寻址方式
    dec %rax
    push %rax
    call *factorial@GOTPCREL(%rip)  # 通过GOT间接引用函数地址
    pop %rdi
    imul 16(%rbp), %rax

end_factorial:
    pop %rbp
    ret

配套编译命令

编译这个汇编文件生成共享库时,记得加上-fPIC参数(汇编器和链接器都会用到):

as -fPIC -o factorial.o factorial.s
gcc -shared -o libfactorial.so factorial.o

简单解释下关键修改:factorial@GOTPCREL(%rip)是x86_64架构下PIC代码引用函数符号的标准写法,它通过指令指针%rip的相对偏移访问全局偏移表(GOT)中的函数地址,确保不管库被加载到哪个内存位置,都能正确找到递归函数的入口。

如果是用C写的递归函数,只需要编译时加-fPIC,编译器会自动处理这些细节,但手写汇编就得自己搞定这些寻址逻辑啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 11:25:28