Skip to content

Instantly share code, notes, and snippets.

@weliveindetail
Created October 22, 2024 08:05
Show Gist options
  • Save weliveindetail/c9884d5c783ec4ac218cab889a1d39e7 to your computer and use it in GitHub Desktop.
Save weliveindetail/c9884d5c783ec4ac218cab889a1d39e7 to your computer and use it in GitHub Desktop.

Call extern function pointer example:

➜ cat test.c
typedef int (fn_t)();
extern fn_t *fn;
int main() {
  return fn();
}

➜ cat fn.c
int f() { return 42; }
typedef int (fn_t)();
fn_t *fn = &f;

➜ clang test.c fn.c -o test
➜ ./test
➜ echo $?
42

Inspect machine code and assembly:

➜ clang -c test.c -o test.o
➜ llvm-objdump --disassemble --x86-asm-syntax=intel test.o

test.o: file format elf64-x86-64

Disassembly of section .text:

0000000000000000 <main>:
       0: 55                            push    rbp
       1: 48 89 e5                      mov     rbp, rsp
       4: 48 83 ec 10                   sub     rsp, 16
       8: c7 45 fc 00 00 00 00          mov     dword ptr [rbp - 4], 0
       f: 48 8b 0d 00 00 00 00          mov     rcx, qword ptr [rip]
      16: b0 00                         mov     al, 0
      18: ff 11                         call    qword ptr [rcx]
      1a: 48 83 c4 10                   add     rsp, 16
      1e: 5d                            pop     rbp
      1f: c3                            ret

Load-address of function pointer is resolved at link-time:

➜ llvm-objdump --disassemble --x86-asm-syntax=intel test | grep "48 8d 0d"
    113f: 48 8d 0d e2 2e 00 00          lea     rcx, [rip + 12002]      # 0x4028 <fn>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment