From 97ea75a8908040cc78ebd98d0817ce7e465acc6f Mon Sep 17 00:00:00 2001 From: Jack May Date: Fri, 23 Aug 2019 11:03:53 -0700 Subject: [PATCH] Pull in solana_rbpf v0.1.14 (#5609) --- Cargo.lock | 8 +- programs/bpf/Cargo.toml | 2 +- programs/bpf/benches/bpf_loader.rs | 53 +++-- programs/bpf/c/src/bench_alu/bench_alu.c | 2 +- programs/bpf_loader_api/Cargo.toml | 2 +- programs/bpf_loader_api/src/alloc.rs | 4 +- programs/bpf_loader_api/src/allocator_bump.rs | 26 +- .../bpf_loader_api/src/allocator_system.rs | 40 ---- programs/bpf_loader_api/src/helpers.rs | 223 +++++------------- programs/bpf_loader_api/src/lib.rs | 12 +- sdk/bpf/c/inc/solana_sdk.h | 30 +-- sdk/bpf/rust/rust-no-std/src/panic.rs | 7 +- 12 files changed, 140 insertions(+), 269 deletions(-) delete mode 100644 programs/bpf_loader_api/src/allocator_system.rs diff --git a/Cargo.lock b/Cargo.lock index e20be5089f..a2194395e7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3108,7 +3108,7 @@ dependencies = [ "serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)", "solana-logger 0.18.0-pre2", "solana-sdk 0.18.0-pre2", - "solana_rbpf 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", + "solana_rbpf 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3132,7 +3132,7 @@ dependencies = [ "solana-logger 0.18.0-pre2", "solana-runtime 0.18.0-pre2", "solana-sdk 0.18.0-pre2", - "solana_rbpf 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", + "solana_rbpf 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", "walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4344,7 +4344,7 @@ dependencies = [ [[package]] name = "solana_rbpf" -version = "0.1.13" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5603,7 +5603,7 @@ dependencies = [ "checksum solana_libra_vm_cache_map 0.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9f0abd2cc72c7d76ca9e0764e3f1fa01a01f49b9014a193f2a3fe735a034bf96" "checksum solana_libra_vm_genesis 0.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4dadfcf5fabfd28d09770d698c618a48d75819f6915bd8bdfa04b93b6e492530" "checksum solana_libra_vm_runtime 0.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "055a5de29d1b8a2b9f9e20293e07998b8e188164bbe6ac8a09260043f99379aa" -"checksum solana_rbpf 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "b6145a3a0104925b0be63e817f7b5814fac6aa29a328bbc1d637ffd33022d748" +"checksum solana_rbpf 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "337645c96a0e0ef4a082dd3e3786be9a004c3904ae8b17e61081389a8b97df65" "checksum solicit 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "172382bac9424588d7840732b250faeeef88942e37b6e35317dce98cafdd75b2" "checksum spin 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "ceac490aa12c567115b40b7b7fceca03a6c9d53d5defea066123debc83c5dc1f" "checksum spin 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44363f6f51401c34e7be73db0db371c04705d35efbe9f7d6082e03a921a32c55" diff --git a/programs/bpf/Cargo.toml b/programs/bpf/Cargo.toml index 0933d4951d..96227e3f7d 100644 --- a/programs/bpf/Cargo.toml +++ b/programs/bpf/Cargo.toml @@ -26,7 +26,7 @@ solana-bpf-loader-api = { path = "../bpf_loader_api", version = "0.18.0-pre2" } solana-logger = { path = "../../logger", version = "0.18.0-pre2" } solana-runtime = { path = "../../runtime", version = "0.18.0-pre2" } solana-sdk = { path = "../../sdk", version = "0.18.0-pre2" } -solana_rbpf = "=0.1.13" +solana_rbpf = "=0.1.14" [[bench]] name = "bpf_loader" diff --git a/programs/bpf/benches/bpf_loader.rs b/programs/bpf/benches/bpf_loader.rs index c58a93752f..316f821c7c 100644 --- a/programs/bpf/benches/bpf_loader.rs +++ b/programs/bpf/benches/bpf_loader.rs @@ -3,7 +3,7 @@ extern crate test; use byteorder::{ByteOrder, LittleEndian, WriteBytesExt}; -use solana_rbpf::EbpfVmRaw; +use solana_rbpf::EbpfVm; use std::env; use std::fs::File; use std::io::Error; @@ -44,7 +44,7 @@ const ARMSTRONG_EXPECTED: u64 = 5; #[bench] fn bench_program_load_elf(bencher: &mut Bencher) { let elf = load_elf().unwrap(); - let mut vm = EbpfVmRaw::new(None).unwrap(); + let mut vm = EbpfVm::new(None).unwrap(); vm.set_verifier(empty_check).unwrap(); bencher.iter(|| { @@ -55,7 +55,7 @@ fn bench_program_load_elf(bencher: &mut Bencher) { #[bench] fn bench_program_verify(bencher: &mut Bencher) { let elf = load_elf().unwrap(); - let mut vm = EbpfVmRaw::new(None).unwrap(); + let mut vm = EbpfVm::new(None).unwrap(); vm.set_verifier(empty_check).unwrap(); vm.set_elf(&elf).unwrap(); @@ -101,28 +101,29 @@ fn bench_program_alu(bencher: &mut Bencher) { println!(" {:?} MIPS", mips); println!("{{ \"type\": \"bench\", \"name\": \"bench_program_alu_interpreted_mips\", \"median\": {:?}, \"deviation\": 0 }}", mips); - println!("JIT to native:"); - vm.jit_compile().unwrap(); - unsafe { - assert_eq!( - 1, /*true*/ - vm.execute_program_jit(&mut inner_iter).unwrap() - ); - } - assert_eq!(ARMSTRONG_LIMIT, LittleEndian::read_u64(&inner_iter)); - assert_eq!( - ARMSTRONG_EXPECTED, - LittleEndian::read_u64(&inner_iter[mem::size_of::()..]) - ); + // JIT disabled until address translation support is added + // println!("JIT to native:"); + // vm.jit_compile().unwrap(); + // unsafe { + // assert_eq!( + // 1, /*true*/ + // vm.execute_program_jit(&mut inner_iter).unwrap() + // ); + // } + // assert_eq!(ARMSTRONG_LIMIT, LittleEndian::read_u64(&inner_iter)); + // assert_eq!( + // ARMSTRONG_EXPECTED, + // LittleEndian::read_u64(&inner_iter[mem::size_of::()..]) + // ); - bencher.iter(|| unsafe { - vm.execute_program_jit(&mut inner_iter).unwrap(); - }); - let summary = bencher.bench(|_bencher| {}).unwrap(); - println!(" {:?} instructions", instructions); - println!(" {:?} ns/iter median", summary.median as u64); - assert!(0f64 != summary.median); - let mips = (instructions * (ns_per_s / summary.median as u64)) / one_million; - println!(" {:?} MIPS", mips); - println!("{{ \"type\": \"bench\", \"name\": \"bench_program_alu_jit_to_native_mips\", \"median\": {:?}, \"deviation\": 0 }}", mips); + // bencher.iter(|| unsafe { + // vm.execute_program_jit(&mut inner_iter).unwrap(); + // }); + // let summary = bencher.bench(|_bencher| {}).unwrap(); + // println!(" {:?} instructions", instructions); + // println!(" {:?} ns/iter median", summary.median as u64); + // assert!(0f64 != summary.median); + // let mips = (instructions * (ns_per_s / summary.median as u64)) / one_million; + // println!(" {:?} MIPS", mips); + // println!("{{ \"type\": \"bench\", \"name\": \"bench_program_alu_jit_to_native_mips\", \"median\": {:?}, \"deviation\": 0 }}", mips); } diff --git a/programs/bpf/c/src/bench_alu/bench_alu.c b/programs/bpf/c/src/bench_alu/bench_alu.c index 8c583775d9..d34a245260 100644 --- a/programs/bpf/c/src/bench_alu/bench_alu.c +++ b/programs/bpf/c/src/bench_alu/bench_alu.c @@ -24,7 +24,7 @@ extern bool entrypoint(const uint8_t *input) { } } - sol_log_64(x, count, 0, 0, 0); + // sol_log_64(x, count, 0, 0, 0); *result = count; return true; } diff --git a/programs/bpf_loader_api/Cargo.toml b/programs/bpf_loader_api/Cargo.toml index 9a797ea4c8..7c5a79bcca 100644 --- a/programs/bpf_loader_api/Cargo.toml +++ b/programs/bpf_loader_api/Cargo.toml @@ -16,7 +16,7 @@ log = "0.4.8" serde = "1.0.99" solana-logger = { path = "../../logger", version = "0.18.0-pre2" } solana-sdk = { path = "../../sdk", version = "0.18.0-pre2" } -solana_rbpf = "=0.1.13" +solana_rbpf = "=0.1.14" [lib] crate-type = ["lib"] diff --git a/programs/bpf_loader_api/src/alloc.rs b/programs/bpf_loader_api/src/alloc.rs index aa6c3d4176..22b56ea116 100644 --- a/programs/bpf_loader_api/src/alloc.rs +++ b/programs/bpf_loader_api/src/alloc.rs @@ -3,8 +3,8 @@ use std::fmt; /// Based loosely on the unstable std::alloc::Alloc trait pub trait Alloc { - fn alloc(&mut self, layout: Layout) -> Result<*mut u8, AllocErr>; - fn dealloc(&mut self, ptr: *mut u8, layout: Layout); + fn alloc(&mut self, layout: Layout) -> Result; + fn dealloc(&mut self, addr: u64, layout: Layout); } #[derive(Clone, PartialEq, Eq, Debug)] diff --git a/programs/bpf_loader_api/src/allocator_bump.rs b/programs/bpf_loader_api/src/allocator_bump.rs index 7755b08544..1dcc521c5d 100644 --- a/programs/bpf_loader_api/src/allocator_bump.rs +++ b/programs/bpf_loader_api/src/allocator_bump.rs @@ -6,27 +6,35 @@ use std::alloc::Layout; #[derive(Debug)] pub struct BPFAllocator { heap: Vec, - pos: usize, + start: u64, + len: u64, + pos: u64, } impl BPFAllocator { - pub fn new(heap: Vec) -> Self { - Self { heap, pos: 0 } + pub fn new(heap: Vec, virtual_address: u64) -> Self { + let len = heap.len() as u64; + Self { + heap, + start: virtual_address, + len, + pos: 0, + } } } impl Alloc for BPFAllocator { - fn alloc(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> { - if self.pos + layout.size() <= self.heap.len() { - let ptr = unsafe { self.heap.as_mut_ptr().add(self.pos) }; - self.pos += layout.size(); - Ok(ptr) + fn alloc(&mut self, layout: Layout) -> Result { + if self.pos + layout.size() as u64 <= self.len { + let addr = self.start + self.pos; + self.pos += layout.size() as u64; + Ok(addr) } else { Err(AllocErr) } } - fn dealloc(&mut self, _ptr: *mut u8, _layout: Layout) { + fn dealloc(&mut self, _addr: u64, _layout: Layout) { // It's a bump allocator, free not supported } } diff --git a/programs/bpf_loader_api/src/allocator_system.rs b/programs/bpf_loader_api/src/allocator_system.rs deleted file mode 100644 index e20027bf0d..0000000000 --- a/programs/bpf_loader_api/src/allocator_system.rs +++ /dev/null @@ -1,40 +0,0 @@ -use crate::alloc; - -use alloc::{Alloc, AllocErr}; -use std::alloc::{self as system_alloc, Layout}; - -#[derive(Debug)] -pub struct BPFAllocator { - allocated: usize, - size: usize, -} - -impl BPFAllocator { - pub fn new(heap: Vec) -> Self { - Self { - allocated: 0, - size: heap.len(), - } - } -} - -impl Alloc for BPFAllocator { - fn alloc(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> { - if self.allocated + layout.size() <= self.size { - let ptr = unsafe { system_alloc::alloc(layout) }; - if !ptr.is_null() { - self.allocated += layout.size(); - return Ok(ptr); - } - } - Err(AllocErr) - } - - #[allow(clippy::not_unsafe_ptr_arg_deref)] - fn dealloc(&mut self, ptr: *mut u8, layout: Layout) { - self.allocated -= layout.size(); - unsafe { - system_alloc::dealloc(ptr, layout); - } - } -} diff --git a/programs/bpf_loader_api/src/helpers.rs b/programs/bpf_loader_api/src/helpers.rs index ce8d3a98d0..21880abb6e 100644 --- a/programs/bpf_loader_api/src/helpers.rs +++ b/programs/bpf_loader_api/src/helpers.rs @@ -1,9 +1,13 @@ -use crate::Alloc; +use crate::alloc; +use alloc::Alloc; use libc::c_char; use log::*; -use solana_rbpf::{EbpfVmRaw, MemoryRegion}; +use solana_rbpf::{ + ebpf::{HelperContext, MM_HEAP_START}, + memory_region::{translate_addr, MemoryRegion}, + EbpfVm, +}; use std::alloc::Layout; -use std::any::Any; use std::ffi::CStr; use std::io::{Error, ErrorKind}; use std::mem; @@ -13,126 +17,66 @@ use std::str::from_utf8; /// Program heap allocators are intended to allocate/free from a given /// chunk of memory. The specific allocator implementation is /// selectable at build-time. -/// Enable only one of the following BPFAllocator implementations. +/// Only one allocator is currently supported /// Simple bump allocator, never frees use crate::allocator_bump::BPFAllocator; -/// Use the system heap (test purposes only). This allocator relies on the system heap -/// and there is no mechanism to check read-write access privileges -/// at the moment. Therefor you must disable memory bounds checking -// use allocator_system::BPFAllocator; - /// Default program heap size, allocators /// are expected to enforce this const DEFAULT_HEAP_SIZE: usize = 32 * 1024; -pub fn register_helpers(vm: &mut EbpfVmRaw) -> Result<(MemoryRegion), Error> { - vm.register_helper_ex("abort", Some(helper_abort_verify), helper_abort, None)?; - vm.register_helper_ex( - "sol_panic", - Some(helper_sol_panic_verify), - helper_sol_panic, - None, - )?; - vm.register_helper_ex( - "sol_panic_", - Some(helper_sol_panic_verify), - helper_sol_panic, - None, - )?; - vm.register_helper_ex("sol_log", Some(helper_sol_log_verify), helper_sol_log, None)?; - vm.register_helper_ex( - "sol_log_", - Some(helper_sol_log_verify_), - helper_sol_log_, - None, - )?; - vm.register_helper_ex("sol_log_64", None, helper_sol_log_u64, None)?; - vm.register_helper_ex("sol_log_64_", None, helper_sol_log_u64, None)?; +pub fn register_helpers(vm: &mut EbpfVm) -> Result<(MemoryRegion), Error> { + vm.register_helper_ex("abort", helper_abort, None)?; + vm.register_helper_ex("sol_panic", helper_sol_panic, None)?; + vm.register_helper_ex("sol_panic_", helper_sol_panic, None)?; + vm.register_helper_ex("sol_log", helper_sol_log, None)?; + vm.register_helper_ex("sol_log_", helper_sol_log, None)?; + vm.register_helper_ex("sol_log_64", helper_sol_log_u64, None)?; + vm.register_helper_ex("sol_log_64_", helper_sol_log_u64, None)?; let heap = vec![0_u8; DEFAULT_HEAP_SIZE]; - let heap_region = MemoryRegion::new_from_slice(&heap); - let context = Box::new(BPFAllocator::new(heap)); - vm.register_helper_ex( - "sol_alloc_free_", - None, - helper_sol_alloc_free, - Some(context), - )?; + let heap_region = MemoryRegion::new_from_slice(&heap, MM_HEAP_START); + let context = Box::new(BPFAllocator::new(heap, MM_HEAP_START)); + vm.register_helper_ex("sol_alloc_free_", helper_sol_alloc_free, Some(context))?; Ok(heap_region) } -/// Verifies a string passed out of the program -fn verify_string(addr: u64, ro_regions: &[MemoryRegion]) -> Result<(()), Error> { - for region in ro_regions.iter() { - if region.addr <= addr && (addr as u64) < region.addr + region.len { - let c_buf: *const c_char = addr as *const c_char; - let max_size = region.addr + region.len - addr; - unsafe { - for i in 0..max_size { - if std::ptr::read(c_buf.offset(i as isize)) == 0 { - return Ok(()); - } - } - } - return Err(Error::new(ErrorKind::Other, "Error, Unterminated string")); - } - } - Err(Error::new( - ErrorKind::Other, - "Error: Load segfault, bad string pointer", - )) -} - -type Context = Option>; - /// Abort helper functions, called when the BPF program calls `abort()` /// The verify function returns an error which will cause the BPF program /// to be halted immediately -pub fn helper_abort_verify( - _arg1: u64, - _arg2: u64, - _arg3: u64, - _arg4: u64, - _arg5: u64, - _context: &mut Context, - _ro_regions: &[MemoryRegion], - _rw_regions: &[MemoryRegion], -) -> Result<(()), Error> { - Err(Error::new( - ErrorKind::Other, - "Error: BPF program called abort()!", - )) -} pub fn helper_abort( _arg1: u64, _arg2: u64, _arg3: u64, _arg4: u64, _arg5: u64, - _context: &mut Context, -) -> u64 { - // Never called because its verify function always returns an error - 0 + _context: &mut HelperContext, + _ro_regions: &[MemoryRegion], + _rw_regions: &[MemoryRegion], +) -> Result<(u64), Error> { + Err(Error::new( + ErrorKind::Other, + "Error: BPF program called abort()!", + )) } /// Panic helper functions, called when the BPF program calls 'sol_panic_()` /// The verify function returns an error which will cause the BPF program /// to be halted immediately -pub fn helper_sol_panic_verify( +pub fn helper_sol_panic( file: u64, + len: u64, line: u64, column: u64, - _arg4: u64, _arg5: u64, - _context: &mut Context, + _context: &mut HelperContext, ro_regions: &[MemoryRegion], _rw_regions: &[MemoryRegion], -) -> Result<(()), Error> { - if verify_string(file, ro_regions).is_ok() { - let c_buf: *const c_char = file as *const c_char; +) -> Result<(u64), Error> { + if let Ok(host_addr) = translate_addr(file, len as usize, "Load", 0, ro_regions) { + let c_buf: *const c_char = host_addr as *const c_char; let c_str: &CStr = unsafe { CStr::from_ptr(c_buf) }; if let Ok(slice) = c_str.to_str() { return Err(Error::new( @@ -146,94 +90,51 @@ pub fn helper_sol_panic_verify( } Err(Error::new(ErrorKind::Other, "Error: BPF program Panicked")) } -pub fn helper_sol_panic( - _arg1: u64, - _arg2: u64, - _arg3: u64, - _arg4: u64, - _arg5: u64, - _context: &mut Context, -) -> u64 { - // Never called because its verify function always returns an error - 0 -} -/// Logging helper functions, called when the BPF program calls `sol_log_()` or -/// `sol_log_64_()`. -pub fn helper_sol_log_verify( - addr: u64, - _arg2: u64, - _arg3: u64, - _arg4: u64, - _arg5: u64, - _context: &mut Context, - ro_regions: &[MemoryRegion], - _rw_regions: &[MemoryRegion], -) -> Result<(()), Error> { - verify_string(addr, ro_regions) -} pub fn helper_sol_log( - addr: u64, - _arg2: u64, - _arg3: u64, - _arg4: u64, - _arg5: u64, - _context: &mut Context, -) -> u64 { - 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!("info!: {:?}", slice), - Err(e) => warn!("Error: Cannot print invalid string: {}", e), - }; - 0 -} -pub fn helper_sol_log_verify_( addr: u64, len: u64, _arg3: u64, _arg4: u64, _arg5: u64, - _context: &mut Context, + _context: &mut HelperContext, ro_regions: &[MemoryRegion], _rw_regions: &[MemoryRegion], -) -> Result<(()), Error> { - for region in ro_regions.iter() { - if region.addr <= addr && (addr as u64) + len <= region.addr + region.len { - return Ok(()); +) -> Result<(u64), Error> { + let host_addr = translate_addr(addr, len as usize, "Load", 0, ro_regions)?; + let c_buf: *const c_char = host_addr as *const c_char; + unsafe { + for i in 0..len { + let c = std::ptr::read(c_buf.offset(i as isize)); + if i == len - 1 || c == 0 { + let message = + from_utf8(from_raw_parts(host_addr as *const u8, len as usize)).unwrap(); + println!("info!: {}", message); + return Ok(0); + } } } Err(Error::new( ErrorKind::Other, - "Error: Load segfault, bad string pointer", + "Error: Unterminated string logged", )) } -pub fn helper_sol_log_( - addr: u64, - len: u64, - _arg3: u64, - _arg4: u64, - _arg5: u64, - _context: &mut Context, -) -> u64 { - let ptr: *const u8 = addr as *const u8; - let message = unsafe { from_utf8(from_raw_parts(ptr, len as usize)).unwrap() }; - info!("info: {:?}", message); - 0 -} + pub fn helper_sol_log_u64( arg1: u64, arg2: u64, arg3: u64, arg4: u64, arg5: u64, - _context: &mut Context, -) -> u64 { + _context: &mut HelperContext, + _ro_regions: &[MemoryRegion], + _rw_regions: &[MemoryRegion], +) -> Result<(u64), Error> { info!( "info!: {:#x}, {:#x}, {:#x}, {:#x}, {:#x}", arg1, arg2, arg3, arg4, arg5 ); - 0 + Ok(0) } /// Dynamic memory allocation helper called when the BPF program calls @@ -244,24 +145,26 @@ pub fn helper_sol_log_u64( /// to the VM to use for enforcement. pub fn helper_sol_alloc_free( size: u64, - free_ptr: u64, + free_addr: u64, _arg3: u64, _arg4: u64, _arg5: u64, - context: &mut Context, -) -> u64 { + context: &mut HelperContext, + _ro_regions: &[MemoryRegion], + _rw_regions: &[MemoryRegion], +) -> Result<(u64), Error> { if let Some(context) = context { if let Some(allocator) = context.downcast_mut::() { return { let layout = Layout::from_size_align(size as usize, mem::align_of::()).unwrap(); - if free_ptr == 0 { + if free_addr == 0 { match allocator.alloc(layout) { - Ok(ptr) => ptr as u64, - Err(_) => 0, + Ok(addr) => Ok(addr as u64), + Err(_) => Ok(0), } } else { - allocator.dealloc(free_ptr as *mut u8, layout); - 0 + allocator.dealloc(free_addr, layout); + Ok(0) } }; }; diff --git a/programs/bpf_loader_api/src/lib.rs b/programs/bpf_loader_api/src/lib.rs index 07317d70a8..7882b557f4 100644 --- a/programs/bpf_loader_api/src/lib.rs +++ b/programs/bpf_loader_api/src/lib.rs @@ -1,6 +1,5 @@ pub mod alloc; pub mod allocator_bump; -pub mod allocator_system; pub mod bpf_verifier; pub mod helpers; @@ -14,10 +13,9 @@ macro_rules! solana_bpf_loader { }; } -use alloc::Alloc; use byteorder::{ByteOrder, LittleEndian, WriteBytesExt}; use log::*; -use solana_rbpf::{EbpfVmRaw, MemoryRegion}; +use solana_rbpf::{memory_region::MemoryRegion, EbpfVm}; use solana_sdk::account::KeyedAccount; use solana_sdk::instruction::InstructionError; use solana_sdk::loader_instruction::LoaderInstruction; @@ -26,8 +24,8 @@ use std::io::prelude::*; use std::io::Error; use std::mem; -pub fn create_vm(prog: &[u8]) -> Result<(EbpfVmRaw, MemoryRegion), Error> { - let mut vm = EbpfVmRaw::new(None)?; +pub fn create_vm(prog: &[u8]) -> Result<(EbpfVm, MemoryRegion), Error> { + let mut vm = EbpfVm::new(None)?; vm.set_verifier(bpf_verifier::check)?; vm.set_max_instruction_count(36000)?; vm.set_elf(&prog)?; @@ -168,7 +166,7 @@ mod tests { use super::*; #[test] - #[should_panic(expected = "Error: Execution exceeded maximum number of instructions")] + #[should_panic(expected = "Error: Exceeded maximum number of instructions allowed")] fn test_non_terminating_program() { #[rustfmt::skip] let prog = &[ @@ -178,7 +176,7 @@ mod tests { ]; let input = &mut [0x00]; - let mut vm = EbpfVmRaw::new(None).unwrap(); + let mut vm = EbpfVm::new(None).unwrap(); vm.set_verifier(bpf_verifier::check).unwrap(); vm.set_max_instruction_count(10).unwrap(); vm.set_program(prog).unwrap(); diff --git a/sdk/bpf/c/inc/solana_sdk.h b/sdk/bpf/c/inc/solana_sdk.h index da2d3396f4..d61e8a344d 100644 --- a/sdk/bpf/c/inc/solana_sdk.h +++ b/sdk/bpf/c/inc/solana_sdk.h @@ -58,18 +58,6 @@ static_assert(sizeof(uint64_t) == 8); #include #endif -/** - * Helper function that prints a string to stdout - */ -void sol_log(const char *); - -/** - * Helper function that prints a 64 bit values represented in hexadecimal - * to stdout - */ -void sol_log_64(uint64_t, uint64_t, uint64_t, uint64_t, uint64_t); - - /** * Prefix for all BPF functions * @@ -78,6 +66,18 @@ void sol_log_64(uint64_t, uint64_t, uint64_t, uint64_t, uint64_t); */ #define SOL_FN_PREFIX __attribute__((always_inline)) static +/** + * Helper function that prints a string to stdout + */ +void sol_log_(const char *, uint64_t); +#define sol_log(message) sol_log_(message, sol_strlen(message)) + +/** + * Helper function that prints a 64 bit values represented in hexadecimal + * to stdout + */ +void sol_log_64(uint64_t, uint64_t, uint64_t, uint64_t, uint64_t); + /** * Size of Public key in bytes */ @@ -175,8 +175,8 @@ SOL_FN_PREFIX size_t sol_strlen(const char *s) { * Prints the line number where the panic occurred and then causes * the BPF VM to immediately halt execution. No accounts' userdata are updated */ -void sol_panic_(const char *, uint64_t, uint64_t); -#define sol_panic() sol_panic_(__FILE__, __LINE__, 0) +void sol_panic_(const char *, uint64_t, uint64_t, uint64_t); +#define sol_panic() sol_panic_(__FILE__, sizeof(__FILE__), __LINE__, 0) /** * Asserts @@ -329,7 +329,7 @@ bool entrypoint(const uint8_t *input); * Stub log functions when building tests */ #include -void sol_log(const char *s) { +void sol_log_(const char *s, uint64_t len) { printf("sol_log: %s\n", s); } void sol_log_64(uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4, uint64_t arg5) { diff --git a/sdk/bpf/rust/rust-no-std/src/panic.rs b/sdk/bpf/rust/rust-no-std/src/panic.rs index aa2ec3b46c..53de3a6640 100644 --- a/sdk/bpf/rust/rust-no-std/src/panic.rs +++ b/sdk/bpf/rust/rust-no-std/src/panic.rs @@ -5,7 +5,7 @@ use core::ptr; #[panic_handler] fn panic(info: &PanicInfo) -> ! { - // Message is ignored for now to avoid incurring formatting program size overhead + // Message is ignored for now to avoid incurring formatting overhead match info.location() { Some(location) => { let mut file: [u8; 128] = [0; 128]; @@ -18,14 +18,15 @@ fn panic(info: &PanicInfo) -> ! { unsafe { sol_panic_( file.as_ptr(), + file.len() as u64, u64::from(location.line()), u64::from(location.column()), ); } } - None => unsafe { sol_panic_(ptr::null(), 0, 0) }, + None => unsafe { sol_panic_(ptr::null(), 0, 0, 0) }, } } extern "C" { - pub fn sol_panic_(file: *const u8, line: u64, column: u64) -> !; + pub fn sol_panic_(file: *const u8, len: u64, line: u64, column: u64) -> !; }