tov / libffi-rs

Rust bindings for libffi
Apache License 2.0
105 stars 37 forks source link

Support function pointer type #57

Open ghost opened 2 years ago

ghost commented 2 years ago

Upstream issue: https://github.com/denoland/deno/issues/15292. Downstream issue: https://github.com/libffi/libffi/issues/725.

It seems that libffi-rs doesn't provide a function pointer type, but after further investigation, it seems that this is because the C libffi does not support this, so I have opened an issue there too; feel free to subscribe to the downstream issue.

Nonetheless, in the meanwhile, it does seem that libffi-rs misuses *const c_void as fn(), which can still be fixed here.

See https://rust-lang.github.io/unsafe-code-guidelines/layout/function-pointers.html and https://c-faq.com/ptrs/generic.html.

Rust claims that Rust's extern "ABI" fn(...) -> R has the same size/alignment/etc. as C's void (*)(), and that it may not necessarily map to C's void *.

Furthermore, Rust's fn documentation requests that code use fn primitives for FFI.

As a result, some present usage here is unsound (on some platforms), such as https://docs.rs/libffi/latest/libffi/low/struct.CodePtr.html.

yorickpeterse commented 2 years ago

@Phosra Out of curiosity, on what platforms would this be unsound?

ghost commented 2 years ago

@Phosra Out of curiosity, on what platforms would this be unsound?

Admittedly, such platform would likely be a Harvard architecture platform that doesn't implement POSIX - in practice... it's very unlikely to encounter such a platform, even less so for one with different sizes.

Although, it's possible to find maybe a Harvard embedded platform? How that could possibly affect FFI, I suppose it could be useful for interacting with native code after developing and running a new scripting language compiled as a bytecode, such as is done for JavaScript via XS, or Python via CircuitPython.

More realistically, although I cannot quite determine whether it's so, but a (future) CHERI Aarch64 Harvard, platform running an OS that doesn't implement POSIX could run into such an issue... still amusingly unlikely!

It's more of a "technical" issue. :)

markcsaving commented 1 year ago

@Phosra

You are correct that a function pointer cannot necessarily be converted to and from a void*. The C standard explicitly details when it is acceptable to convert between pointer types, and there is nothing saying a function pointer can be converted to and from void*. However, the documentation for the C libffi library, which this crate is a wrapper of, explicitly states that on any platform where closures are supported, you can convert certain void*s produced by the library into function pointers. See the manual here. If this is broken, it is a problem on the C library's side.