I want to generate following instructions. What C source will compile to this asm?
call *get_func@GOTPCREL(%rip)
cmpq func@GOTPCREL(%rip), %rax
I want to generate following instructions. What C source will compile to this asm?
call *get_func@GOTPCREL(%rip)
cmpq func@GOTPCREL(%rip), %rax
Looks like a call to get_func()
compiled with -fno-plt
, then comparing the return value against the address of another function.
I used void*
instead of declaring a function that returns a function pointer, because that's easier. This is a c question so everything can convert to / from void*
without casts.
void func();
void *get_func(void); // returns a function pointer
int foo(void) {
return func == get_func();
}
# gcc7.2 -O3 -fno-plt
subq $8, %rsp
# your lines verbatim in the compiler output
call *get_func@GOTPCREL(%rip)
cmpq func@GOTPCREL(%rip), %rax
sete %al
addq $8, %rsp
movzbl %al, %eax
ret
With or without a PLT, the function address will come from the GOT, but with the traditional -fplt
(which is still the default), the call
instruction will be a rel32
call to the PLT in this executable or shared object.
e.g. with just -fPIC
:
call get_func@PLT
cmpq func@GOTPCREL(%rip), %rax
or without either (for just a position-dependent executable, so the address of func
is a link-time constant):
call get_func # converted at link-time to a PLT call if it's in a shared lib
cmpq $func, %rax
Related: 32-bit absolute addresses no longer allowed in x86-64 Linux? Many distros make gcc enable -pie
/ -fPIE
by default.
clang is smarter, and xor-zeroes eax
before cmp, so there's no movzbl
on the critical path. But the call/cmp are basically the same.
clang doesn't have a no-PLT option.