问题
I'm building a shared library with NASM. In that library, in some function, I need what we'd call a static variable in C. Basically, I think it is some space in the .data section:
SECTION .data
last_tok: dq 0 ; Define a QWORD
The problem arises when I try to access last_tok in my function.
I read the NASM Manual: 8.2 Writing Linux/ELF Shared Libraries which explains the problem and gives the solution.
SECTION .data
last_tok: dq 0 ; Define a QWORD
SECTION .text
EXTERN _GLOBAL_OFFSET_TABLE_
GLOBAL strtok:function
strtok:
enter 0, 0
push rbx
call .get_GOT
.get_GOT:
pop rbx
add rbx, _GLOBAL_OFFSET_TABLE_ + $$ - .get_GOT wrt ..gotpc
mov [rbx + last_tok wrt ..gotoff], rdi ; Store the contents of RDI at last_tok
mov rbx, [rbp - 8]
leave
ret
It may work with ELF32, but with ELF64 I get the following error:
nasm -f elf64 -o strtok.o strtok.s
strtok:15: error: ELF64 requires ..gotoff references to be qword
<builtin>: recipe for target 'strtok.o' failed
make: *** [strtok.o] Error 1
What am I doing wrong?
回答1:
The effective address format only allows for 32 bit displacement that is sign extended to 64 bit. According to the error message, you need full 64 bits. You can add it via a register, such as:
mov rax, last_tok wrt ..gotoff
mov [rbx + rax], rdi
Also, the call .get_GOT
is a 32 bit solution, in 64 bit mode you have rip relative addressing which you can use there. While the above may compile, but I am not sure it will work. Luckily the simple solution is to use the mentioned rip relative addressing to access your variable thus:
SECTION .data
GLOBAL last_tok
last_tok: dq 0 ; Define a QWORD
SECTION .text
GLOBAL strtok:function
strtok:
mov [rel last_tok wrt ..gotpc], rdi ; Store the contents of RDI at last_tok
ret
Note that for a private (static) variable you can just use [rel last_tok]
without having to mess with the got at all.
来源:https://stackoverflow.com/questions/36223182/access-data-section-in-position-independent-code