This is unsafe - First of all, a function call has to be assumed to clobber all the call-clobbered registers, and the red-zone below RSP, so it's a huge pain to do it safely from GNU C inline asm. Calling printf in extended inline ASM shows a safe example that declares clobbers on all the relevant integer, mmx, x87, and xmm registers, and avoids the red-zone.
*%P0
makes GCC print *functionPointer
instead of *functionPointer(%rip)
, which can't link into a PIE executable because it's a 32-bit-sign-extended absolute addressing mode. 32-bit absolute addresses no longer allowed in x86-64 Linux?
Remember, you're doing a memory-indirect jump so you want a normal data addressing mode, not the bare symbol name. So you want just *%0
, exactly like if it might be a register so you could let GCC emit call *%rax
if it wanted to, for an "rm"
constraint.
https://godbolt.org/z/hWeexz8cf
%P
only makes sense when you want a direct call, like asm("call %P0" : : "i"(callee));
, e.g. call callee
not call *callee
.