* Add solana-program-sdk boilerplate (cherry picked from commit3718771ffb
) # Conflicts: # sdk/Cargo.toml * Initial population of solana-program-sdk (cherry picked from commit63db324204
) # Conflicts: # Cargo.lock * Port programs to solana-program-sdk (cherry picked from commitfe68f7f786
) # Conflicts: # programs/bpf/Cargo.lock # programs/bpf/rust/128bit/Cargo.toml # programs/bpf/rust/128bit_dep/Cargo.toml # programs/bpf/rust/alloc/Cargo.toml # programs/bpf/rust/call_depth/Cargo.toml # programs/bpf/rust/custom_heap/Cargo.toml # programs/bpf/rust/dep_crate/Cargo.toml # programs/bpf/rust/deprecated_loader/Cargo.toml # programs/bpf/rust/dup_accounts/Cargo.toml # programs/bpf/rust/error_handling/Cargo.toml # programs/bpf/rust/external_spend/Cargo.toml # programs/bpf/rust/instruction_introspection/Cargo.toml # programs/bpf/rust/invoke/Cargo.toml # programs/bpf/rust/invoked/Cargo.toml # programs/bpf/rust/iter/Cargo.toml # programs/bpf/rust/many_args/Cargo.toml # programs/bpf/rust/many_args_dep/Cargo.toml # programs/bpf/rust/noop/Cargo.toml # programs/bpf/rust/panic/Cargo.toml # programs/bpf/rust/param_passing/Cargo.toml # programs/bpf/rust/param_passing_dep/Cargo.toml # programs/bpf/rust/rand/Cargo.toml # programs/bpf/rust/ristretto/Cargo.toml # programs/bpf/rust/sanity/Cargo.toml # programs/bpf/rust/sha256/Cargo.toml # programs/bpf/rust/sysval/Cargo.toml * Only activate legacy program feature for the solana-sdk crate (cherry picked from commit85c51f5787
) * Run serum-dex unit tests (cherry picked from commit92ce381d60
) * Rename solana-program-sdk to solana-program (cherry picked from commitdd711ab5fb
) # Conflicts: # programs/bpf/rust/128bit/Cargo.toml # programs/bpf/rust/128bit_dep/Cargo.toml # programs/bpf/rust/alloc/Cargo.toml # programs/bpf/rust/call_depth/Cargo.toml # programs/bpf/rust/custom_heap/Cargo.toml # programs/bpf/rust/dep_crate/Cargo.toml # programs/bpf/rust/deprecated_loader/Cargo.toml # programs/bpf/rust/dup_accounts/Cargo.toml # programs/bpf/rust/error_handling/Cargo.toml # programs/bpf/rust/external_spend/Cargo.toml # programs/bpf/rust/instruction_introspection/Cargo.toml # programs/bpf/rust/invoke/Cargo.toml # programs/bpf/rust/invoked/Cargo.toml # programs/bpf/rust/iter/Cargo.toml # programs/bpf/rust/many_args/Cargo.toml # programs/bpf/rust/many_args_dep/Cargo.toml # programs/bpf/rust/noop/Cargo.toml # programs/bpf/rust/panic/Cargo.toml # programs/bpf/rust/param_passing/Cargo.toml # programs/bpf/rust/param_passing_dep/Cargo.toml # programs/bpf/rust/rand/Cargo.toml # programs/bpf/rust/ristretto/Cargo.toml # programs/bpf/rust/sanity/Cargo.toml # programs/bpf/rust/sha256/Cargo.toml # programs/bpf/rust/sysval/Cargo.toml * Update frozen_abi hashes The movement of files in sdk/ caused ABI hashes to change (cherry picked from commita4956844bd
) * Resolve merge conflicts Co-authored-by: Michael Vines <mvines@gmail.com>
69 lines
2.0 KiB
Rust
69 lines
2.0 KiB
Rust
//! @brief Example Rust-based BPF that tests out using a custom heap
|
|
|
|
use solana_program::{
|
|
account_info::AccountInfo,
|
|
entrypoint,
|
|
entrypoint::{ProgramResult, HEAP_LENGTH, HEAP_START_ADDRESS},
|
|
info,
|
|
pubkey::Pubkey,
|
|
};
|
|
use std::{
|
|
alloc::{alloc, Layout},
|
|
mem::{align_of, size_of},
|
|
ptr::null_mut,
|
|
usize,
|
|
};
|
|
|
|
/// Developers can implement their own heap by defining their own
|
|
/// `#[global_allocator]`. The following implements a dummy for test purposes
|
|
/// but can be flushed out with whatever the developer sees fit.
|
|
struct BumpAllocator;
|
|
unsafe impl std::alloc::GlobalAlloc for BumpAllocator {
|
|
#[inline]
|
|
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
|
|
if layout.size() == usize::MAX - 0x42 {
|
|
// Return test value
|
|
0x42 as *mut u8
|
|
} else {
|
|
const POS_PTR: *mut usize = HEAP_START_ADDRESS as *mut usize;
|
|
const TOP_ADDRESS: usize = HEAP_START_ADDRESS + HEAP_LENGTH;
|
|
const BOTTOM_ADDRESS: usize = HEAP_START_ADDRESS + size_of::<*mut u8>();
|
|
|
|
let mut pos = *POS_PTR;
|
|
if pos == 0 {
|
|
// First time, set starting position
|
|
pos = TOP_ADDRESS;
|
|
}
|
|
pos = pos.saturating_sub(layout.size());
|
|
pos &= !(layout.align().saturating_sub(1));
|
|
if pos < BOTTOM_ADDRESS {
|
|
return null_mut();
|
|
}
|
|
*POS_PTR = pos;
|
|
pos as *mut u8
|
|
}
|
|
}
|
|
#[inline]
|
|
unsafe fn dealloc(&self, _: *mut u8, _: Layout) {
|
|
// I'm a bump allocator, I don't free
|
|
}
|
|
}
|
|
#[cfg(not(test))]
|
|
#[global_allocator]
|
|
static A: BumpAllocator = BumpAllocator;
|
|
|
|
entrypoint!(process_instruction);
|
|
fn process_instruction(
|
|
_program_id: &Pubkey,
|
|
_accounts: &[AccountInfo],
|
|
_instruction_data: &[u8],
|
|
) -> ProgramResult {
|
|
info!("Custom heap");
|
|
unsafe {
|
|
let layout = Layout::from_size_align(usize::MAX - 0x42, align_of::<u8>()).unwrap();
|
|
let ptr = alloc(layout);
|
|
assert_eq!(ptr as u64, 0x42);
|
|
}
|
|
Ok(())
|
|
}
|