I am compiling a NASM 64-bit shared object in Linux using the NASM compiler and linking with ld. It compiles to an object file using the following string:
sudo nasm -felf64 Test_File.asm
I link with ld:
sudo ld -shared Test_File.o -o Test_File.so
and I get the following errors:
Relocation R_X86_64_32S against '.data' can not be used when making a shared object; recompile with -fPIC
ld: final link failed: Nonrepresentable section on output
Unfortunately, the NASM compiler does not have a -fPIC option.
After reading many resources on writing position-independent code for 64-bit shared libraries in Linux, I understand the issue very well, but I still don't have a clear idea of what instruction changes I need to make to be position-independent in 64-bit NASM. For example, do all instructions involving named variables need to be "rel" -- for example, movsd xmm0,[rel abc] instead of movsd xmm0,[abc]? I know that R_X86_64_32S indicates 32-bit addressing, but I don't have any 32-bit addressing in my code.
Also, there are significant differences between 32-bit and 64-bit on how position independent code is written, and some of the resources concentrate only on 32-bit code. Even Section 9.2 Writing NetBSD/FreeBSD/OpenBSD and Linux/ELF Shared Libraries in the NASM manual is not clear on how 64-bit code must be altered for position-independent code. That section focuses on 32-bit code (using the global offset table), which is not (based on other research) used for 64-bit code.
The file is headed with [BITS 64] and [default rel], as required.
The data section is declared as section .data align=16
Every variable in the .data section is defined as dq, for example, number: dq 0.
The top of the file contains the exports in this format: global ABC:function.
I suspect that only data movement instructions would be affected -- math instructions would not. For the external calls to realloc, I added the wrt ..plt special symbol, but I still get the same errors.
Here are my questions:
Do all mov instructions need to be rewritten with the "rel" keyword, for example, mov rax,[rel abc] instead of mov rax,[abc]?
Do lea instructions need to be changed (e.g., lea rdi,[rel abc])?
Are there any other instruction types that need special handling?
I am not posting the entire (very long) nasm code listing here because I'm not looking for line-by-line analysis. I just want to know what instruction types (for example, mov, cmp, jmp, lea) need to be rewritten for 64-bit relative addressing, and how. Does it involve only accesses to variables defined in the data section (e.g., mov rcx,[abc] where abc is defined in the data section as abc: dq 0).
To summarize, my question is: what changes do I need to make for position-independent code for 64-bit NASM, since the NASM compiler does not have a fPIC option? I certainly don't mean line-by-line, but what types of instructions need to be added or rewritten.
Thanks very much.