2023-10-18 05:14:24 -05:00
|
|
|
|
//! Holey Bytes Experimental Runtime
|
2023-11-15 12:03:56 -06:00
|
|
|
|
|
|
|
|
|
#![deny(unsafe_op_in_unsafe_fn)]
|
|
|
|
|
|
2023-10-18 05:14:24 -05:00
|
|
|
|
mod mem;
|
|
|
|
|
|
|
|
|
|
use {
|
|
|
|
|
hbvm::{mem::Address, Vm, VmRunOk},
|
2023-11-25 21:13:30 -06:00
|
|
|
|
memmap2::Mmap,
|
2024-02-03 19:46:50 -06:00
|
|
|
|
std::{env::args, fs::File, process::exit},
|
2023-10-18 05:14:24 -05:00
|
|
|
|
};
|
2023-09-26 16:36:27 -05:00
|
|
|
|
|
|
|
|
|
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
2023-11-23 18:09:15 -06:00
|
|
|
|
eprintln!("== HB×RT (Holey Bytes Experimental Runtime) v0.1 ==");
|
2023-10-18 05:14:24 -05:00
|
|
|
|
eprintln!("[W] Currently supporting only flat images");
|
|
|
|
|
|
2024-02-13 18:25:44 -06:00
|
|
|
|
if !hbvm::FL_ARCH_SPECIFIC_SUPPORTED {
|
|
|
|
|
eprintln!(
|
|
|
|
|
"\
|
|
|
|
|
[W] Architecture not fully supported!\n \
|
|
|
|
|
FTI32, FTI64 will yield {:#x}\n \
|
|
|
|
|
FC64T32 will yield NaN\
|
|
|
|
|
",
|
|
|
|
|
i64::MAX,
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-25 21:13:30 -06:00
|
|
|
|
let mut args = args().skip(1);
|
|
|
|
|
let Some(image_path) = args.next() else {
|
2023-10-18 05:14:24 -05:00
|
|
|
|
eprintln!("[E] Missing image path");
|
|
|
|
|
exit(1);
|
|
|
|
|
};
|
|
|
|
|
|
2023-11-25 21:13:30 -06:00
|
|
|
|
let dsls = args.next().as_deref() == Some("-L");
|
|
|
|
|
if cfg!(not(target_os = "linux")) && dsls {
|
|
|
|
|
eprintln!("[E] Unsupported platform for Direct Linux syscall mode");
|
|
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if dsls {
|
|
|
|
|
eprintln!("[I] Direct Linux syscall mode activated")
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-15 12:17:25 -06:00
|
|
|
|
// Allocate stack
|
2024-02-03 19:21:14 -06:00
|
|
|
|
let mut stack = unsafe { mem::alloc_stack() };
|
2023-11-25 21:13:30 -06:00
|
|
|
|
eprintln!("[I] Stack allocated at {:p}", stack.as_ptr());
|
2023-11-15 12:17:25 -06:00
|
|
|
|
|
2023-10-18 05:14:24 -05:00
|
|
|
|
// Load program
|
|
|
|
|
eprintln!("[I] Loading image from \"{image_path}\"");
|
2023-11-25 21:13:30 -06:00
|
|
|
|
let file_handle = File::open(image_path)?;
|
|
|
|
|
let mmap = unsafe { Mmap::map(&file_handle) }?;
|
2023-10-18 05:14:24 -05:00
|
|
|
|
|
2023-11-25 21:13:30 -06:00
|
|
|
|
eprintln!("[I] Image loaded at {:p}", mmap.as_ptr());
|
2023-10-19 17:12:32 -05:00
|
|
|
|
|
2024-05-16 09:54:12 -05:00
|
|
|
|
let mut vm = unsafe {
|
2024-07-08 00:22:53 -05:00
|
|
|
|
Vm::<_, 0>::new(hbvm::mem::HostMemory, Address::new(mmap.as_ptr().add(stack.len()) as u64))
|
2024-05-16 09:54:12 -05:00
|
|
|
|
};
|
2023-11-25 21:13:30 -06:00
|
|
|
|
vm.write_reg(254, stack.as_mut_ptr() as u64);
|
2023-10-19 17:12:32 -05:00
|
|
|
|
|
2023-11-15 12:03:56 -06:00
|
|
|
|
// Execute program
|
2023-10-18 05:14:24 -05:00
|
|
|
|
let stat = loop {
|
|
|
|
|
match vm.run() {
|
2024-07-08 00:22:53 -05:00
|
|
|
|
Ok(VmRunOk::Breakpoint) => {
|
|
|
|
|
eprintln!("[I] Hit breakpoint\nIP: {}\n== Registers ==\n{:?}", vm.pc, vm.registers)
|
|
|
|
|
}
|
2023-10-18 05:14:24 -05:00
|
|
|
|
Ok(VmRunOk::Timer) => (),
|
2023-11-25 21:13:30 -06:00
|
|
|
|
Ok(VmRunOk::Ecall) if dsls => unsafe {
|
2023-10-18 05:14:24 -05:00
|
|
|
|
std::arch::asm!(
|
|
|
|
|
"syscall",
|
|
|
|
|
inlateout("rax") vm.registers[1].0,
|
|
|
|
|
in("rdi") vm.registers[2].0,
|
|
|
|
|
in("rsi") vm.registers[3].0,
|
|
|
|
|
in("rdx") vm.registers[4].0,
|
|
|
|
|
in("r10") vm.registers[5].0,
|
|
|
|
|
in("r8") vm.registers[6].0,
|
|
|
|
|
in("r9") vm.registers[7].0,
|
|
|
|
|
)
|
|
|
|
|
},
|
2023-11-25 21:13:30 -06:00
|
|
|
|
Ok(VmRunOk::Ecall) => {
|
|
|
|
|
eprintln!("[E] General environment calls not supported");
|
|
|
|
|
exit(1);
|
|
|
|
|
}
|
2023-10-18 05:14:24 -05:00
|
|
|
|
Ok(VmRunOk::End) => break Ok(()),
|
|
|
|
|
Err(e) => break Err(e),
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
eprintln!("\n== Registers ==\n{:?}", vm.registers);
|
|
|
|
|
if let Err(e) = stat {
|
|
|
|
|
eprintln!("\n[E] Runtime error: {e:?}");
|
|
|
|
|
exit(2);
|
|
|
|
|
}
|
2023-09-26 16:36:27 -05:00
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|