apache / apache/nuttx

[HELP] FFI compatiblity issues

Open
#12,960 15 comments 3 reactions 1 assignee Claimed by @lupyuen View on GitHub
Community: Question
Dominant language
C
Stars
4k
Forks
1.7k
Avg merge
1d 17h
Merged PRs (30d)
237

Description

### Description

# Backgound

I'm porting Rust libstd to NuttX, and I've run into a problem with FFI.

Please check the early work in progress: https://github.com/apache/nuttx-apps/pull/2487

For Rust, the libstd is split into two parts: `libcore` and `libstd`.
The `libcore` is a minimal runtime that can be used on bare metal systems,
and it doesn't depend on any OS-specific functionality. The `libstd`,
on the other hand, depends on the OS-specific functionality, such as
threading, networking, etc.

`libstd` uses `libc` for FFI, and them usually shipped as static libraray.
And I've run into a problem with that.

# Problem

NuttX is highly configurable, the good part of it is that you can disable
anything you don't need, but the bad part is that you can't assume anything
about the system. For example, the size of complex types like `struct timespec`
can be different:

https://github.com/apache/nuttx/blob/f7adb52c8bafd3a242af4c80e27b64c534553ae5/include/time.h#L113-L117

The `time_t` type can be 32 or 64 bits, and the `struct timespec` can be
8 or 16 bytes. This is a problem for Rust, because it's hard to catch this at compile time.

And for libc, there are many complex types will be used in both Rust side and C side,
for current implmentation of `libc` crate, they defiend all of these types again with `#[repr(C)]`,
which means that they have the same layout as in C:

https://github.com/no1wudi/libc/blob/b395ec66982ae160dba1d7061c51311f32052633/src/unix/nuttx/mod.rs#L32-L56

Maybe for other OS, the data definitons are stable enough, but for NuttX, it's not.

For example, these data types are used in `libc` crate:

https://github.com/apache/nuttx/blob/f7adb52c8bafd3a242af4c80e27b64c534553ae5/include/pthread.h#L221-L243

It's hard to map `CONFIG_SCHED_SPORADIC` and `CONFIG_SMP` and mores one by one in Rust side, espcially in a cross-compiling environment.

And full list of data types used in `libc` crate can be found here:
https://github.com/no1wudi/libc/blob/libc-0.2/src/unix/nuttx/mod.rs

# Possible Solutions

## 1. Reserving space in Rust side for all possible data types

This is the most simple solution, but it's not very elegant. Many strucutres can be used as opaue data blobs in Rust side,
they don't need to be defined excatly same as in C side, just keepping the sizse of them is enough, for example:

https://github.com/no1wudi/libc/blob/b395ec66982ae160dba1d7061c51311f32052633/src/unix/nuttx/mod.rs#L79-L81

The drawback of this solution:
1. Waste memory space, especially for embedded systems.
2. Hard to maintain, if the data type is changed in C side, and exceeeding the reserved size, it will cause undefined behavior.

## 2. Mapping all possible conigurations in Rust side

The drawback of this solution:
1. It's hard to maintain the configs in both Rust and NuttX side, or other lanuages in the future.
2. The `libstd` and `libcore` must be build from source code each time.

## 3. Isolate the exported data types from NuttX

Do not use the libc data typs directly in NuttX intenral if any funtionality is conigurable, instead, define a new data type for it.

The drwa back of this solution:
1. It's a larage work to change all the exported data types from NuttX.

## 4. Let Rust runtime only avaliable with specific configurations

For example, add a special config like `CONFIG_RUST_RUNTIME` in NuttX, and let it depenends on all the configurations that Rust runtime needs and match the data types with `libc` crate:

```
config RUST_RUNTIME
bool "Enable Rust Runtime"
depends on !ARCH_FPU
depends on SYSTEM_TIME64
depends on ANYOTHER_ESSENTIAL_CONFIGS
```

# Discussion

I prefer the solution 4, but it's less flexible if you do not want to use full feaure of Rust libstd.

Any sugestions are welcome!

### Verification

- [X] I have verified before submitting the report.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.