Hello Frank and everyone else,
OK, I promised more readable code and herein it follows. I have structured the problem by writing a simple calling program (callrel) that is linked dynamically to a called program (twerk).
The caller looks just like this:
extern twerk
extern dataquad
extern printf
SEGMENT .data
fmt db "The value in dataquad is %x",13,10,0
GLOBAL _start
SEGMENT .text
_start:
nop
call twerk wrt ..plt
lea rdi, [rel dataquad wrt ..gotpc]
mov rdi, [rdi] ; I would have thought a single dereference would do the job, but
mov rsi, [rdi] ; I was wrong! It takes yet another dereference to get to the value. Namely, 0x69
mov rdi, fmt
call printf
mov rax, 60
mov rdi, 0
syscal
And the shared library function (librel.so.1.0) looks like this:
extern printf
DEFAULT rel ;Following guidance from a swarm of different inet locations I use the default rel. But is it necessary to do this here? Why not just the caller?
SEGMENT .data
GLOBAL fmt
fmt db "%s",0
GLOBAL msg
msg db "Don't you dare twerk!",13,10,0
msglen equ $-msg
GLOBAL dataquad:data
dataquad dd 0x69
SEGMENT .text
GLOBAL twerk
twerk:
push rbp
mov rbp, rsp
lea rsi, [msg ]
; do the twerk-out with syscall
mov rdi, 1
mov rdx, msglen
mov rax, 1
syscall
; do twerk-out again with printf
mov rdi, msg
call printf wrt ..plt
mov rsp, rbp
pop rbp
ret
I have skipped including the assembly and link code for brevity.
Yes, the thing runs as intended, unlike my initial flawed posting. But, I'm still struggling to understand how this RIP thing works. As noted in the calling program, it appears that a double dereferencing of the global data item (dataquad--admittedly ill-chosen name) from the shared library is required, and I don't see why. Second question is: Do I need to use RIP addressing in the SHARED library--isn't it sufficient to do this just in the caller.
Can someone clariy what is going on here?
Ciao,
Mark Allyn