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?
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:
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 tonewline
in your code to able to refer to some other definition ofnewline
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 ofnewline
.