-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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
Rust BPF programs #2268
Comments
Update:Solana's Rust based BPF modules are built using a customized version of Rustc/LLVM and linked by a customized version of LLVM with a customized version of the sysroot (core libraries, etc...). Rustc: LLVM: Sysroot: All changes to these repos have been rebased and therefore will be the latest changes in the logs. All the necessary plumbing is in place to sync and build the Rust noop example. The Solana SDK downloads the Rust and LLVM toolchains as well as the source for the sysroot. The build script Overall most of Rust is supported support is still preliminary and shouild be made available for general consumption. In general:
It seems at every turn there are special cases that need to be worked around or behavior that does not quite work as expected so don't be surprised at this point if you encounter weird behavior. Please file an issue if you do. Rust BPF tests are located in Here is a sample command that will execute the Rust BPF program: $ ./programs/bpf/rust/noop/build.sh
$ cd programs/bpf
$ export RUST_LOG=solana_bpf_loader=info; cargo test --features="bpf_rust" -- --nocapture test_program_bpf_rust The following are updates of the notes mentioned in the original post:
Outstanding issues, issues filed
|
Rust BPF status now tracked by this github project |
Overview
This issue is a catch-all for now and intended to be both a guide, report of current challenges, and a forum for feedback and ideas, it should be broken up into smaller action items later.
Solana now contains an example BPF program written in Rust that prints out the parameters passed to it. The program is modeled after the BPF C program
noop
. It is preliminary, and a lot more work is required to get it fully functional.programs/bpf/rust/noop/...
The program must be built with the
makefile
and not viacargo build
. The Rust source files are compiled into LLVM IR by cargo and rustc. Linking into a.o
and then.so
are done by the custom Solana fork of LLVM (installed for you as part of running the makefile).Rust BPF programs are tested as part of the Solana integration tests and enabled with the cargo feature
bpf_rust
. Thesolana-bpf-rust-noop
crate must be built with themakefile
first before building Solana.Notes
Rust BPF programs require calling cargo with specific parameters not used when building Solana and therefore we cannot build this program at the same time as Solana. Doing so would result in recursive cargo deadlock, more notes on building specifics can be found in the makefile
The project contains two files:
src/lib.rs
which is the main program file that a Solana developer would modify when building their programsrc/solana_sdk.rs
which is modeled after the BPF C header filesolana_sdk.h
. It is not complete yet and should be moved to a common place in the tree.Only single source file BPF Rust programs supported at this time,
solana_sdk_rs
is being inlined by chance, not reliably, and should be a library that gets linked in. (Or could use something similar to macrostd::include
) Any additional dependent crates (byteorder, etc...) would also need to be linked in. The underlying BPF work to support object linking and multi-file projects is already on the docket for BPF C programs.The program does not rely on the Rust standard library since it must not have any local system dependencies, instead, it relies on Rust's core library. You can find a helpful walk-through of a freestanding binary here. Do note that in that blog they are creating a fully linked crate whereas we are stopping at the cargo compilation stage and then doing the linking ourselves to BPF. Any other dependent crates added must also support
no-std
. Here is a handy list of other crates that supportno-std
: https://crates.io/categories/no-stdThe limited usage of the Rust core library by this program is also being inlined by chance. Things like
core::str::from_utf8()
are not being inlined and require us to link the core lib into this program (or do it dynamically at runtime :-)).Using dependent crates will probably require that they are inlined or rebuilt into BPF libraries (will probably have to do this for the Rust core library right off the bat)
A good approach to building crates for BPF may be to define a new cargo target triple. That would be useful not only for this crate but any dependent crate that needs to rebuilt into BPF. One possible hangup is that rustc emits LLVM IR or bytecode and we would need a way to run both llc and lld, but it seems like a new cargo target can only define the linker (not both), more investigation is needed. A basic walk-through about creating a new target triple specification can be found here
It would be nice to depend directly on the Solana SDK for types like
Pubkey
andKeyedAccount
but the Solana SDK currently depends on the Rust standard library. For now, just like in BPF C,solana_sdk.rs
defines its own versions of those types.Panics are not supported yet. The panic type is set to
abort
when calling cargo so there won't be any unwinding but whenpanic!()
or.unwrap()
are used unresolved external references tocore::panicking::panic
and other Rust core library symbols are generated. To resolve this, the Rust core library must be linked in (see above). More information about Rust panicking can be found here. When support for library linking is added to Solana the following code clip added tolib/rs
should override the default panic handlerNo allocator is provided yet so things like Rust vectors are not supported. This program does use the
heapless
crate (also inlined by chance) which provide some basic facilities by using fixed sizes.Custom LLVM is required (installed for you). Customizations to LLVM are a work in progress. In some cases, the only changes were removing an error case that prevented certain behavior (passing and returning structs). After removing the error the behaviors seem to be working fine but more testing is required.
The cargo portion of the build uses
Release
mode becauseDebug
causes LLC to crash.Building in
Debug
mode also requires turning off incremental buildsCARGO_INCREMENTAL=0
, otherwise many.ll
files are produced, it's unknown yet why or which one to build into the.so
.Turning up the inline threshold generates relative BPF
call
instructions which are not supported yet. BPF missing support for 'call' instructions with a relative instruction offset #2260CARGO_FLAGS
in the makefile:-C inline-threshold=1
Cargo adds a nonce to the end of the generated files so it's difficult to know which file is the latest (could use timestamps. For now, we blow away all the respective
.ll
files then build and copy the one newly generated one.The generated
.ll
file is copied to the local output directory for easy finding.The text was updated successfully, but these errors were encountered: