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.
