Skip to content

Instantly share code, notes, and snippets.

@dvanhorn
Last active January 25, 2021 22:17
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dvanhorn/670b8ea1a2346ea3675897accd99b85c to your computer and use it in GitHub Desktop.
Save dvanhorn/670b8ea1a2346ea3675897accd99b85c to your computer and use it in GitHub Desktop.
problem running indirect function call via ffi

Here's a transcipt of something very similar that seems to result in an infinite loop on Linux. :(

dvanhorn@starburst:small $ cat f.c
int f() {
  return 42;
}

int (*ptr_to_f)() = f;

dvanhorn@starburst:small $ cat try.s
	global main
	default rel
	section .text
	extern ptr_to_f
main:
	sub rsp, 8
	lea rax, [rel ptr_to_f wrt ..plt]
	call [rax]
	add rsp, 8
	ret
dvanhorn@starburst:small $ cat ffi-f.rkt
#lang racket
(require ffi/unsafe)

(define libf (ffi-lib "f.so"))

(define asm-main
  (get-ffi-obj "main" libf (_fun -> _int)))

(asm-main)
dvanhorn@starburst:small $ nasm -f elf64 try.s -o try.o
dvanhorn@starburst:small $ gcc -shared -fPIC f.c try.o -o f.so
dvanhorn@starburst:small $ racket ffi-f.rkt
Killed

Here's a transcript of successfully running this on Mac OS

☞  cat f.c
int f() {
  return 42;
}

int (*ptr_to_f)() = f;

☞  cat try.s
	global _main
	default rel
	section .text
	extern _ptr_to_f
_main:
	sub rsp, 8
	lea rax, [rel _ptr_to_f]
	call [rax]
	add rsp, 8
	ret
☞  cat ffi-f.rkt
#lang racket
(require ffi/unsafe)

(define libf (ffi-lib "f.so"))

(define asm-main
  (get-ffi-obj "main" libf (_fun -> _int)))

(asm-main)
☞  nasm -f macho64 try.s -o try.o
☞  gcc -shared -fPIC f.c try.o -o f.so
☞  racket ffi-f.rkt
42

just an added note: the assembly code seems fine for generating a static exectutable on Linux. Here's a transcript:

dvanhorn@starburst:small $ gcc -fPIC f.c try.o -o f
dvanhorn@starburst:small $ ./f
dvanhorn@starburst:small $ echo $?
42

Another data point, here's a slightly different program that calls f directly rather than the indirection through ptr_to_f that works.

dvanhorn@starburst:small $ cat try.s
	global main
	default rel
	section .text
	extern f
main:
	sub rsp, 8
	lea rax, [rel f wrt ..plt]
	call rax
	add rsp, 8
	ret
dvanhorn@starburst:small $ nasm -f elf64 try.s -o try.o
dvanhorn@starburst:small $ gcc -shared -fPIC f.c try.o -o f.so
dvanhorn@starburst:small $ racket ffi-f.rkt
42 
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment