使用 gas (-fPIC) 生成位置无关代码

ead*_*ead 4 assembly gnu-assembler shared-libraries

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

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

.section .text
.globl write_newline
    .type write_newline, @function
write_newline: 
    mov  $newline, %rax    
    ret
Run Code Online (Sandbox Code Playgroud)

建筑如下:

as minimal.s -o minimal.o
ld -shared minimal.o -o libmin.so
Run Code Online (Sandbox Code Playgroud)

导致以下错误:

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
Run Code Online (Sandbox Code Playgroud)

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

as -fPIC minimal.s -o minimal.o
as: unrecognized option '-PIC'
Run Code Online (Sandbox Code Playgroud)

可以做些什么呢?

Ros*_*dge 6

正如 Marc B 在评论中所说,错误消息假定您使用的是 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
Run Code Online (Sandbox Code Playgroud)

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