-1

I want to generate following instructions. What C source will compile to this asm?

call    *get_func@GOTPCREL(%rip)
cmpq    func@GOTPCREL(%rip), %rax
Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Akshay
  • 159
  • 1
  • 9

1 Answers1

1

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 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();
}

source + asm on Godbolt

    # 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.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
  • thanks a lot for your explanation but how to compile c file with -fno-plt option it is giving error that unrecognized command line option ‘-fno-plt’ – Akshay Nov 28 '17 at 07:08
  • @Akshay: What compiler are you using, on what OS? I was testing with gcc/clang targeting Linux, but OS X might be different. As I said, clang doesn't have a `-fno-plt` option (yet), but perhaps it generates code without a PLT on some targets. – Peter Cordes Nov 28 '17 at 07:09
  • I am using gcc 4.8.5 and linux os (cent os ) – Akshay Nov 28 '17 at 07:14
  • @Akshay: If you want it to emit code like that without a PLT, then yes. But why exactly do you want that? (However, using a gcc version that old is a bad idea in general, so I'd recommend gcc 6.4 or maybe even 7.2 if you're willing to upgrade.) I have no idea why you specifically want to reproduce that asm, or what problem you're trying to solve, but a more recent gcc is rarely a bad idea. – Peter Cordes Nov 28 '17 at 07:16
  • actually i have another compiler and I want to see what are the corresponding instructions in that compiler that is why I need to reproduce this asm with c code so I can see the corresponding behavior in another compiler – Akshay Nov 28 '17 at 07:20
  • 1
    @Akshay that's "housekeeping" or platform-implementation-specific piece of code, so it's sort of weird to compare it between different compilers/platforms, I don't see what kind of purpose that may have. Comparing the real "body" part of code, which is actually doing something, would make sense, but whatever the target compiler+platform is doing to emulate C abstract machine is sort of uninteresting, unless you are working on the C compiler itself or fixing some platform bug. And there's no generic C source to produce that asm, it will happen only on specific target+compiler+options. – Ped7g Nov 28 '17 at 11:39