Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

i128/u128 are not FFI safe #119

Closed
gnzlbg opened this issue Apr 15, 2019 · 8 comments
Closed

i128/u128 are not FFI safe #119

gnzlbg opened this issue Apr 15, 2019 · 8 comments
Labels
A-ffi Topic: Related to FFI A-layout Topic: Related to data structure layout (`#[repr]`) C-open-question Category: An open question that we should revisit

Comments

@gnzlbg
Copy link
Contributor

gnzlbg commented Apr 15, 2019

The layout of i128/u128 appears to currently be not fully specified due to: rust-lang/rust#54341 and these types are indeed not safe to use in Rust FFI.

We probably want to guarantee that their layout matches __int128 and similar C language extensions in the platforms that expose them, and to say that their alignment is "implementation-defined" in platforms that do not expose these, probably documenting what it is, at least on Tier-1 platforms like Windows msvc targets.

@gnzlbg gnzlbg added the A-layout Topic: Related to data structure layout (`#[repr]`) label Apr 15, 2019
@elichai
Copy link

elichai commented Aug 8, 2019

Would love to see a conversation around this :)
I think FFI is important to the rust ecosystem and having a primitive type that isn't FFI safe is pretty bad

@gnzlbg
Copy link
Contributor Author

gnzlbg commented Aug 9, 2019

This is blocked on resolving rust-lang/rust#54341 - it doesn't really matter what we specify here if we cannot implement it.

@RalfJung RalfJung added C-open-question Category: An open question that we should revisit A-ffi Topic: Related to FFI labels Aug 14, 2019
@RalfJung
Copy link
Member

Is there anywhere an official list of types that are FFI-safe? Would be nice to have something to point people to.

@gnzlbg
Copy link
Contributor Author

gnzlbg commented Sep 16, 2019

I don't think such a list exists (might want to look at the improper ctypes lint).

Also, instead of documenting types that are FFI safe (all types are safe for the "Rust" ABI), one should probably document for which types an ABI is well defined (e.g. the "C" ABI is only defined for certain types).

@Diggsey
Copy link

Diggsey commented Sep 16, 2019

all types are safe for the "Rust" ABI

Is that true? What if you pass ownership of a Box<T> in a situation like this:

Static Jemalloc        Static Jemalloc
       |                      |
    Foo.dll <------------> Bar.exe

The Rust ABI doesn't define what allocator to use, so passing ownership of heap allocated types across an ABI boundary is potentially unsafe, even if the ABI does define what the representation should be.

edit:
I know you could do the same thing with C pointers, but ownership is not encoded in the type of a raw pointer, and typically for C APIs you would never actually pass ownership in this way: the caller would be expected to tell the C library to free the pointer rather than trying to do so directly.

@gnzlbg
Copy link
Contributor Author

gnzlbg commented Sep 16, 2019

Is that true? What if you pass ownership of a Box in a situation like this:

Calling an extern declaration is unsafe. Being able to pass such a function arguments without invoking undefined behavior due to a mismatching calling convention is required but not sufficient for safety. There might be other requirements that you need to prove.

In your particular example, Bar.exe and Foo.dll communicate through extern "Rust" declarations, and you can pass a Box<T> to such a declaration without invoking UB. However, such a declaration might also require you to pass it a Box<T> that has been allocated with the same allocator that, e.g., the dll is using, because it intends to free it with that allocator, so you'd need to prove that as well.

@Lokathor
Copy link
Contributor

(a non-stable implementation detail of Rust on MSVC is that the global allocator is HeapAlloc, using the process heap, so as long as it's not cross-process you can pass allocations between an exe and a dll)

@JakobDegen
Copy link
Contributor

Closing. This is not a T-opsem question, it's mostly tracking a compiler bug

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-ffi Topic: Related to FFI A-layout Topic: Related to data structure layout (`#[repr]`) C-open-question Category: An open question that we should revisit
Projects
None yet
Development

No branches or pull requests

6 participants