diff --git a/programs/bpf/rust/128bit/src/lib.rs b/programs/bpf/rust/128bit/src/lib.rs index e034b33ece..8e395103fa 100644 --- a/programs/bpf/rust/128bit/src/lib.rs +++ b/programs/bpf/rust/128bit/src/lib.rs @@ -1,7 +1,7 @@ //! @brief Example Rust-based BPF program tests loop iteration extern crate solana_program; -use solana_program::entrypoint::SUCCESS; +use solana_program::{custom_panic_default, entrypoint::SUCCESS}; #[no_mangle] pub extern "C" fn entrypoint(_input: *mut u8) -> u64 { @@ -50,6 +50,8 @@ pub extern "C" fn entrypoint(_input: *mut u8) -> u64 { SUCCESS } +custom_panic_default!(); + #[cfg(test)] mod test { use super::*; diff --git a/programs/bpf/rust/alloc/src/lib.rs b/programs/bpf/rust/alloc/src/lib.rs index e735c9b39b..1df03a1cf8 100644 --- a/programs/bpf/rust/alloc/src/lib.rs +++ b/programs/bpf/rust/alloc/src/lib.rs @@ -2,7 +2,7 @@ #[macro_use] extern crate alloc; -use solana_program::{entrypoint::SUCCESS, msg}; +use solana_program::{custom_panic_default, entrypoint::SUCCESS, msg}; use std::{alloc::Layout, mem}; #[no_mangle] @@ -81,6 +81,8 @@ pub extern "C" fn entrypoint(_input: *mut u8) -> u64 { SUCCESS } +custom_panic_default!(); + #[cfg(test)] mod test { use super::*; diff --git a/programs/bpf/rust/call_depth/src/lib.rs b/programs/bpf/rust/call_depth/src/lib.rs index 562731a69f..f5ec2168a9 100644 --- a/programs/bpf/rust/call_depth/src/lib.rs +++ b/programs/bpf/rust/call_depth/src/lib.rs @@ -1,6 +1,6 @@ //! @brief Example Rust-based BPF program that tests call depth and stack usage -use solana_program::{entrypoint::SUCCESS, msg}; +use solana_program::{custom_panic_default, entrypoint::SUCCESS, msg}; #[inline(never)] pub fn recurse(data: &mut [u8]) { @@ -25,3 +25,5 @@ pub unsafe extern "C" fn entrypoint(input: *mut u8) -> u64 { recurse(&mut data); SUCCESS } + +custom_panic_default!(); diff --git a/programs/bpf/rust/deprecated_loader/src/lib.rs b/programs/bpf/rust/deprecated_loader/src/lib.rs index 0201cce929..a0f03e46c3 100644 --- a/programs/bpf/rust/deprecated_loader/src/lib.rs +++ b/programs/bpf/rust/deprecated_loader/src/lib.rs @@ -20,6 +20,12 @@ fn return_sstruct() -> SStruct { SStruct { x: 1, y: 2, z: 3 } } +#[no_mangle] +fn custom_panic(info: &core::panic::PanicInfo<'_>) { + // Full panic reporting + msg!(&format!("{}", info)); +} + entrypoint_deprecated!(process_instruction); fn process_instruction( program_id: &Pubkey, diff --git a/programs/bpf/rust/iter/src/lib.rs b/programs/bpf/rust/iter/src/lib.rs index 3eec536b2b..efa9825f26 100644 --- a/programs/bpf/rust/iter/src/lib.rs +++ b/programs/bpf/rust/iter/src/lib.rs @@ -1,7 +1,7 @@ //! @brief Example Rust-based BPF program tests loop iteration extern crate solana_program; -use solana_program::{entrypoint::SUCCESS, msg}; +use solana_program::{custom_panic_default, entrypoint::SUCCESS, msg}; #[no_mangle] pub extern "C" fn entrypoint(_input: *mut u8) -> u64 { @@ -18,6 +18,8 @@ pub extern "C" fn entrypoint(_input: *mut u8) -> u64 { SUCCESS } +custom_panic_default!(); + #[cfg(test)] mod test { use super::*; diff --git a/programs/bpf/rust/many_args/src/lib.rs b/programs/bpf/rust/many_args/src/lib.rs index 39de05eadf..2cf8f37501 100644 --- a/programs/bpf/rust/many_args/src/lib.rs +++ b/programs/bpf/rust/many_args/src/lib.rs @@ -2,7 +2,7 @@ mod helper; extern crate solana_program; -use solana_program::{entrypoint::SUCCESS, msg}; +use solana_program::{custom_panic_default, entrypoint::SUCCESS, msg}; #[no_mangle] pub extern "C" fn entrypoint(_input: *mut u8) -> u64 { @@ -26,6 +26,8 @@ pub extern "C" fn entrypoint(_input: *mut u8) -> u64 { SUCCESS } +custom_panic_default!(); + #[cfg(test)] mod test { use super::*; diff --git a/programs/bpf/rust/mem/src/lib.rs b/programs/bpf/rust/mem/src/lib.rs index fe08f6e03e..860ff16a24 100644 --- a/programs/bpf/rust/mem/src/lib.rs +++ b/programs/bpf/rust/mem/src/lib.rs @@ -4,7 +4,7 @@ #![feature(compiler_builtins_lib)] extern crate compiler_builtins; -use solana_program::entrypoint::SUCCESS; +use solana_program::{custom_panic_default, entrypoint::SUCCESS, info}; #[no_mangle] pub extern "C" fn entrypoint(_input: *mut u8) -> u64 { @@ -183,3 +183,5 @@ pub extern "C" fn entrypoint(_input: *mut u8) -> u64 { SUCCESS } + +custom_panic_default!(); diff --git a/programs/bpf/rust/param_passing/src/lib.rs b/programs/bpf/rust/param_passing/src/lib.rs index 5c38fd76c7..9d1002d92b 100644 --- a/programs/bpf/rust/param_passing/src/lib.rs +++ b/programs/bpf/rust/param_passing/src/lib.rs @@ -2,7 +2,7 @@ extern crate solana_program; use solana_bpf_rust_param_passing_dep::{Data, TestDep}; -use solana_program::{entrypoint::SUCCESS, msg}; +use solana_program::{custom_panic_default, entrypoint::SUCCESS, msg}; #[no_mangle] pub extern "C" fn entrypoint(_input: *mut u8) -> u64 { @@ -23,6 +23,8 @@ pub extern "C" fn entrypoint(_input: *mut u8) -> u64 { SUCCESS } +custom_panic_default!(); + #[cfg(test)] mod test { use super::*; diff --git a/programs/bpf/rust/sha256/src/lib.rs b/programs/bpf/rust/sha256/src/lib.rs index c215050a5f..fc5c55b3e6 100644 --- a/programs/bpf/rust/sha256/src/lib.rs +++ b/programs/bpf/rust/sha256/src/lib.rs @@ -2,6 +2,7 @@ extern crate solana_program; use solana_program::{ + custom_panic_default, hash::{hashv, Hasher}, msg, }; @@ -22,6 +23,8 @@ pub extern "C" fn entrypoint(_input: *mut u8) -> u64 { 0 } +custom_panic_default!(); + #[cfg(test)] mod test { use super::*; diff --git a/programs/bpf/tests/programs.rs b/programs/bpf/tests/programs.rs index 529f2deea4..f5e25e7c48 100644 --- a/programs/bpf/tests/programs.rs +++ b/programs/bpf/tests/programs.rs @@ -897,9 +897,9 @@ fn assert_instruction_count() { { programs.extend_from_slice(&[ ("solana_bpf_rust_128bit", 572), - ("solana_bpf_rust_alloc", 12777), + ("solana_bpf_rust_alloc", 12919), ("solana_bpf_rust_dep_crate", 2), - ("solana_bpf_rust_external_spend", 538), + ("solana_bpf_rust_external_spend", 514), ("solana_bpf_rust_iter", 724), ("solana_bpf_rust_many_args", 237), ("solana_bpf_rust_noop", 488), diff --git a/sdk/program/src/entrypoint.rs b/sdk/program/src/entrypoint.rs index 6c502b7cee..44664a9e1f 100644 --- a/sdk/program/src/entrypoint.rs +++ b/sdk/program/src/entrypoint.rs @@ -38,23 +38,49 @@ pub const HEAP_LENGTH: usize = 32 * 1024; /// Deserialize the program input arguments and call the user defined /// `process_instruction` function. Users must call this macro otherwise an /// entry point for their program will not be created. -/// -/// If the program defines the feature `custom-heap` then the default heap -/// implementation will not be included and the program is free to implement -/// their own `#[global_allocator]` #[macro_export] macro_rules! entrypoint { ($process_instruction:ident) => { + /// # Safety + #[no_mangle] + pub unsafe extern "C" fn entrypoint(input: *mut u8) -> u64 { + let (program_id, accounts, instruction_data) = + unsafe { $crate::entrypoint::deserialize(input) }; + match $process_instruction(&program_id, &accounts, &instruction_data) { + Ok(()) => $crate::entrypoint::SUCCESS, + Err(error) => error.into(), + } + } + $crate::custom_heap_default!(); + $crate::custom_panic_default!(); + }; +} + +/// Fallback to default for unused custom heap feature. +#[macro_export] +macro_rules! custom_heap_default { + () => { /// A program can provide their own custom heap implementation by adding /// a `custom-heap` feature to `Cargo.toml` and implementing their own /// `global_allocator`. + /// + /// If the program defines the feature `custom-heap` then the default heap + /// implementation will not be included and the program is free to implement + /// their own `#[global_allocator]` #[cfg(all(not(feature = "custom-heap"), target_arch = "bpf"))] #[global_allocator] static A: $crate::entrypoint::BumpAllocator = $crate::entrypoint::BumpAllocator { start: $crate::entrypoint::HEAP_START_ADDRESS, len: $crate::entrypoint::HEAP_LENGTH, }; + }; +} +/// Fallback to default for unused custom panic feature. +/// This must be used if the entrypoint! macro is not used. +#[macro_export] +macro_rules! custom_panic_default { + () => { /// A program can provide their own custom panic implementation by /// adding a `custom-panic` feature to `Cargo.toml` and implementing /// their own `custom_panic`. @@ -69,17 +95,6 @@ macro_rules! entrypoint { // Full panic reporting $crate::msg!("{}", info); } - - /// # Safety - #[no_mangle] - pub unsafe extern "C" fn entrypoint(input: *mut u8) -> u64 { - let (program_id, accounts, instruction_data) = - unsafe { $crate::entrypoint::deserialize(input) }; - match $process_instruction(&program_id, &accounts, &instruction_data) { - Ok(()) => $crate::entrypoint::SUCCESS, - Err(error) => error.into(), - } - } }; }