【问题标题】:Generating position independent code with gas (-fPIC)使用气体生成与位置无关的代码 (-fPIC)
【发布时间】:2016-11-06 15:49:16
【问题描述】:

我尝试在 x86-64 上创建共享库但失败了。问题归结为以下代码(请不要介意,它没有多大意义):

.section .data
newline:
    .ascii "\n"

.section .text
.globl write_newline
    .type write_newline, @function
write_newline: 
    mov  $newline, %rax    
    ret

如下构建:

as minimal.s -o minimal.o
ld -shared minimal.o -o libmin.so

导致以下错误:

ld: minimal.o: relocation R_X86_64_32 against `.data' can not be used when making a shared object; recompile with -fPIC
minimal.o: error adding symbols: Bad value

但是gas不知道选项-fPIC,所以我不能用它重新编译:

as -fPIC minimal.s -o minimal.o
as: unrecognized option '-PIC'

可以做些什么呢?

【问题讨论】:

  • -fpic 将是编译器的一个选项,例如 gcc。如果你在写 asm,你必须自己写图片。
  • @MarcB 这怎么可能?我应该从哪里开始?
  • @ead 对于初学者,请写mov newline@GOTPCREL(%rip),%rax。检查您的 C 编译器生成的输出,以了解如何编写 PIC。

标签: assembly shared-libraries gnu-assembler


【解决方案1】:

正如 Marc B 在 cmets 中所说,错误消息假定您使用的是 GCC 或其他一些编译器。由于您已经在汇编中编写了代码,因此您有责任确保您的代码与位置无关。

在 x86-64 目标上,您可以使用 RIP 相对寻址解决此错误:

        .section .data
newline:
    .ascii "\n"

.section .text
.globl write_newline
    .type write_newline, @function
write_newline:
    lea  newline(%rip), %rax
    ret

请注意,这里不需要使用 GOT,因为 newline 是本地符号。如果它是全局的,并且您希望代码中对newline 的引用能够在其他运行时组件中引用newline 的其他定义,那么您将需要使用@GOTPCREL 重定位。这将允许动态链接器更改 GOT 中的条目以指向 newline 的不同定义。

【讨论】:

  • 谢谢,成功了!但是为什么不需要 @GOTPCREL 就像在 newline@GOTPCREL(%rip) 那样 gcc 会做和@FUZxxl 建议?
  • 好吧,GCC 不会为等效的 C 代码生成 @GOTPCREL。它将使用 LEA 指令和 RIP 相对寻址,因为 newline 不是全局的。如果它是全局的,则动态链接意味着其他模块中的其他全局 newline 定义优先,因此它将通过 GOT 访问它。
  • 你是对的,我的测试 C 代码有一个全局变量,但汇编代码是一个局部变量。很高兴问你。非常感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-11-27
  • 1970-01-01
  • 2015-09-28
  • 2011-07-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多