From 75d5bc80c24db60e3d1e535be45adae9e82bac9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Mei=C3=9Fner?= Date: Fri, 13 Dec 2024 18:38:06 +0100 Subject: [PATCH] Bump to v0.9.0 (#2) * Updates the README * Bump to v0.9.0 * Renames the crate. --- .github/workflows/main.yml | 2 +- Cargo.lock | 8 +++--- Cargo.toml | 6 ++-- README.md | 32 ++++++++++----------- benches/elf_loader.rs | 4 +-- benches/jit_compile.rs | 4 +-- benches/memory_mapping.rs | 4 +-- benches/vm_execution.rs | 8 +++--- cli/Cargo.lock | 14 ++++----- cli/Cargo.toml | 8 +++--- cli/src/main.rs | 2 +- examples/disassemble.rs | 4 +-- examples/to_json.rs | 4 +-- fuzz/Cargo.lock | 14 ++++----- fuzz/Cargo.toml | 6 ++-- fuzz/fuzz_targets/common.rs | 2 +- fuzz/fuzz_targets/dumb.rs | 2 +- fuzz/fuzz_targets/grammar_aware.rs | 2 +- fuzz/fuzz_targets/semantic_aware.rs | 2 +- fuzz/fuzz_targets/smart.rs | 2 +- fuzz/fuzz_targets/smart_jit_diff.rs | 2 +- fuzz/fuzz_targets/smarter_jit_diff.rs | 2 +- fuzz/fuzz_targets/verify_semantic_aware.rs | 2 +- misc/rbpf.ico | Bin 1150 -> 0 bytes misc/rbpf.png | Bin 29765 -> 0 bytes misc/rbpf_256.png | Bin 13059 -> 0 bytes src/assembler.rs | 2 +- src/ebpf.rs | 10 +++---- src/lib.rs | 6 +--- src/syscalls.rs | 2 +- src/vm.rs | 2 +- test_utils/Cargo.lock | 8 +++--- test_utils/Cargo.toml | 4 +-- test_utils/src/lib.rs | 8 +++--- tests/assembler.rs | 8 +++--- tests/disassembler.rs | 6 ++-- tests/elfs/elfs.sh | 2 +- tests/execution.rs | 6 ++-- tests/exercise_instructions.rs | 4 +-- tests/verifier.rs | 4 +-- 40 files changed, 101 insertions(+), 107 deletions(-) delete mode 100644 misc/rbpf.ico delete mode 100644 misc/rbpf.png delete mode 100644 misc/rbpf_256.png diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index adf5fecd..68562d26 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,4 +1,4 @@ -name: rbpf +name: sbpf on: push: diff --git a/Cargo.lock b/Cargo.lock index 8b9c8a77..b6adf25e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -346,8 +346,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] -name = "solana_rbpf" -version = "0.8.2" +name = "solana-sbpf" +version = "0.9.0" dependencies = [ "arbitrary", "byteorder 1.4.3", @@ -385,10 +385,10 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "test_utils" -version = "0.8.2" +version = "0.9.0" dependencies = [ "libc", - "solana_rbpf", + "solana-sbpf", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index f5537db5..cd0d1c84 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,9 +1,9 @@ [package] -name = "solana_rbpf" -version = "0.8.2" +name = "solana-sbpf" +version = "0.9.0" description = "Virtual machine and JIT compiler for eBPF programs" authors = ["Solana Maintainers "] -repository = "https://github.com/solana-labs/rbpf" +repository = "https://github.com/anza-xyz/sbpf" homepage = "https://solana.com/" keywords = ["BPF", "eBPF", "interpreter", "JIT", "filtering"] license = "Apache-2.0" diff --git a/README.md b/README.md index f1d9e63a..0b5ee51a 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,13 @@ -# solana_rbpf +# solana-sbpf -![](misc/rbpf_256.png) +SBPF virtual machine -Rust (user-space) virtual machine for eBPF - -[![Build Status](https://github.com/solana-labs/rbpf/actions/workflows/main.yml/badge.svg)](https://github.com/solana-labs/rbpf/actions/workflows/main.yml) -[![Crates.io](https://img.shields.io/crates/v/solana_rbpf.svg)](https://crates.io/crates/solana_rbpf) +[![Build Status](https://github.com/anza-xyz/sbpf/actions/workflows/main.yml/badge.svg)](https://github.com/anza-xyz/sbpf/actions/workflows/main.yml) +[![Crates.io](https://img.shields.io/crates/v/solana-sbpf.svg)](https://crates.io/crates/solana-sbpf) ## Description -This is a fork of [RBPF](https://github.com/qmonnet/rbpf) by Quentin Monnet. +This is a fork of [RBPF](https://github.com/solana-labs/rbpf) which in turn is a fork of [RBPF](https://github.com/qmonnet/rbpf) by Quentin Monnet. This crate contains a virtual machine for eBPF program execution. BPF, as in _Berkeley Packet Filter_, is an assembly-like language initially developed for @@ -26,13 +24,13 @@ although the JIT-compiler does not work with Windows at this time. ## Link to the crate -This crate is available from [crates.io](https://crates.io/crates/solana_rbpf), +This crate is available from [crates.io](https://crates.io/crates/solana-sbpf), so it should work out of the box by adding it as a dependency in your `Cargo.toml` file: ```toml [dependencies] -solana_rbpf = "0.8.2" +solana-sbpf = "0.9.0" ``` You can also use the development version from this GitHub repository. This @@ -40,7 +38,7 @@ should be as simple as putting this inside your `Cargo.toml`: ```toml [dependencies] -solana_rbpf = { git = "https://github.com/solana-labs/rbpf", branch = "main" } +solana-sbpf = { git = "https://github.com/anza-xyz/sbpf", branch = "main" } ``` Of course, if you prefer, you can clone it locally, possibly hack the crate, @@ -48,26 +46,26 @@ and then indicate the path of your local version in `Cargo.toml`: ```toml [dependencies] -solana_rbpf = { path = "path/to/solana_rbpf" } +solana-sbpf = { path = "path/to/sbpf" } ``` Then indicate in your source code that you want to use the crate: ```rust,ignore -extern crate solana_rbpf; +extern crate solana_sbpf; ``` ## API The API is pretty well documented inside the source code. You should also be able to access [an online version of the documentation from -here](https://docs.rs/solana_rbpf/), automatically generated from the -[crates.io](https://crates.io/crates/solana_rbpf) +here](https://docs.rs/solana-sbpf/), automatically generated from the +[crates.io](https://crates.io/crates/solana-sbpf) version (may not be up-to-date with master branch). [Examples](examples), [unit tests](tests) and [performance benchmarks](benches) should also prove helpful. -Here are the steps to follow to run an eBPF program with rbpf: +Here are the steps to follow to run an SBPF: 1. Create the config and a loader built-in program, add some functions. 2. Create an executable, either from the bytecode or an ELF. @@ -81,7 +79,7 @@ Here are the steps to follow to run an eBPF program with rbpf: ## Developer ### Dependencies -- rustc version 1.72 or higher +- rustc version 1.83 or higher ### Build and test instructions - To build run `cargo build` @@ -90,7 +88,7 @@ Here are the steps to follow to run an eBPF program with rbpf: ## License Following the effort of the Rust language project itself in order to ease -integration with other projects, the rbpf crate is distributed under the terms +integration with other projects, the sbpf crate is distributed under the terms of both the MIT license and the Apache License (Version 2.0). See [LICENSE-APACHE](LICENSE-APACHE) and [LICENSE-MIT](LICENSE-MIT) for details. diff --git a/benches/elf_loader.rs b/benches/elf_loader.rs index 656c794a..d64c0745 100644 --- a/benches/elf_loader.rs +++ b/benches/elf_loader.rs @@ -6,11 +6,11 @@ #![feature(test)] -extern crate solana_rbpf; +extern crate solana_sbpf; extern crate test; extern crate test_utils; -use solana_rbpf::{ +use solana_sbpf::{ elf::Executable, program::{BuiltinFunction, BuiltinProgram, FunctionRegistry}, syscalls, diff --git a/benches/jit_compile.rs b/benches/jit_compile.rs index cbc7a072..6c7f7b5b 100644 --- a/benches/jit_compile.rs +++ b/benches/jit_compile.rs @@ -6,10 +6,10 @@ #![feature(test)] -extern crate solana_rbpf; +extern crate solana_sbpf; extern crate test; -use solana_rbpf::{ +use solana_sbpf::{ elf::Executable, program::BuiltinProgram, verifier::RequisiteVerifier, vm::TestContextObject, }; use std::{fs::File, io::Read, sync::Arc}; diff --git a/benches/memory_mapping.rs b/benches/memory_mapping.rs index 91e77dee..a2074a96 100644 --- a/benches/memory_mapping.rs +++ b/benches/memory_mapping.rs @@ -7,11 +7,11 @@ #![feature(test)] extern crate rand; -extern crate solana_rbpf; +extern crate solana_sbpf; extern crate test; use rand::{rngs::SmallRng, Rng, SeedableRng}; -use solana_rbpf::{ +use solana_sbpf::{ memory_region::{ AccessType, AlignedMemoryMapping, MemoryRegion, MemoryState, UnalignedMemoryMapping, }, diff --git a/benches/vm_execution.rs b/benches/vm_execution.rs index d39b47c4..45c02690 100644 --- a/benches/vm_execution.rs +++ b/benches/vm_execution.rs @@ -6,17 +6,17 @@ #![feature(test)] -extern crate solana_rbpf; +extern crate solana_sbpf; extern crate test; #[cfg(all(feature = "jit", not(target_os = "windows"), target_arch = "x86_64"))] -use solana_rbpf::{ +use solana_sbpf::{ ebpf, memory_region::MemoryRegion, program::{FunctionRegistry, SBPFVersion}, vm::Config, }; -use solana_rbpf::{ +use solana_sbpf::{ elf::Executable, program::BuiltinProgram, verifier::RequisiteVerifier, vm::TestContextObject, }; use std::{fs::File, io::Read, sync::Arc}; @@ -83,7 +83,7 @@ fn bench_jit_vs_interpreter( instruction_meter: u64, mem: &mut [u8], ) { - let mut executable = solana_rbpf::assembler::assemble::( + let mut executable = solana_sbpf::assembler::assemble::( assembly, Arc::new(BuiltinProgram::new_loader( config, diff --git a/cli/Cargo.lock b/cli/Cargo.lock index 0caf8e1a..c1d74f53 100644 --- a/cli/Cargo.lock +++ b/cli/Cargo.lock @@ -301,11 +301,11 @@ dependencies = [ ] [[package]] -name = "rbpf_cli" -version = "0.8.2" +name = "sbpf_cli" +version = "0.9.0" dependencies = [ "clap", - "solana_rbpf", + "solana-sbpf", "test_utils", ] @@ -322,8 +322,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04c565b551bafbef4157586fa379538366e4385d42082f255bfd96e4fe8519da" [[package]] -name = "solana_rbpf" -version = "0.8.2" +name = "solana-sbpf" +version = "0.9.0" dependencies = [ "byteorder", "combine", @@ -366,10 +366,10 @@ dependencies = [ [[package]] name = "test_utils" -version = "0.8.2" +version = "0.9.0" dependencies = [ "libc", - "solana_rbpf", + "solana-sbpf", ] [[package]] diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 6aa44a7d..1146356c 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -1,14 +1,14 @@ [package] -name = "rbpf_cli" -version = "0.8.2" +name = "sbpf_cli" +version = "0.9.0" description = "CLI to test and analyze eBPF programs" authors = ["Solana Maintainers "] -repository = "https://github.com/solana-labs/rbpf" +repository = "https://github.com/anza-xyz/sbpf" homepage = "https://solana.com/" keywords = ["BPF", "eBPF", "interpreter", "JIT"] edition = "2018" [dependencies] -solana_rbpf = { path = "../", features = ["debugger"] } +solana-sbpf = { path = "../", features = ["debugger"] } test_utils = { path = "../test_utils/" } clap = "3.0.0-beta.2" diff --git a/cli/src/main.rs b/cli/src/main.rs index cded744a..5c3d344b 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -1,5 +1,5 @@ use clap::{crate_version, App, Arg}; -use solana_rbpf::{ +use solana_sbpf::{ aligned_memory::AlignedMemory, assembler::assemble, ebpf, diff --git a/examples/disassemble.rs b/examples/disassemble.rs index d668cbaf..50b45fec 100644 --- a/examples/disassemble.rs +++ b/examples/disassemble.rs @@ -4,8 +4,8 @@ // the MIT license , at your option. This file may not be // copied, modified, or distributed except according to those terms. -extern crate solana_rbpf; -use solana_rbpf::{ +extern crate solana_sbpf; +use solana_sbpf::{ elf::Executable, program::{BuiltinProgram, FunctionRegistry, SBPFVersion}, static_analysis::Analysis, diff --git a/examples/to_json.rs b/examples/to_json.rs index cb6b1e2e..068c5edf 100644 --- a/examples/to_json.rs +++ b/examples/to_json.rs @@ -10,8 +10,8 @@ extern crate json; extern crate elf; use std::path::PathBuf; -extern crate solana_rbpf; -use solana_rbpf::{ +extern crate solana_sbpf; +use solana_sbpf::{ elf::Executable, program::{BuiltinProgram, FunctionRegistry, SBPFVersion}, static_analysis::Analysis, diff --git a/fuzz/Cargo.lock b/fuzz/Cargo.lock index 287092d4..0116e06f 100644 --- a/fuzz/Cargo.lock +++ b/fuzz/Cargo.lock @@ -315,8 +315,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04c565b551bafbef4157586fa379538366e4385d42082f255bfd96e4fe8519da" [[package]] -name = "solana_rbpf" -version = "0.8.2" +name = "solana-sbpf" +version = "0.9.0" dependencies = [ "arbitrary", "byteorder", @@ -332,14 +332,14 @@ dependencies = [ ] [[package]] -name = "solana_rbpf-fuzz" -version = "0.8.2" +name = "solana-sbpf-fuzz" +version = "0.9.0" dependencies = [ "arbitrary", "libfuzzer-sys", "num-traits", "rayon", - "solana_rbpf", + "solana-sbpf", "test_utils", ] @@ -356,10 +356,10 @@ dependencies = [ [[package]] name = "test_utils" -version = "0.8.2" +version = "0.9.0" dependencies = [ "libc", - "solana_rbpf", + "solana-sbpf", ] [[package]] diff --git a/fuzz/Cargo.toml b/fuzz/Cargo.toml index c16abfa7..03a1b71f 100644 --- a/fuzz/Cargo.toml +++ b/fuzz/Cargo.toml @@ -1,6 +1,6 @@ [package] -name = "solana_rbpf-fuzz" -version = "0.8.2" +name = "solana-sbpf-fuzz" +version = "0.9.0" authors = ["Automatically generated"] publish = false edition = "2018" @@ -15,7 +15,7 @@ num-traits = "0.2" rayon = "1.5" test_utils = { path = "../test_utils/" } -[dependencies.solana_rbpf] +[dependencies.solana-sbpf] path = ".." features = ["fuzzer-not-safe-for-production"] diff --git a/fuzz/fuzz_targets/common.rs b/fuzz/fuzz_targets/common.rs index 17e8d0c7..0caa9bef 100644 --- a/fuzz/fuzz_targets/common.rs +++ b/fuzz/fuzz_targets/common.rs @@ -2,7 +2,7 @@ use std::mem::size_of; use arbitrary::{Arbitrary, Unstructured}; -use solana_rbpf::vm::Config; +use solana_sbpf::vm::Config; #[derive(Debug)] pub struct ConfigTemplate { diff --git a/fuzz/fuzz_targets/dumb.rs b/fuzz/fuzz_targets/dumb.rs index ee624f5b..d0c8fc0c 100644 --- a/fuzz/fuzz_targets/dumb.rs +++ b/fuzz/fuzz_targets/dumb.rs @@ -4,7 +4,7 @@ use std::hint::black_box; use libfuzzer_sys::fuzz_target; -use solana_rbpf::{ +use solana_sbpf::{ ebpf, elf::Executable, memory_region::MemoryRegion, diff --git a/fuzz/fuzz_targets/grammar_aware.rs b/fuzz/fuzz_targets/grammar_aware.rs index b5b19f2e..69e557fa 100644 --- a/fuzz/fuzz_targets/grammar_aware.rs +++ b/fuzz/fuzz_targets/grammar_aware.rs @@ -1,6 +1,6 @@ #![allow(dead_code)] -use solana_rbpf::insn_builder::{Arch, BpfCode, Cond, Endian, Instruction, MemSize, Source}; +use solana_sbpf::insn_builder::{Arch, BpfCode, Cond, Endian, Instruction, MemSize, Source}; #[derive(arbitrary::Arbitrary, Debug, Eq, PartialEq)] pub enum FuzzedOp { diff --git a/fuzz/fuzz_targets/semantic_aware.rs b/fuzz/fuzz_targets/semantic_aware.rs index 6e1a066f..28bd752a 100644 --- a/fuzz/fuzz_targets/semantic_aware.rs +++ b/fuzz/fuzz_targets/semantic_aware.rs @@ -3,7 +3,7 @@ use std::num::NonZeroI32; -use solana_rbpf::insn_builder::{Arch, BpfCode, Cond, Endian, Instruction, MemSize, Move, Source}; +use solana_sbpf::insn_builder::{Arch, BpfCode, Cond, Endian, Instruction, MemSize, Move, Source}; #[derive(arbitrary::Arbitrary, Debug, Eq, PartialEq, Copy, Clone)] pub struct Register(u8); diff --git a/fuzz/fuzz_targets/smart.rs b/fuzz/fuzz_targets/smart.rs index 9232b0d3..e003ceff 100644 --- a/fuzz/fuzz_targets/smart.rs +++ b/fuzz/fuzz_targets/smart.rs @@ -5,7 +5,7 @@ use std::hint::black_box; use libfuzzer_sys::fuzz_target; use grammar_aware::*; -use solana_rbpf::{ +use solana_sbpf::{ ebpf, elf::Executable, insn_builder::{Arch, IntoBytes}, diff --git a/fuzz/fuzz_targets/smart_jit_diff.rs b/fuzz/fuzz_targets/smart_jit_diff.rs index b77ab691..0bfb637f 100644 --- a/fuzz/fuzz_targets/smart_jit_diff.rs +++ b/fuzz/fuzz_targets/smart_jit_diff.rs @@ -3,7 +3,7 @@ use libfuzzer_sys::fuzz_target; use grammar_aware::*; -use solana_rbpf::{ +use solana_sbpf::{ ebpf, elf::Executable, insn_builder::{Arch, Instruction, IntoBytes}, diff --git a/fuzz/fuzz_targets/smarter_jit_diff.rs b/fuzz/fuzz_targets/smarter_jit_diff.rs index ebfa6e04..e1774b4f 100644 --- a/fuzz/fuzz_targets/smarter_jit_diff.rs +++ b/fuzz/fuzz_targets/smarter_jit_diff.rs @@ -3,7 +3,7 @@ use libfuzzer_sys::fuzz_target; use semantic_aware::*; -use solana_rbpf::{ +use solana_sbpf::{ ebpf, elf::Executable, insn_builder::IntoBytes, diff --git a/fuzz/fuzz_targets/verify_semantic_aware.rs b/fuzz/fuzz_targets/verify_semantic_aware.rs index 68c7d4b1..68e6fecb 100644 --- a/fuzz/fuzz_targets/verify_semantic_aware.rs +++ b/fuzz/fuzz_targets/verify_semantic_aware.rs @@ -3,7 +3,7 @@ use libfuzzer_sys::fuzz_target; use semantic_aware::*; -use solana_rbpf::{ +use solana_sbpf::{ insn_builder::IntoBytes, program::{BuiltinFunction, FunctionRegistry, SBPFVersion}, verifier::{RequisiteVerifier, Verifier}, diff --git a/misc/rbpf.ico b/misc/rbpf.ico deleted file mode 100644 index 6bb94a1c3e0bdeb109a02dba7cb51b05abd2fb7c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1150 zcmeIuu`feW6vy#X70;yYVr%+DlU6NV`~_n02Ur?|upkBon~;z;5rf4b5eyQe0RuxD zWvMh_>p+@Vni%^ZwBH{t*JiIapPqZ)Ip_A=XBOcbj~lqW8!vE(F zZy=Q#P2vuZnDJZK8%|Nf4F;7bev}dW@QRI0W_*@-fuuWw^)kv~n9dW&aNu%^>~lEA zGa4wN;A&W};uejs`XcKDG}9G!&_o@olWl0$dmN#KOO$bjLp)&;FQ`C0d(gSM&n7cR zi2K-r=2FcF&Y^i9uz;#J?>hTw=s%TT!H}2Nop+&rou@mjdHD(U@6g=WI6(kcqW&1% qtV^t;-$@qir=UJb!%z48y3;Z9wcBQIbC~~mH3NZ}1hL<>>gxh+sB6an diff --git a/misc/rbpf.png b/misc/rbpf.png deleted file mode 100644 index b3f07c4bd6e709af8033c371de2817d7da67b25e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29765 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

Oz5%vp^Sd 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 diff --git a/misc/rbpf_256.png b/misc/rbpf_256.png deleted file mode 100644 index b8ae83498d1be593b8b47bae090759dd80cec7be..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13059 zcmV+eGyKenP)3qMjx-QD;5W6ot~Z{B_H-nZ{<_U*p&`Rr$RZ<#wYXXec5 z2Raz6G12cetTAH}?wx0iS!|8jHo6|%%UNSKw8jhy->F0AfB;X8imUkjoHgcDYs|q3 z@Ar;yTZigH!wUTNi@@vFn4_YF<3zB=Yyg}B^Z{-Ia3VO7=)D_&SAl!#=<9r-INS$# z8Th&W9}?;_fD3?|tuecWgu@!s2e=b>%o?*!ow(O10SHckm8>zVgx7UJd=*#&=m}hH zjoB*L;MW7a^zYTJG1mm|UjQ7c|88fE867P!z29JsS=}1bw~pElIpzBlxYq#u5HP?w z)|lfX0c;$Mg*HFHR={JxbHV0E|E?>ND#Yq1 zu-qYjzYM&s9Ne!Hn(JNUQ%URLCTq;)z+1uQ2iUgQI;=x_XxBzm)@&ef2XLDc`BT82 zZCv1$;VGML0`e*zlp<1JC~&P&3BZTem>e(w_!Tf1__h;isiQtM5m*ga!->2cyR}K| z|22T0q-?fDxzAD@=s5j}!?wUh!RBwU#*7DEaUx6VSnF6Fz{$X_z;)J`4}o7PGIlPr zy?cORPNcVT4dp;z-~emPmw-P3p8_WVhZWE<)FByq01p6@tua%qG2gew47SGf0M;+F z&C7tDRDbi|GTZo4AZDHqybnCDZP%eAbpY0wpU_sR7g6|fiOV1-vLI;xH+ZdbR>w6&3*flt@MJ4=1vJ z9djMa0W7FwyV2$kh{Ccu+A|T+#j$Js%iR1Zi{298cV>b1)55^m<_DNx zM_H8!KoLbtdnf(*kce1gejDf)2H_n?!e`%W=Yn3EaeUq3q%ZdW(h7bmV%;M>(fX>N zsT9-+Ks7}GYs^c)D7@zV5xlq8(ZC@YnwbVX4gB4S+^g-biZ>0eqt8qP9Pmx0^ZHW1?D-Crl9RU!0UQ=M4VVS|0g?tR8p1NVEB02KIC!n>&%0fX`wwfAo6>uuTD( z{|YB^mLfNPwo||!8H`SK{4`h74 zS=sFgPUPB{Y`+|SRQb09@KJF45GQhVigl59B0mPklik!e7kIah-V7o@5<;vo2LQLG zARLo{J)Fpg?e*Kv`hFl%?12v~Ds_r2b|U>M@$DL7_ml9ugyJ51Ay@ZRC-T3va}+*j zjoAr!(TU70XO68g+vDQ`)=csEQ%+=?`c}`V1F**Q2aW=kDBHdO*q_#Dyd*duILC=B zSy3A(AOdRucLAH1c;zI#bzvoy9b25p)!jhu?-^s)XB8osk=%X`aIO<+DwjC7hrkB7 z9RmCXuM95A**KBi;$yA{6qP0b4*A^S?MN|6qo8mg(X+t(d&t5sM<>+OEJq zGB(+jqs>+-PT2V80S=F2P5oeq7f91c)tk+F4_^qOE*afvk)QBF--&3Ez-udPUM(E^U)pQb4Q-p zbLU1AxX#eV#_>ZN8^4Tq^Ifk7$F={^#>UlV&z*a3G_HUcd_1(VaVFl4xDX5mdJJuB zTy1D$}B}ccEJo04MSxa9tN1<8^U%SQB0BoAUi-z~NnB9!~CpxINq& zvsVFbXDzb%INaRr34juTAL8A3yArHojoBkO9RNn?36ch`b|Np-a=rj%jb8!I>Vj+d zXstyM!lfDB-_ePD+FkQOG=z&pVK)j#PhAUKUZdmuMr@2>-GC2)zfm~z&@)ctq>#O= zMF;|>&ckQeEd)(9I=s!$5OwA5*1_i-Oam7?kw?3;TX4?;rjP;nL=da$|9N1qAbH0{ zsyyj|PvE&Xkk>_a8Swp#efTo4sD#d;C$Kd>4q?MG#<^~=5jMapj{qKXB0K1~;xX$0 zGpsRvOF0k=7JyYvSYbdt~_ZOTg3;xXt5> ziEJ2~`?RoTw2l?OyJ&lP;0k=E;(ox@c!#D4nt?xt1hP94fzS%@CE!e@sKbJ1mO7C> z;X<;;+=@3L%?HLfk&pELrN9p|_MyKMS(I`i_rPb9`9{WXJnlrcS7LV!-n#THjw^H*=N@ zJ*PR53sUxVFz{`BmY}RK6rUFY%}l)-KGtEA$W*9SuE~H6-g^_cGz$Fcj(!0R)|i#m zdE!ZY@XxRUTtctd#H^ve2Pq*~j-ZsQhbRHf_|)E6;R*dc5FZy1LEO!`u|VI}!DliO zYs?L`v^aD_tZ$9EONsSq1@QYx?Ef%z)-R%3d>K#va&S9WvjR2%@44^i7X9D zmMv9oC(apOWsPaE#{3RgrMqzf4a(}TTjH7P0!n=$Z7Z{Mh$BgGnw680_G10rE4Bgd zw#E$7#WRYwg)0leK{bfuhk(6`+`lMB+`ktSy*BD7Vx{mwJDLe=3tDT;T0v#$5wxvY z80Un)NBUTTuA>8RB5$bU#A!vIJIoqW=;ZwnA1}}zXioWD4{J;#@SlwBU+P5W=qa#3 z+4-;Oy)nQ%Ys}jz8uk>}-ib`9MIC@D#FQM?B^U{ouHn?k@%veS=xCM*u{xRcT)!DVhiO&l1+V4 zWY(!p$+QR{*VLchp+IvN0Ddub0T+^IAuBm2XMX<$(kVsYs|G2_X+F;5C*=TUJCUI&=3*Q^k!cc~4qW6!x?S1025Za_s_fY#1xwx8 zp&3{?GFxVZQt|(%120=+wy%YgQBT7LYs~lX-hag`0ZsTs8MOp+&}6SE+;|tH(04p* zjoDQb;dCDYfcJ(PlyY-*cIbh(*-x^@^v~$u-IC&&4e?5?T7lz%-_mLuPl9~P@pl$z z0d{gCZ>QwO(j<2o58RJ;D(Y4Q;P@025;{H~TzgW4VYL%kz)_y9lahc@mxftYK{3RzOY9js8;dJE%3oWNr>ANID+z$a-2TTi-ek6f~~Fwyyip}7P&tKxZWCb9>u*C3+{7k%-T-my>_y^A4ZF>)?xvIeqU>i z*%3Inz@vRhrw7UkcU7vmN;LOn&c7{!@83I-r)rI`S5gNMvBO`-hfgNKwpHpwE(P*) zYTBEcvF(*f_6SQ$?g!(w|6`MM3hiCkh5oK&``Yi56E;73`mbDt?^jH((9X@dL6LjE zRZmH}BL~o+13w42r3Au;SYuXM5uMaB;NT0BW*y(gA#wvGADE$?A;44Cmoyu0MKo4%no`WA|BO_Nz33kGIts2~1Co^FA}> z^Ltuj{*yo`mgq^6`IJbqy#^aUg2&2e{|al&3}C7?W-&0(8nZ3g(_=O2_xqQz2>Rl) z)V>A$HDqV4F~b1SXSZ@9lVY{+Cg2mHT;N19Mat>>7XUv>@%YXZH*uDeF{mXCfvP4n zH#hg8bVOqV@DFRuK2GGWG6?KSDrUSK)hh_*e|zy;qU)QI>@HoDgTM!t-3EL;hL>CP_i@&kYn;fd0pa+r z?x{~H?W<8;`CDtQpM?*M=?u;g3xO}H4|_;$1)sjWBOs4g0NxM$qEtYTX482Ocs{IL zV~zP2ZOd3kS$H;O`2-l}Ig!)#WOy~e(L1_8X9t93w4U5IskT4qggOQ9>%T@;4yKB5 zzZ2QLT8)n$F@m>d&Sdn65xeB``3H&+fVuc+zzf67NCoDyzwV045H|dS<`&DuMn< z$Hg1m27EiRQk2;IBWX>gbtAr7a^!~}uVH_SHRcXr`vOgUU)$O`wqS?j{q-N$@13dy zyPqziD~inB#nzbL0AulqLHFteD6OjB{aZ6U1$K)LF8I{D2M50mj8xM7y13xPX>&3_JX65cOiooa~&xdNxfD)`!Y zE86j=4F?e8R37c1K0N6}woN0yT4TOV+ZqJ3@IDSd!Y9|P1U!aMW^xCuiA@2nb0S9- z6GwvIS@J$q6Yh2*dsp)V)|ib+wj4DBTrM}Vfan#6ovblG z4TyOUYs~f5m@BL?gM)%2gIGQj)gaZEr4e-&rNphlXGfwC0f-dG)|jKMF%N|YQM(C% zDjbgP?8sHw>w*saWN+Xv!T&o3r}10Bzm;%~E~D*5z?YoJ@lNDuyt!&&8SV73#{60P z`6<5M9eB%5Bu#^AwK*IA0ZV;KPd##RtfJ0^Fz~=fNbq5*JlP0Arm< zf7QQCFLNxrSYx)pXE^#m^$|N!fpTvRF`4`QTEMImc~+6skzz*#@w^CMA)TGQ5X_Cr zjwyAYPIjvEA(tssDMDCwStuZt;HPNeAuR-~I{+d8E%N4-yL-_ob4tT?f+#TG@ zS8%9vgY^pO@)Bf$1r;Lzfp?nVJ<}#yV$ zE^tZ-w(Tq@@|oK88-PiH*{9ryxsUKwjc(9BZ-}=m|JI3oS8?zcT1%h3r!wp=db+P) z#y1zEPF9-A>=~dB@N2bY->58a65N504((e>q>kHk(;@rpyYH$;eEZu)H-A2#2gv1e zxssc5X;TyL{_lTiMC%udJo+;ya!HZ()*b>dQxC+=_5YiJ&2+uyVjRH#=~~;e(gYxj z&p@sSMa|)D%g2>yV>aGC{lDPdUU=8Yp}-W~OjUJr49r|>;hkM(IFY8!k9`vI>@Epl?4rky)klza4Sq1o}%JJJ}Ah?(5 zslNlQm5{D;B1c(c{zvJ;E;~DshpK_I-dOW_b>*8+U9w#zK`*bg@DfR>(lD;*qF3FRC?SispyD46`QC&e= zxD9W5-c)r`+W<42$hfo(GJTuiLdLnHLwrfUfM?|@;xUqnhpSK%)Y7! z>!H;AHQ-j zz)Q$pBQb)X<2@X&O{u6H=|nzK2c^AqZZ^|7y?qi6h3%Zkf&#uI{qV}<>wpO< zr>B{=4n+%{$bfbc0PV~VDX&mtL5*xwfU(L8f#1C$e8;Y@a3r3YN?Y@1BEUneSwn*cGN|dwi@peRge{0Skv&Ck``B)2<(ZkMqP+) zpNOvrlvWh{g|7XqO1T-pWlrRGDY%jWdfDY(lNY7Q#x(QW=r1jWa+3hTPpd(ZtlLgLFLif8g_|<@}?NsNp zM8)adi|vD0U4#3Tu)WT74;8<^2)~sQM~j`v;ZCHl6FD*Bl8U_>%X+lT ziQJ=HXqrgamZUY1M09c)6)yX$;vtD}jMZYJ(E>k8<;*6%H@%9B1T~OU5Q?^{xqpJd0>&xzJO0sxkCLXg8A-?_x3B6xj3(zy+KcQfOnn9{??e+ ziYTF;RM|DJ-?T~u1_R%ZPR1&YZ-C1EBYaaD)L@mYs|X3X|mYhUs28LLRK&Y_*(2lj@20ak{{`4%pk310`ZZig(*XB^zl?YT3^kb8OI$^(n0_ zKa{razNO#}C$fnXS-2w8XeHG>bRs9}iwn9tPpoF#4~G4V<+BSJo-Z9<8-2?D$$#8kYd zIo`g*d+t36EGS^7FRC?FFqvquvi~kv|nN0-qcg#xm zbQZ5UirZy{@Q{@NOu=i%pHRih%Xs_$K^X@;3vd3Kq;0*R8u3!!AFc~x2Ye}~@fi`- z1pEYVf1jWW=!;7654XlVLV5KERs=NT{nRgVA`c`G$^I&;6f^gI;6&DpWv`j5ZO>4G zodu?)T8PS9-YFE(Y`>UcksUVFQ^Xa1Lb6TsQzGWyqoius>f+;$G3j%L{1In zU`u=%vA?S#@j0@2+I0ok+KD`qw3plMzi*8>p5pZcIuk6yd)Y;K2KT~yg^j`o$LvgP z)j*7kJO|-D!Qw>VIK@#Cz8}U1$4t{x{|=2E=%J_P<~1@0S38m8f^iSVn-9mTuHbt$ zjNfwM-*{K$>3Gl7Hm7(cysU1^5adee6<}@X8g&-ak z__aW+>r+E>Fen0WX1|!;;RdowCW-M8R@YiU3@y zEab8HT!N=)AgE6Qd+5j|R^iK|(lrH-~G(Sd(_?018Aig~1F5 z0Jq0pc~4J~N(Kc?Q5ilgZuucT4*SDWeYeIu%<@S#YZ;n=ZJo%o!5GuB!*lTY1>X(u zn8Oz{`7AbXlUQ;2Bmd$=j*P9hK~7|TEIjy9vRg5_GCc1@+Tg5R96;PE5c~g?0?LT7 z__*gvW%Zqe*HCX2V{vEG8i!B{exO9DjWP*u>)r^j90PBq_z&J6{#GS!pJwcDv-a)N z57bjSA=v!0RlXmO*NDgA`%dKD7?I3J`5a<6j;Gsx1n+e7SOpjC6?p5< z$Fb{AgnbE0+_&+icOpN;nL}wvt#$}Q^aZ!21x(_5`;-aK~%r4p|!W-W7Q`Y z@_h~$aZuIeYcWFjOrS~rKP~I^ipouohUKoyI0avKBAcXnP+fD+)&6CH955(29mA0B z{hi1o`uCRBnCY}lW_o}%<|TYsaz4yOP{0HnRWw=zoa00;)PDaQ?;{d|=tkU|<(0-C zDACxTfO8NlEsUM&YwSjr3&o7eyR&uLl3HTBfkr4%JF)Ihv!y3~gT4W{W?+svoYs^*nvR-K+56laS zyc`>h{gD_RZl-N;$zFI{{0G*UtBRz~0`Gy>0!(xwZw05ytGeM$(4Re=$m_b{PLH*- zrxTfMjoAa;t8o!*ezbhsh1zZ(-7xJ5YMSCi zUhAl%-Wszxt@$c0bRvs``MLrh4-$#_WAJelQ-HIh3R4Z$=vcsl%?T9_!HM!OWl5TV z6P?IY!2PfY$i z7$4~3%KYxs;AASK1RW1NY>l}bZ#O@Mwx+OGJBYeRbFxK7W$l!poZ7cPJ}7AmeoX#)-?7}pc>8pw!k}1M3Ty?w*$u$@csdV zGrl?>pE3CN?a%>?RnaX?KiA6V^Y6tHqMqtRew|^ghvS{u8e%$?G->R9=|s-#bOfLS zPu5-Wi6KkDJ9=79bRr)F@0UXWmZ!ZO9PC8?7T4HYW5(b!I{hpq zAvnc}TvCnr{z`B71l*2QrDK}7f);$?kK4i+kunLuovMFIv#$oQd=On~0uYRKQg4jTC1P+A$;C1S_<<9-Gl4THhX7O)PIe-frr30+;d2l+CgA^XPUPSf zl>w)ML}0jzdxH};{ine1oya)}?UX|R+6!4ZfKd0*h8tv@%0FjDmv|IjXAnN_2Zg=V64R|Tt5zs zh&F$%jWHZ+pgWtR9-0fjV;+bq3wJjH zFc2T|nkG~5k{TG#YQPiLm|+=Dvakqd66~M^X6IVj1lE`@<6Xmlnt}j!WhgbiU4Zwk zF-Q08W(1%Q>C1TMYh+B@053X`ED24Q;N5~tL0^0j(Zm{=i)%@jIHskGuk%?c55udv z8wcmk(}Mc;7l08IjwEXjypbUo$f_)R zREG8svc}vS#ZDB0bw`b&xw&}&$qKSNoydN1`MMT#0Q$QL?-h5aiY|r5xq6kl@l7S* zk$E-B?Ash%%Ljd^ikUG7!;8qTKhdgJSYzmx1V9Hr1UR|KBO6xXvsr?H96rO(0XDD9NZnG7AnrVL@CYwUCAEkZ#+oXkxK?5+=8uOKK z&T47%TVpoCr>sxna;jCXK8s`B$N2E*eeosf_GS45I+-0|)-ugG@QGPU$%+55#_a7x?yfQX zZi!FavQmlp-O`CnT7i9CgwNJnQP^PAsJ=^^o5z)S>_%(M22SMk?kEBrOS(W21MF#y zNy;tItJES(VDW}pW135xB7O9^?~pyERlK6i=b)P(yy-9vQMtMri?qt{DCvsDe8(E| zcEYnw`0PeyaR8b|ExzIN9pO>Btfj@0uEyohtTBJ>js)Ob-5@8H*aU-U%{@>l7=Wz;!#Q3%$rzfw&xK zrZrvH@*1E;iw;r_sL%qL1zZQ57v$j{iXW-4eyQ{vVApsYwR=5krT+3Il z_Skc|T#tM{zekbHAC=_$r4xBFtJ0!N5rRO`wjSPjq(>JS-hEDF&jjMvTlF8~6W;xX z6S=k4HhvM@_Emy*NGIsp8BXL^RUZ4A_yV_uMAJ8c-JHmbU_ErpV4!#z>+f`-&A$wv zT(j-5G;(CLDK^Ku_9iJXe`$^BS*x2r!fo*PVyb8I>x^(5$$F{5sE1&f!mV2pfI!2( zeT~Yw%ZYyad;cggWE)|x)jaeay!kIzgoQmVr8i+`7xl2l{EkjsAt>l)CE8en;>lxI z!+QX>A(GuTA&5G|eAIMbYBrb;hSA#9FGCxoX9^4og`yMj%2-2qk03E>t@JP z+K1t?E-){Dp_2#w1gXi}+tlj#EXes3`2CJGX7xG&@XDd9fw%CQ^I8cJjgUJHU;BNB zC<|~rnd-=O)?xaL88kIFAA-02M_gZ=^J~#|KgQ?g?+V26@nF6>WoUPp@i?FNU5tLG zVf#N{5c&K$_zc#$1g<`sgBE;_%g?&C2vA7LWsO+}pKko%BCq}rxQld-CaEEp%jMQz zfBljD`t?i1N#B0`a?Q=n)1P?kv3q*=>GM)l=RGNla`1Z;K0D4T37>xvpML#aC$gm2 z9MzzXXQ=8mEIzj56uc#*7=9~CEb{q0Lxv1lZP>737u-K_;+gq;zDEI~l+WdI~$

#H(OwiKO!kBf}&8@fIdM%e@k*x|!*@4OR5jFyUN+1iOb zlXL)fYXT4>1gk20RLTQv5%7g5|GU-~9D}bg(;v7gp6|Yj{ayo~^MA2Y_~}}i2d!}P z0O=|pZ{b9q@8UTAB3>z2biV?7Ig$Hf?~cSfaJ}P1W>g!u0S7YxZ^nGriOh>VGg`UP z4N5e3HE?{AqOnc@S|{{)d_A=^@E*Qk=vGQFdea(MwFnrjIR~oQ-$D2)x#N`cSc>-p zm<8OXgkfCD=ALsRTXtn}&l>YuiPJxXuj5l@?Ta@f_Ej7>bG+X4Mv1@Erg2Opd8 ze!$MZhR;>8L5im4>fyGu5Yeg=fYu40f-h!T3D_^HCs4)yZUDSqq2?9<6T-q6T@1H7 z;LDd+0&a04hg7kz5y6^>FVtEI_^}hYxX_J;`quv(J}l#%#rSBwLus3caf=S<@A%jT zJ{S07nQi6pIpVr1e6bzxKCfI|1lx!Dl1f8xO2-|T=Cz~QU5g>Ue)_jk-CiNI z{#U#ycYyx%1+Go1nBB9!{oB}M<8pidBCjn1o{eeF@4{OVtjcbSszt1TJ@nG6PUM~7 zM0!f~6B{QqF(@|nrdYdOlDIpOs|wuvHOVI3lbp!=!MyyC)@;&W#g{g(7K{zJ^F4I) z<3y%dW3C{%U~CKUFDl z&qJL6B*WSi&-l|HxWO7T)*7>hHRf7iC%xAfUxH~!C2Q;jNIW~ZJjxn#rhcOzKGW>l z<;sNJ2udmPerJtYIhgZMiB`30N&3AB!KKTi>uTCPu0#`=f}iR-fMiO%1Ff3lyvmLX z^~B9GZ?^*%;Y~W9Wi=04V;b-#sZ~|H_)$i}{fTk~18EI=zR8Ik+RgDhowmtABUjmY zX!v7zb82G&5%5glCSZ={_$$eBCwQUu#E0u{3;d=4=jrfy4i8{?r=R9npBFii{&fP- z{spo!Ub8+Mcvg`xU6m{cmeJ(<`u-bu_uK#C9gk*3i^m$%TNONOo9Er@6dz6|-xcm>_0DCtIt?+?XW zi+0rC8UC(|J9- zqOX4iKJ$(q8ncvh?4!CFLpleZG;nyKA~0ESTekvahk-TJ*FH%~pzgZ)ON_mD1rNpH zR6qaYpp4^N4(dw4_7i|+%B$s9X;`KwO`HJKxxDmHhyX;P(kmKTs&N?A2|#v;N=|(Q zTmX!9B7-Pyp6Lka2ds(rOq{CMmQp)q&N~D2q%~Z)3Ai3#W$E-4+^?rqPjH^DyX82% zIsxc7_yOKbvnD=&-kW;;sTJ6#X-=fsiOh8(zjY$x@XEejX=}f(LveT>xDoFmI0QJ- zi9CgO`dPdJ`}Lp`c@a3>iL8!SUOtFdShkzu)ghbwxCD5ifTHDb+B%3d16S$^GOj|O z|3DY$VZa)}^{L@Q+P9aZzw3}1w=MXBA#s?Gw+4lCJ`Zoz`9cM|FavMWi|Y=s>J>?TB8DQb|OQa$TYovUx8PCj?b%D zh>%}|Pdm3HcKt0UGR283bRv6e8=nF*oyfFmjjc`qDhqo6hd7Z%G1lzY!83n$B2m)K zKhYXs62VV((Om}|A6$PKAITR6FP#nSq(LI}*{?1ftDM(iG12Ol*mD;G=Q@#_BQ`yN z7o5mXoXFpldkEtVP7T|2BIn|>OpU9Hay8B!SYy_<#=K;Wxz8HYCq$+-W*2KrUVqLC z-ihx2+!`~}8nbVGHaj0~_4lKSzZ(lY^S<6&YK<8id+#W{{(gOvcm2gONL_sk-TQ_$ z=G1tiQ6&U9YfNK(fplsDFwh#aVT8XJ0pHddv)CGQejyxMW5#H1#}$I#{|78TGMeWS RmQDZw002ovPDHLkV1g04Y0v-w diff --git a/src/assembler.rs b/src/assembler.rs index 40f58ba3..0737a6be 100644 --- a/src/assembler.rs +++ b/src/assembler.rs @@ -293,7 +293,7 @@ fn resolve_label( /// # Examples /// /// ``` -/// use solana_rbpf::{assembler::assemble, program::BuiltinProgram, vm::{Config, TestContextObject}}; +/// use solana_sbpf::{assembler::assemble, program::BuiltinProgram, vm::{Config, TestContextObject}}; /// let executable = assemble::( /// "add64 r1, 0x605 /// mov64 r2, 0x32 diff --git a/src/ebpf.rs b/src/ebpf.rs index 35bdcb36..be9bfc7e 100644 --- a/src/ebpf.rs +++ b/src/ebpf.rs @@ -208,7 +208,7 @@ pub const BPF_JSLT: u8 = 0xc0; pub const BPF_JSLE: u8 = 0xd0; // Op codes -// (Following operation names are not “official”, but may be proper to rbpf; Linux kernel only +// (Following operation names are not “official”, but may be proper to sbpf; Linux kernel only // combines above flags and does not attribute a name per operation.) /// BPF opcode: `lddw dst, imm` /// `dst = imm`. [DEPRECATED] @@ -531,7 +531,7 @@ impl Insn { /// # Examples /// /// ``` - /// use solana_rbpf::ebpf; + /// use solana_sbpf::ebpf; /// /// let prog: &[u8] = &[ /// 0xb7, 0x12, 0x56, 0x34, 0xde, 0xbc, 0x9a, 0x78, @@ -564,7 +564,7 @@ impl Insn { /// # Examples /// /// ``` - /// use solana_rbpf::ebpf; + /// use solana_sbpf::ebpf; /// /// let prog: Vec = vec![ /// 0xb7, 0x12, 0x56, 0x34, 0xde, 0xbc, 0x9a, 0x78, @@ -595,7 +595,7 @@ impl Insn { /// # Examples /// /// ``` -/// use solana_rbpf::ebpf; +/// use solana_sbpf::ebpf; /// /// let prog = &[ /// 0xb7, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -608,7 +608,7 @@ impl Insn { /// The example below will panic, since the last instruction is not complete and cannot be loaded. /// /// ```rust,should_panic -/// use solana_rbpf::ebpf; +/// use solana_sbpf::ebpf; /// /// let prog = &[ /// 0xb7, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, diff --git a/src/lib.rs b/src/lib.rs index 573d8810..3e1c6176 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9,12 +9,8 @@ // the MIT license , at your option. This file may not be // copied, modified, or distributed except according to those terms. -//! Virtual machine and JIT compiler for eBPF programs. +//! Virtual machine for SBPF programs. #![warn(missing_docs)] -#![doc( - html_logo_url = "https://raw.githubusercontent.com/qmonnet/rbpf/master/misc/rbpf.png", - html_favicon_url = "https://raw.githubusercontent.com/qmonnet/rbpf/master/misc/rbpf.ico" -)] #![deny(clippy::arithmetic_side_effects)] #![deny(clippy::ptr_as_ptr)] diff --git a/src/syscalls.rs b/src/syscalls.rs index a8d398db..1ef007b5 100644 --- a/src/syscalls.rs +++ b/src/syscalls.rs @@ -15,7 +15,7 @@ //! //! * Some of them mimic the syscalls available in the Linux kernel. //! * Some of them were proposed as example syscalls in uBPF and they were adapted here. -//! * Other syscalls may be specific to rbpf. +//! * Other syscalls may be specific to sbpf. //! //! The prototype for syscalls is always the same: five `u64` as arguments, and a `u64` as a return //! value. Hence some syscalls have unused arguments, or return a 0 value in all cases, in order to diff --git a/src/vm.rs b/src/vm.rs index 3afa01b6..e1312c94 100644 --- a/src/vm.rs +++ b/src/vm.rs @@ -232,7 +232,7 @@ pub struct CallFrame { /// # Examples /// /// ``` -/// use solana_rbpf::{ +/// use solana_sbpf::{ /// aligned_memory::AlignedMemory, /// ebpf, /// elf::Executable, diff --git a/test_utils/Cargo.lock b/test_utils/Cargo.lock index a546bc6d..fe0d0385 100644 --- a/test_utils/Cargo.lock +++ b/test_utils/Cargo.lock @@ -153,8 +153,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04c565b551bafbef4157586fa379538366e4385d42082f255bfd96e4fe8519da" [[package]] -name = "solana_rbpf" -version = "0.8.2" +name = "solana-sbpf" +version = "0.9.0" dependencies = [ "byteorder", "combine", @@ -181,10 +181,10 @@ dependencies = [ [[package]] name = "test_utils" -version = "0.8.2" +version = "0.9.0" dependencies = [ "libc", - "solana_rbpf", + "solana-sbpf", ] [[package]] diff --git a/test_utils/Cargo.toml b/test_utils/Cargo.toml index 2c1bc4de..f4592b20 100644 --- a/test_utils/Cargo.toml +++ b/test_utils/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "test_utils" -version = "0.8.2" +version = "0.9.0" authors = ["Solana Maintainers "] edition = "2018" publish = false [dependencies] libc = "0.2" -solana_rbpf = { path = "../" } +solana-sbpf = { path = "../" } diff --git a/test_utils/src/lib.rs b/test_utils/src/lib.rs index 0f8e1c2d..2f1d8df5 100644 --- a/test_utils/src/lib.rs +++ b/test_utils/src/lib.rs @@ -8,7 +8,7 @@ #![allow(dead_code)] -use solana_rbpf::{ +use solana_sbpf::{ aligned_memory::AlignedMemory, ebpf::{self, HOST_ALIGN}, elf::Executable, @@ -194,10 +194,10 @@ pub fn create_memory_mapping<'a, C: ContextObject>( #[macro_export] macro_rules! create_vm { ($vm_name:ident, $verified_executable:expr, $context_object:expr, $stack:ident, $heap:ident, $additional_regions:expr, $cow_cb:expr) => { - let mut $stack = solana_rbpf::aligned_memory::AlignedMemory::zero_filled( + let mut $stack = solana_sbpf::aligned_memory::AlignedMemory::zero_filled( $verified_executable.get_config().stack_size(), ); - let mut $heap = solana_rbpf::aligned_memory::AlignedMemory::with_capacity(0); + let mut $heap = solana_sbpf::aligned_memory::AlignedMemory::with_capacity(0); let stack_len = $stack.len(); let memory_mapping = test_utils::create_memory_mapping( $verified_executable, @@ -207,7 +207,7 @@ macro_rules! create_vm { $cow_cb, ) .unwrap(); - let mut $vm_name = solana_rbpf::vm::EbpfVm::new( + let mut $vm_name = solana_sbpf::vm::EbpfVm::new( $verified_executable.get_loader().clone(), $verified_executable.get_sbpf_version(), $context_object, diff --git a/tests/assembler.rs b/tests/assembler.rs index 2ce72f09..6b78613e 100644 --- a/tests/assembler.rs +++ b/tests/assembler.rs @@ -5,12 +5,12 @@ // the MIT license , at your option. This file may not be // copied, modified, or distributed except according to those terms. -extern crate solana_rbpf; +extern crate solana_sbpf; extern crate test_utils; -use solana_rbpf::program::{FunctionRegistry, SBPFVersion}; -use solana_rbpf::vm::Config; -use solana_rbpf::{assembler::assemble, ebpf, program::BuiltinProgram, vm::TestContextObject}; +use solana_sbpf::program::{FunctionRegistry, SBPFVersion}; +use solana_sbpf::vm::Config; +use solana_sbpf::{assembler::assemble, ebpf, program::BuiltinProgram, vm::TestContextObject}; use std::sync::Arc; use test_utils::{TCP_SACK_ASM, TCP_SACK_BIN}; diff --git a/tests/disassembler.rs b/tests/disassembler.rs index cc55af86..a4a358c8 100644 --- a/tests/disassembler.rs +++ b/tests/disassembler.rs @@ -6,9 +6,9 @@ // the MIT license , at your option. This file may not be // copied, modified, or distributed except according to those terms. -extern crate solana_rbpf; -use solana_rbpf::program::SBPFVersion; -use solana_rbpf::{ +extern crate solana_sbpf; +use solana_sbpf::program::SBPFVersion; +use solana_sbpf::{ assembler::assemble, program::{BuiltinProgram, FunctionRegistry}, static_analysis::Analysis, diff --git a/tests/elfs/elfs.sh b/tests/elfs/elfs.sh index 93190d97..25b72b7a 100755 --- a/tests/elfs/elfs.sh +++ b/tests/elfs/elfs.sh @@ -1,7 +1,7 @@ #!/bin/bash -ex # Requires Latest release of Solana's custom LLVM -# https://github.com/solana-labs/platform-tools/releases +# https://github.com/anza-xyz/platform-tools/releases TOOLCHAIN=../../../agave/sdk/sbf/dependencies/platform-tools RC_COMMON="$TOOLCHAIN/rust/bin/rustc --target sbf-solana-solana --crate-type lib -C panic=abort -C opt-level=2" diff --git a/tests/execution.rs b/tests/execution.rs index 22439ffa..bd87ad07 100644 --- a/tests/execution.rs +++ b/tests/execution.rs @@ -8,14 +8,14 @@ extern crate byteorder; extern crate libc; -extern crate solana_rbpf; +extern crate solana_sbpf; extern crate test_utils; extern crate thiserror; use byteorder::{ByteOrder, LittleEndian}; #[cfg(all(not(windows), target_arch = "x86_64"))] use rand::{rngs::SmallRng, RngCore, SeedableRng}; -use solana_rbpf::{ +use solana_sbpf::{ assembler::assemble, declare_builtin_function, ebpf, elf::Executable, @@ -3435,7 +3435,7 @@ fn execute_generated_program(prog: &[u8]) -> bool { || !TestContextObject::compare_trace_log(&tracer_interpreter, tracer_jit) { let analysis = - solana_rbpf::static_analysis::Analysis::from_executable(&executable).unwrap(); + solana_sbpf::static_analysis::Analysis::from_executable(&executable).unwrap(); println!("result_interpreter={result_interpreter:?}"); println!("result_jit={result_jit:?}"); let stdout = std::io::stdout(); diff --git a/tests/exercise_instructions.rs b/tests/exercise_instructions.rs index 2538b305..f8f5a89b 100644 --- a/tests/exercise_instructions.rs +++ b/tests/exercise_instructions.rs @@ -8,12 +8,12 @@ extern crate byteorder; extern crate libc; -extern crate solana_rbpf; +extern crate solana_sbpf; extern crate test_utils; extern crate thiserror; use rand::{rngs::SmallRng, RngCore, SeedableRng}; -use solana_rbpf::{ +use solana_sbpf::{ assembler::assemble, ebpf, memory_region::MemoryRegion, diff --git a/tests/verifier.rs b/tests/verifier.rs index d6ff690d..658d9b5e 100644 --- a/tests/verifier.rs +++ b/tests/verifier.rs @@ -19,10 +19,10 @@ // These are unit tests for the eBPF “verifier”. -extern crate solana_rbpf; +extern crate solana_sbpf; extern crate thiserror; -use solana_rbpf::{ +use solana_sbpf::{ assembler::assemble, ebpf, elf::Executable,