extern crate solana_rbpf;
use solana_rbpf::{
elf::Executable,
syscalls,
user_error::UserError,
vm::{Config, EbpfVm, SyscallObject, SyscallRegistry, TestInstructionMeter},
};
use std::collections::BTreeMap;
fn main() {
let prog1 = &[
0xb4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0c, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ];
let hkey = syscalls::BPF_KTIME_GETNS_IDX as u8;
let prog2 = &[
0xb7, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb7, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb7, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb7, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb7, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, hkey, 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ];
let executable = Executable::<UserError, TestInstructionMeter>::from_text_bytes(
prog1,
None,
Config::default(),
SyscallRegistry::default(),
BTreeMap::default(),
)
.unwrap();
let mut vm =
EbpfVm::<UserError, TestInstructionMeter>::new(&executable, &mut [], &mut []).unwrap();
assert_eq!(
vm.execute_program_interpreted(&mut TestInstructionMeter { remaining: 5 })
.unwrap(),
0x3
);
let mut syscall_registry = SyscallRegistry::default();
syscall_registry
.register_syscall_by_hash::<UserError, _>(
syscalls::BPF_KTIME_GETNS_IDX,
syscalls::BpfTimeGetNs::call,
)
.unwrap();
#[allow(unused_mut)]
let mut executable = Executable::<UserError, TestInstructionMeter>::from_text_bytes(
prog2,
None,
Config::default(),
syscall_registry,
BTreeMap::default(),
)
.unwrap();
#[cfg(not(windows))]
{
executable.jit_compile().unwrap();
}
let mut vm =
EbpfVm::<UserError, TestInstructionMeter>::new(&executable, &mut [], &mut []).unwrap();
vm.bind_syscall_context_object(Box::new(syscalls::BpfTimeGetNs {}), None)
.unwrap();
let time;
#[cfg(not(windows))]
{
time = vm
.execute_program_jit(&mut TestInstructionMeter { remaining: 7 })
.unwrap();
}
#[cfg(windows)]
{
time = vm
.execute_program_interpreted(&mut TestInstructionMeter { remaining: 7 })
.unwrap();
}
let days = time / 10u64.pow(9) / 60 / 60 / 24;
let hours = (time / 10u64.pow(9) / 60 / 60) % 24;
let minutes = (time / 10u64.pow(9) / 60) % 60;
let seconds = (time / 10u64.pow(9)) % 60;
let nanosec = time % 10u64.pow(9);
println!(
"Uptime: {:#x} ns == {} days {:02}:{:02}:{:02}, {} ns",
time, days, hours, minutes, seconds, nanosec
);
}