//! @brief Example Rust-based BPF program that prints out the parameters passed to it #![no_std] #[macro_use] extern crate alloc; extern crate solana_sdk_bpf_utils; use solana_sdk_bpf_utils::log::*; use core::alloc::Layout; use core::mem; #[no_mangle] pub extern "C" fn entrypoint(_input: *mut u8) -> bool { unsafe { // Confirm large allocation fails let layout = Layout::from_size_align(core::usize::MAX, mem::align_of::()).unwrap(); let ptr = alloc::alloc::alloc(layout); if !ptr.is_null() { sol_log("Error: Alloc of very larger buffer should fail"); panic!(); } } unsafe { // Test modest allocation and deallocation let layout = Layout::from_size_align(100, mem::align_of::()).unwrap(); let ptr = alloc::alloc::alloc(layout); if ptr.is_null() { sol_log("Error: Alloc of 100 bytes failed"); alloc::alloc::handle_alloc_error(layout); } alloc::alloc::dealloc(ptr, layout); } unsafe { // Test allocated memory read and write let layout = Layout::from_size_align(100, mem::align_of::()).unwrap(); let ptr = alloc::alloc::alloc(layout); if ptr.is_null() { sol_log("Error: Alloc of 100 bytes failed"); alloc::alloc::handle_alloc_error(layout); } let iter = 0..100; // This weirdness due to #issue $#4271 for (i, _) in iter.enumerate() { *ptr.add(i) = i as u8; } let iter = 0..100; // This weirdness due to #issue $#4271 for (i, _) in iter.enumerate() { assert_eq!(*ptr.add(i as usize), i as u8); } sol_log_64(0x3, 0, 0, 0, *ptr.add(42) as u64); assert_eq!(*ptr.add(42), 42); alloc::alloc::dealloc(ptr, layout); } // // TODO not supported for system or bump allocator // unsafe { // // Test alloc all bytes and one more (assumes heap size of 2048) // let layout = Layout::from_size_align(2048, mem::align_of::()).unwrap(); // let ptr = alloc::alloc::alloc(layout); // if ptr.is_null() { // sol_log("Error: Alloc of 2048 bytes failed"); // alloc::alloc::handle_alloc_error(layout); // } // let layout = Layout::from_size_align(1, mem::align_of::()).unwrap(); // let ptr_fail = alloc::alloc::alloc(layout); // if !ptr_fail.is_null() { // sol_log("Error: Able to alloc 1 more then max"); // panic!(); // } // alloc::alloc::dealloc(ptr, layout); // } // TODO gremlin causes crash only on CI // { // // Test allocated vector // const ITERS: usize = 100; // let ones = vec![1_u64; ITERS]; // let mut sum: u64 = 0; // for (i, v) in ones.iter().enumerate() { // sol_log_64(i as u64, 0, 0, 0, 0); // sum += ones[i as usize]; // } // sol_log_64(0x4, 0, 0, 0, sum); // assert_eq!(sum, ITERS as u64); // } sol_log("Success"); true }