Generating position independent code with gas (-fP

2019-07-28 18:31发布

I try to create a shared library on x86-64 but fail. The problem boils down to the following code (please don't mind, that it does not make a lot of sense):

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

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

building as follows:

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

leads to the following error:

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

But gas doesn't know option -fPIC, so I cannot recompile with it:

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

What can be done instead?

1条回答
爷的心禁止访问
2楼-- · 2019-07-28 19:01

As Marc B said in the comments, the error message assumes you were using GCC or so some other compiler. Since you've written the code in assembly its your responsibility to ensure that your code is position independent.

On x86-64 targets you can resolve this error using RIP relative addressing:

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

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

Note that you don't need to use the GOT here because newline is a local symbol. If it were global, and you wanted the reference to newline in your code to able to refer to some other definition of newline in some other runtime component, then you would need to use an @GOTPCREL relocation. That would allow the dynamic linker to change the entry in the GOT to point to a different definition of newline.

查看更多
登录 后发表回答