【发布时间】:2018-08-28 14:02:33
【问题描述】:
在处理某个项目期间,我遇到了无法构建这样的库的问题。我得到了类似的错误:relocation R_X86_64_PC32 against symbol '' can not be used when making a shared object;用 -fPIC 重新编译 最终我设法找到了根本原因。它是库中的递归函数。例如,我有以下众所周知的例子:
.section .text
.globl factorial
.type factorial,STT_FUNC
factorial:
push %rbp
mov %rsp,%rbp
mov 16(%rbp),%rax
cmp $1,%rax
je end_factorial
dec %rax
push %rax #this is how we pass the argument to function
call factorial
pop %rbx
inc %rbx
imul %rbx,%rax
end_factorial:
mov %rbp, %rsp
pop %rbp
ret
现在,让我们尝试构建共享库:
as -g -o fact.o fact.s
ld -shared fact.o -o libfact.so
ld: fact.o: relocation R_X86_64_PC32 against symbol `factorial' can not be used when making a shared object; recompile with -fPIC
如果我包装阶乘函数,像这样:
.section .text
.globl fact
.type fact,STT_FUNC
fact:
factorial:
push %rbp
mov %rsp,%rbp
mov 16(%rbp),%rax
cmp $1,%rax
je end_factorial
dec %rax
push %rax #this is how we pass the argument to function
call factorial
pop %rbx
inc %rbx
imul %rbx,%rax
end_factorial:
mov %rbp, %rsp
pop %rbp
ret
我可以毫无错误地构建 so 库。
问题是:为什么在构建包含递归函数的共享库时会出错? 附:在这种情况下,静态链接可以正常工作。 谢谢!
【问题讨论】:
-
对于全局符号,您需要使用PLT或GOT,即
call factorial@PLT或call *factorial@GOTPCREL(%rip)。如果您愿意,当然可以反向进行包装,这样您就可以保留公共factorial符号并使用一些本地进行递归。
标签: assembly shared-libraries x86-64 gnu dynamic-linking