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 rcx, [rel last_tok wrt ..gotpc] ; load the address from the GOT
mov rax, [rcx] ; load the old dq value from there
; and/or
mov [rcx], rdi ; store arg at that address
ret
Note that for a private (static) variable you can just use [rel last_tok]
without having to mess with the got at all.
In a PIE executable, compilers use (the equivalent of) [rel symbol]
to access even global variables, on the assumption that the main executable doesn't need or want symbol interposition for its own symbols.
(Symbol interposition, or symbols defined in other shared libraries, is the only reason to load symbol addresses from the GOT on x86-64. But even something like mov rdx, [rel stdin]
is safe in a PIE executable: https://godbolt.org/z/eTf87e - the linker creates a definition of the variable in the executable so it's within range and at a link-time-constant offset for RIP-relative addressing.)
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…