Gcc 编写气体代码不需要';t检测-fPIC选项

Gcc 编写气体代码不需要';t检测-fPIC选项,gcc,assembly,gnu-assembler,position-independent-code,Gcc,Assembly,Gnu Assembler,Position Independent Code,我正在尝试使用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

我正在尝试使用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代码。如何解决此问题?

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

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

movq $bar, %rdx
使用


(通常要获得所需的语法,我只需在匹配的C代码段上运行
gcc-fPIE-S-o-

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

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

movq $bar, %rdx
使用


(通常,为了获得所需的语法,我只需在匹配的C代码段上运行
gcc-fPIE-S-o-

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

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

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

唯一需要的更改是
leabar(%rip),%rdx
,一个与rip相关的lea,而不是
mov$imm32,%r/m64
。(movab可以工作到,但更大,通常更慢。)


或者,如果您实际上打算使用
-static
构建并创建一个可执行文件,该文件将加载到地址空间低32位的固定地址,那么您应该使用
mov$bar,%edx
获得一个5字节
mov$imm32,%r32
编码,而不是7字节
mov$sign\u extended\u imm32,%r/m64
或7字节LEA。另请参见

使用
重新编译-fPIC
仅在asm由编译器生成而非手工编写时适用。它对asm如何组装成机器代码没有影响

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

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

唯一需要的更改是
leabar(%rip),%rdx
,一个与rip相关的lea,而不是
mov$imm32,%r/m64
。(movab可以工作到,但更大,通常更慢。)


或者,如果您实际上打算使用
-static
构建并创建一个可执行文件,该文件将加载到地址空间低32位的固定地址,那么您应该使用
mov$bar,%edx
获得一个5字节
mov$imm32,%r32
编码,而不是7字节
mov$sign\u extended\u imm32,%r/m64
或7字节LEA。另请参见

OP正在制作饼图,而不是共享库;内部静态符号不需要GOT或PLT。唯一需要的更改是
leabar(%rip),%rdx
,一个rip相对lea,而不是
mov$imm32,%r64
。(movabs可以工作,但会更大,通常会更慢。)@PeterCordes谢谢,我会更新的。我认为这个问题也应该更新。为什么,你认为这个问题缺少什么?它有
-ffreestanding-nostlib
,名称类似于
boot.o
,并提到多重引导。此外,错误消息还提到使饼图可执行。对我来说似乎很清楚,OP实际上并没有试图创建一个共享库。(在从asm生成可执行文件时,这也不是关于此错误消息的第一个问题,因此我根本不希望问题是关于实际生成共享LIB。通常情况下,这只是一个PIE,需要在任何地方重新定位代码,以便意外捕获用户。)@PeterCordes,如果可能的话,为什么不把事情说得更清楚呢?@PeterCordes是的,我是专门为此而设计的。可悲的是,我发现包维护人员通常不太关心去除虚假的GOT/PLT引用……OP是在做馅饼,而不是共享库;内部静态符号不需要GOT或PLT。唯一需要的更改是
leabar(%rip),%rdx
,一个rip相对lea,而不是
mov$imm32,%r64
。(movabs可以工作,但会更大,通常会更慢。)@PeterCordes谢谢,我会更新的。我认为这个问题也应该更新。为什么,你认为这个问题缺少什么?它有
-ffreestanding-nostlib
,名称类似于
boot.o
,并提到多重引导。此外,错误消息还提到使饼图可执行。对我来说似乎很清楚,OP实际上并没有试图创建一个共享库。(在从asm生成可执行文件时,这也不是关于此错误消息的第一个问题,所以我不是