【问题标题】:Compiling GAS code doesn't detect -fPIC option编译 GAS 代码未检测到 -fPIC 选项
【发布时间】:2018-11-13 23:47:32
【问题描述】:

我正在尝试使用 GCC gnu 编译器为项目编译一些 GAS 代码。这是我的编译方式:

gcc -c boot.s -o boot.o -fPIC

使用-fPIC 参数编译我的kernel.c 文件后,我尝试将其与以下命令链接:

gcc -N -T linker.ld -o Slack\ Berry.bin -ffreestanding -nostdlib kernel.o boot.o -lgcc

它提出了:

/usr/bin/ld: boot.o: relocation R_X86_64_32 against '.multiboot' can not be used when making a PIE object; recompile with -fPIC

这让我认为它没有使用-fPIC 编译我的 GAS 代码。我该如何解决这个问题?

【问题讨论】:

    标签: gcc assembly gnu-assembler position-independent-code


    【解决方案1】:

    首先,您可能需要-fPIE 而不是-fPIC-fPIE 允许编译器生成更高效的代码,但只能用于作为主可执行文件一部分的代码(不是共享库)。

    现在-fPIC-fPIE 都是编译器专用标志,不会传递给汇编器。您需要在汇编代码中显式使用特定于 PIC 的助记符,而不是依赖位置的调用和分支,例如,而不是

    movq $bar, %rdx
    

    使用

    movq bar@GOTPCREL(%rip), %rdx
    

    (通常为了获得我需要的语法,我只需在匹配的 C sn-p 上运行 gcc -fPIE -S -o-)。

    【讨论】:

    • OP 正在制作 PIE,而不是共享库;他们不需要 GOT 或 PLT 用于内部静态符号。唯一需要的更改是lea bar(%rip), %rdx,一个与 RIP 相关的 LEA,而不是 mov $imm32, %r64。 (movabs 可以,但更大,通常更慢。)
    • @PeterCordes 谢谢,我会更新的。我认为这个问题也应该更新。
    • 为什么,您认为问题中缺少什么?它有-ffreestanding -nostdlib,并有类似boot.o 的名称,并提到了多重引导。错误消息还提到制作 PIE 可执行文件。对我来说似乎很清楚 OP 实际上并没有尝试创建共享库。 (从 asm 制作可执行文件时,这也不是关于此错误消息的第一个问题,所以我根本没想到这个问题是关于实际制作共享库的。通常它只是 PIE 需要可重定位的任何地方的代码来捕捉人们惊喜。)
    • @PeterCordes 好吧,如果可能的话,为什么不把事情说得更清楚些呢?
    • @PeterCordes 是的,我专门为此开发了ShlibVisibilityChecker。遗憾的是,我发现包维护者通常不太关心摆脱虚假的 GOT/PLT 引用......
    【解决方案2】:

    使用-fPIC 重新编译仅适用于 asm 由编译器生成而不是手工编写的情况。它对 asm 如何组装成机器码没有影响。

    问题是您的 PIE 可执行文件无法与 32 位绝对地址链接。 (您的意思是制作 PIE 而不是静态位置相关的可执行文件)?

    您不需要完整的共享库内容来引用另一个库或主可执行文件中的符号(如@yugr 的答案显示了如何做)。您的独立内核甚至可能没有 GOT 或 PLT,绝对不应该将它们用于内部符号。

    唯一需要更改的是lea bar(%rip), %rdx,一个与 RIP 相关的 LEA,而不是 mov $imm32, %r/m64。 (movabs 可以,但更大,通常更慢。)

    或者,如果您实际上打算使用-static 构建并创建一个可执行文件,该可执行文件将加载到地址空间的低 32 位中的固定地址,您应该使用mov $bar, %edx 来获得一个 5 字节的@987654327 @ 编码而不是 7 字节 mov $sign_extended_imm32, %r/m64 或 7 字节 LEA。另见Difference between movq and movabsq in x86-64

    【讨论】:

      猜你喜欢
      • 2013-12-26
      • 2014-06-07
      • 1970-01-01
      • 2019-04-16
      • 1970-01-01
      • 2017-04-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多