BPF rust language updates (#4752)
This commit is contained in:
@ -81,8 +81,9 @@ fn main() {
|
||||
"cargo:warning=(not a warning) Building Rust-based BPF programs: solana_bpf_rust_{}",
|
||||
program
|
||||
);
|
||||
assert!(Command::new("./build.sh")
|
||||
assert!(Command::new("./do.sh")
|
||||
.current_dir("rust")
|
||||
.arg("build")
|
||||
.arg(program)
|
||||
.status()
|
||||
.expect(&format!(
|
||||
|
@ -6,11 +6,10 @@
|
||||
extern crate alloc;
|
||||
extern crate solana_sdk_bpf_utils;
|
||||
|
||||
use solana_sdk_bpf_utils::log::*;
|
||||
|
||||
use alloc::vec::Vec;
|
||||
use core::alloc::Layout;
|
||||
use core::mem;
|
||||
use solana_sdk_bpf_utils::info;
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn entrypoint(_input: *mut u8) -> bool {
|
||||
@ -20,7 +19,7 @@ pub extern "C" fn entrypoint(_input: *mut u8) -> bool {
|
||||
let layout = Layout::from_size_align(core::usize::MAX, mem::align_of::<u8>()).unwrap();
|
||||
let ptr = alloc::alloc::alloc(layout);
|
||||
if !ptr.is_null() {
|
||||
sol_log("Error: Alloc of very larger buffer should fail");
|
||||
info!("Error: Alloc of very larger buffer should fail");
|
||||
panic!();
|
||||
}
|
||||
}
|
||||
@ -31,7 +30,7 @@ pub extern "C" fn entrypoint(_input: *mut u8) -> bool {
|
||||
let layout = Layout::from_size_align(100, mem::align_of::<u8>()).unwrap();
|
||||
let ptr = alloc::alloc::alloc(layout);
|
||||
if ptr.is_null() {
|
||||
sol_log("Error: Alloc of 100 bytes failed");
|
||||
info!("Error: Alloc of 100 bytes failed");
|
||||
alloc::alloc::handle_alloc_error(layout);
|
||||
}
|
||||
alloc::alloc::dealloc(ptr, layout);
|
||||
@ -44,7 +43,7 @@ pub extern "C" fn entrypoint(_input: *mut u8) -> bool {
|
||||
let layout = Layout::from_size_align(100, mem::align_of::<u8>()).unwrap();
|
||||
let ptr = alloc::alloc::alloc(layout);
|
||||
if ptr.is_null() {
|
||||
sol_log("Error: Alloc failed");
|
||||
info!("Error: Alloc failed");
|
||||
alloc::alloc::handle_alloc_error(layout);
|
||||
}
|
||||
for i in 0..ITERS {
|
||||
@ -53,7 +52,7 @@ pub extern "C" fn entrypoint(_input: *mut u8) -> bool {
|
||||
for i in 0..ITERS {
|
||||
assert_eq!(*ptr.add(i as usize), i as u8);
|
||||
}
|
||||
sol_log_64(0x3, 0, 0, 0, u64::from(*ptr.add(42)));
|
||||
info!(0x3, 0, 0, 0, u64::from(*ptr.add(42)));
|
||||
assert_eq!(*ptr.add(42), 42);
|
||||
alloc::alloc::dealloc(ptr, layout);
|
||||
}
|
||||
@ -65,13 +64,13 @@ pub extern "C" fn entrypoint(_input: *mut u8) -> bool {
|
||||
// let layout = Layout::from_size_align(2048, mem::align_of::<u8>()).unwrap();
|
||||
// let ptr = alloc::alloc::alloc(layout);
|
||||
// if ptr.is_null() {
|
||||
// sol_log("Error: Alloc of 2048 bytes failed");
|
||||
// info!("Error: Alloc of 2048 bytes failed");
|
||||
// alloc::alloc::handle_alloc_error(layout);
|
||||
// }
|
||||
// let layout = Layout::from_size_align(1, mem::align_of::<u8>()).unwrap();
|
||||
// let ptr_fail = alloc::alloc::alloc(layout);
|
||||
// if !ptr_fail.is_null() {
|
||||
// sol_log("Error: Able to alloc 1 more then max");
|
||||
// info!("Error: Able to alloc 1 more then max");
|
||||
// panic!();
|
||||
// }
|
||||
// alloc::alloc::dealloc(ptr, layout);
|
||||
@ -87,7 +86,7 @@ pub extern "C" fn entrypoint(_input: *mut u8) -> bool {
|
||||
for v in ones.iter() {
|
||||
sum += ones[*v];
|
||||
}
|
||||
sol_log_64(0x0, 0, 0, 0, sum as u64);
|
||||
info!(0x0, 0, 0, 0, sum as u64);
|
||||
assert_eq!(sum, ITERS);
|
||||
}
|
||||
|
||||
@ -98,13 +97,12 @@ pub extern "C" fn entrypoint(_input: *mut u8) -> bool {
|
||||
let mut v = Vec::new();
|
||||
|
||||
for i in 0..ITERS {
|
||||
sol_log_64(i as u64, 0, 0, 0, 0);
|
||||
v.push(i);
|
||||
}
|
||||
sol_log_64(0x4, 0, 0, 0, v.len() as u64);
|
||||
info!(0x4, 0, 0, 0, v.len() as u64);
|
||||
assert_eq!(v.len(), ITERS);
|
||||
}
|
||||
|
||||
sol_log("Success");
|
||||
info!("Success");
|
||||
true
|
||||
}
|
||||
|
@ -1,12 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
if [ "$#" -ne 1 ]; then
|
||||
# Build all projects
|
||||
for project in */ ; do
|
||||
./../../../sdk/bpf/rust/build.sh "$PWD/$project"
|
||||
done
|
||||
else
|
||||
# Build requested project
|
||||
./../../../sdk/bpf/rust/build.sh "$PWD/$1"
|
||||
|
||||
fi
|
@ -1,12 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
if [ "$#" -ne 1 ]; then
|
||||
# Clean all projects
|
||||
for project in */ ; do
|
||||
./../../../sdk/bpf/rust/clean.sh "$PWD/$project"
|
||||
done
|
||||
else
|
||||
# Clean requested project
|
||||
./../../../sdk/bpf/rust/clean.sh "$PWD/$1"
|
||||
|
||||
fi
|
@ -6,7 +6,7 @@
|
||||
extern crate solana_sdk_bpf_utils;
|
||||
|
||||
use byteorder::{ByteOrder, LittleEndian};
|
||||
use solana_sdk_bpf_utils::log::*;
|
||||
use solana_sdk_bpf_utils::info;
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn entrypoint(_input: *mut u8) -> bool {
|
||||
@ -18,6 +18,6 @@ pub extern "C" fn entrypoint(_input: *mut u8) -> bool {
|
||||
LittleEndian::write_i16(&mut buf, -5_000);
|
||||
assert_eq!(-5_000, LittleEndian::read_i16(&buf));
|
||||
|
||||
sol_log("Success");
|
||||
info!("Success");
|
||||
true
|
||||
}
|
||||
|
100
programs/bpf/rust/do.sh
Executable file
100
programs/bpf/rust/do.sh
Executable file
@ -0,0 +1,100 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
usage() {
|
||||
echo ""
|
||||
echo " Usage: do.sh action <project>"
|
||||
echo ""
|
||||
echo " If relative_project_path is ommitted then action will"
|
||||
echo " be performed on all projects"
|
||||
echo ""
|
||||
echo " Supported actions:"
|
||||
echo " build"
|
||||
echo " clean"
|
||||
echo " clippy"
|
||||
echo " fmt"
|
||||
echo ""
|
||||
}
|
||||
|
||||
perform_action() {
|
||||
set -e
|
||||
case "$1" in
|
||||
build)
|
||||
./../../../sdk/bpf/rust/build.sh "$2"
|
||||
;;
|
||||
clean)
|
||||
./../../../sdk/bpf/rust/clean.sh "$2"
|
||||
;;
|
||||
clippy)
|
||||
(
|
||||
cd "$2"
|
||||
echo "clippy $2"
|
||||
cargo +nightly clippy
|
||||
)
|
||||
;;
|
||||
fmt)
|
||||
(
|
||||
cd "$2"
|
||||
echo "formatting $2"
|
||||
cargo fmt
|
||||
)
|
||||
;;
|
||||
dump)
|
||||
# Dump depends on tools that are not installed by default and must be installed manually
|
||||
# - greadelf
|
||||
# - llvm-objdump
|
||||
# - rustfilt
|
||||
(
|
||||
pwd
|
||||
./do.sh clean "$3"
|
||||
./do.sh build "$3"
|
||||
|
||||
cd "$3"
|
||||
|
||||
set +e
|
||||
cp ./target/dump.txt ./targetdump-last.txt 2>/dev/null
|
||||
set -e
|
||||
|
||||
ls \
|
||||
-la \
|
||||
./target/bpfel-unknown-unknown/release/solana_bpf_rust_"${3%/}".so \
|
||||
> ./target/dump_mangled.txt
|
||||
greadelf \
|
||||
-aW \
|
||||
./target/bpfel-unknown-unknown/release/solana_bpf_rust_"${3%/}".so \
|
||||
>> ./target/dump_mangled.txt
|
||||
llvm-objdump \
|
||||
-print-imm-hex \
|
||||
--source \
|
||||
--disassemble \
|
||||
./target/bpfel-unknown-unknown/release/solana_bpf_rust_"${3%/}".so \
|
||||
>> ./target/dump_mangled.txt
|
||||
sed \
|
||||
s/://g \
|
||||
< ./target/dump_mangled.txt \
|
||||
| rustfilt \
|
||||
> ./target/dump.txt
|
||||
)
|
||||
;;
|
||||
help)
|
||||
usage
|
||||
exit
|
||||
;;
|
||||
*)
|
||||
echo "Error: Unknown command"
|
||||
usage
|
||||
exit
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
set -e
|
||||
|
||||
if [ "$#" -ne 2 ]; then
|
||||
# Build all projects
|
||||
for project in */ ; do
|
||||
perform_action "$1" "$PWD/$project" "$project"
|
||||
done
|
||||
else
|
||||
# Build requested project
|
||||
perform_action "$1" "$PWD/$2" "$2"
|
||||
fi
|
@ -1,21 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
if [ "$#" -ne 1 ]; then
|
||||
echo "Error: Must provide the name of the project to dump"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
./clean.sh "$1"
|
||||
./build.sh "$1"
|
||||
|
||||
cd "$1"
|
||||
|
||||
cp ./target/dump.txt ./targetdump-last.txt 2>/dev/null
|
||||
|
||||
set -ex
|
||||
|
||||
ls -la ./target/bpfel-unknown-unknown/release/solana_bpf_rust_"${1%/}".so > ./target/dump_mangled.txt
|
||||
greadelf -aW ./target/bpfel-unknown-unknown/release/solana_bpf_rust_"${1%/}".so >> ./target/dump_mangled.txt
|
||||
llvm-objdump -print-imm-hex --source --disassemble ./target/bpfel-unknown-unknown/release/solana_bpf_rust_"${1%/}".so >> ./target/dump_mangled.txt
|
||||
sed s/://g < ./target/dump_mangled.txt | rustfilt > ./target/dump.txt
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
extern crate solana_sdk_bpf_utils;
|
||||
|
||||
use solana_sdk_bpf_utils::log::*;
|
||||
use solana_sdk_bpf_utils::info;
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn entrypoint(_input: *mut u8) -> bool {
|
||||
@ -16,9 +16,9 @@ pub extern "C" fn entrypoint(_input: *mut u8) -> bool {
|
||||
for v in ones.iter() {
|
||||
sum += *v;
|
||||
}
|
||||
sol_log_64(0xff, 0, 0, 0, sum);
|
||||
info!(0xff, 0, 0, 0, sum);
|
||||
assert_eq!(sum, ITERS as u64);
|
||||
|
||||
sol_log("Success");
|
||||
info!("Success");
|
||||
true
|
||||
}
|
||||
|
@ -7,18 +7,18 @@ mod helper;
|
||||
|
||||
extern crate solana_sdk_bpf_utils;
|
||||
|
||||
use solana_sdk_bpf_utils::log::*;
|
||||
use solana_sdk_bpf_utils::info;
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn entrypoint(_input: *mut u8) -> bool {
|
||||
sol_log("call same package");
|
||||
info!("call same package");
|
||||
assert_eq!(crate::helper::many_args(1, 2, 3, 4, 5, 6, 7, 8, 9), 45);
|
||||
sol_log("call another package");
|
||||
info!("call another package");
|
||||
assert_eq!(
|
||||
solana_bpf_rust_many_args_dep::many_args(1, 2, 3, 4, 5, 6, 7, 8, 9),
|
||||
45
|
||||
);
|
||||
|
||||
sol_log("Success");
|
||||
info!("Success");
|
||||
true
|
||||
}
|
||||
|
6
programs/bpf/rust/many_args_dep/Xargo.toml
Normal file
6
programs/bpf/rust/many_args_dep/Xargo.toml
Normal file
@ -0,0 +1,6 @@
|
||||
[dependencies.compiler_builtins]
|
||||
path = "../../../../sdk/bpf/dependencies/rust-bpf-sysroot/src/compiler-builtins"
|
||||
features = ["c", "mem"]
|
||||
|
||||
[target.bpfel-unknown-unknown.dependencies]
|
||||
alloc = { path = "../../../../sdk/bpf/dependencies/rust-bpf-sysroot/src/liballoc" }
|
@ -4,7 +4,7 @@
|
||||
|
||||
extern crate solana_sdk_bpf_utils;
|
||||
|
||||
use solana_sdk_bpf_utils::log::*;
|
||||
use solana_sdk_bpf_utils::info;
|
||||
|
||||
pub fn many_args(
|
||||
arg1: u64,
|
||||
@ -17,8 +17,8 @@ pub fn many_args(
|
||||
arg8: u64,
|
||||
arg9: u64,
|
||||
) -> u64 {
|
||||
sol_log("another package");
|
||||
sol_log_64(arg1, arg2, arg3, arg4, arg5);
|
||||
sol_log_64(arg6, arg7, arg8, arg9, 0);
|
||||
info!("another package");
|
||||
info!(arg1, arg2, arg3, arg4, arg5);
|
||||
info!(arg6, arg7, arg8, arg9, 0);
|
||||
arg1 + arg2 + arg3 + arg4 + arg5 + arg6 + arg7 + arg8 + arg9
|
||||
}
|
||||
|
@ -2,12 +2,13 @@
|
||||
|
||||
#![no_std]
|
||||
#![allow(unreachable_code)]
|
||||
#![allow(unused_attributes)]
|
||||
|
||||
extern crate solana_sdk_bpf_utils;
|
||||
|
||||
use solana_sdk_bpf_utils::entrypoint;
|
||||
use solana_sdk_bpf_utils::entrypoint::*;
|
||||
use solana_sdk_bpf_utils::log::*;
|
||||
use solana_sdk_bpf_utils::{entrypoint, info};
|
||||
|
||||
struct SStruct {
|
||||
x: u64,
|
||||
@ -21,18 +22,14 @@ fn return_sstruct() -> SStruct {
|
||||
}
|
||||
|
||||
entrypoint!(process_instruction);
|
||||
fn process_instruction(
|
||||
ka: &mut [Option<SolKeyedAccount>; MAX_ACCOUNTS],
|
||||
info: &SolClusterInfo,
|
||||
data: &[u8],
|
||||
) -> bool {
|
||||
sol_log("Program identifier:");
|
||||
fn process_instruction(ka: &mut [SolKeyedAccount], info: &SolClusterInfo, data: &[u8]) -> bool {
|
||||
info!("Program identifier:");
|
||||
sol_log_key(&info.program_id);
|
||||
|
||||
// Log the provided account keys and instruction input data. In the case of
|
||||
// the no-op program, no account keys or input data are expected but real
|
||||
// programs will have specific requirements so they can do their work.
|
||||
sol_log("Account keys and instruction input data:");
|
||||
info!("Account keys and instruction input data:");
|
||||
sol_log_params(ka, data);
|
||||
|
||||
{
|
||||
@ -49,7 +46,7 @@ fn process_instruction(
|
||||
let result_str = core::str::from_utf8(&sparkle_heart).unwrap();
|
||||
assert_eq!(4, result_str.len());
|
||||
assert_eq!("💖", result_str);
|
||||
sol_log(result_str);
|
||||
info!(result_str);
|
||||
}
|
||||
|
||||
{
|
||||
@ -59,6 +56,6 @@ fn process_instruction(
|
||||
assert_eq!(s.x + s.y + s.z, 6);
|
||||
}
|
||||
|
||||
sol_log("Success");
|
||||
info!("Success");
|
||||
true
|
||||
}
|
||||
|
@ -6,22 +6,14 @@
|
||||
extern crate solana_sdk_bpf_utils;
|
||||
|
||||
use byteorder::{ByteOrder, LittleEndian};
|
||||
use solana_sdk_bpf_utils::entrypoint;
|
||||
use solana_sdk_bpf_utils::entrypoint::*;
|
||||
use solana_sdk_bpf_utils::log::*;
|
||||
use solana_sdk_bpf_utils::{entrypoint, info};
|
||||
|
||||
entrypoint!(process_instruction);
|
||||
fn process_instruction(
|
||||
ka: &mut [Option<SolKeyedAccount>; MAX_ACCOUNTS],
|
||||
_info: &SolClusterInfo,
|
||||
_data: &[u8],
|
||||
) -> bool {
|
||||
sol_log("Tick Height:");
|
||||
if let Some(k) = &ka[2] {
|
||||
let tick_height = LittleEndian::read_u64(k.data);
|
||||
assert_eq!(10u64, tick_height);
|
||||
sol_log("Success");
|
||||
return true;
|
||||
}
|
||||
panic!();
|
||||
fn process_instruction(ka: &mut [SolKeyedAccount], _info: &SolClusterInfo, _data: &[u8]) -> bool {
|
||||
let tick_height = LittleEndian::read_u64(ka[2].data);
|
||||
assert_eq!(10u64, tick_height);
|
||||
|
||||
info!("Success");
|
||||
true
|
||||
}
|
||||
|
@ -87,10 +87,10 @@ mod bpf {
|
||||
|
||||
let programs = [
|
||||
("solana_bpf_rust_alloc", true),
|
||||
("solana_bpf_rust_dep_crate", true),
|
||||
("solana_bpf_rust_iter", true),
|
||||
// ("solana_bpf_rust_many_args", true), // Issue #3099
|
||||
("solana_bpf_rust_noop", true),
|
||||
("solana_bpf_rust_dep_crate", true),
|
||||
("solana_bpf_rust_panic", false),
|
||||
("solana_bpf_rust_tick_height", true),
|
||||
];
|
||||
|
@ -164,7 +164,7 @@ pub fn helper_sol_log(
|
||||
let c_buf: *const c_char = addr as *const c_char;
|
||||
let c_str: &CStr = unsafe { CStr::from_ptr(c_buf) };
|
||||
match c_str.to_str() {
|
||||
Ok(slice) => info!("sol_log: {:?}", slice),
|
||||
Ok(slice) => info!("info!: {:?}", slice),
|
||||
Err(e) => warn!("Error: Cannot print invalid string: {}", e),
|
||||
};
|
||||
0
|
||||
@ -178,7 +178,7 @@ pub fn helper_sol_log_u64(
|
||||
_context: &mut Option<Box<Any + 'static>>,
|
||||
) -> u64 {
|
||||
info!(
|
||||
"sol_log_u64: {:#x}, {:#x}, {:#x}, {:#x}, {:#x}",
|
||||
"info!: {:#x}, {:#x}, {:#x}, {:#x}, {:#x}",
|
||||
arg1, arg2, arg3, arg4, arg5
|
||||
);
|
||||
0
|
||||
|
Reference in New Issue
Block a user