diff --git a/Cargo.lock b/Cargo.lock index 6f8b02af..c2318229 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -220,8 +220,7 @@ name = "hbxrt" version = "0.1.0" dependencies = [ "hbvm", - "nix", - "windows", + "memmap2", ] [[package]] @@ -257,6 +256,15 @@ version = "2.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" +[[package]] +name = "memmap2" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "deaba38d7abf1d4cca21cc89e932e542ba2b9258664d2a9ef0e61512039c9375" +dependencies = [ + "libc", +] + [[package]] name = "miniz_oxide" version = "0.7.1" @@ -528,82 +536,6 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" -[[package]] -name = "windows" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" -dependencies = [ - "windows-core", - "windows-targets", -] - -[[package]] -name = "windows-core" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" -dependencies = [ - "windows-targets", -] - -[[package]] -name = "windows-targets" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" -dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" - [[package]] name = "with_builtin_macros" version = "0.0.3" diff --git a/hbxrt/Cargo.toml b/hbxrt/Cargo.toml index c880971e..73c98b7a 100644 --- a/hbxrt/Cargo.toml +++ b/hbxrt/Cargo.toml @@ -6,16 +6,4 @@ default-run = "hbxrt" [dependencies] hbvm.path = "../hbvm" - -[target.'cfg(unix)'.dependencies] -nix = { version = "0.27", features = ["mman", "signal"] } - -[target.'cfg(windows)'.dependencies.windows] -version = "0.52" -features = [ - "Win32_Foundation", - "Win32_System_Memory", - "Win32_System_SystemServices", - "Win32_Security", - "Win32_Storage_FileSystem", -] +memmap2 = "0.9" diff --git a/hbxrt/src/main.rs b/hbxrt/src/main.rs index 07aafe4b..e299c27c 100644 --- a/hbxrt/src/main.rs +++ b/hbxrt/src/main.rs @@ -2,43 +2,50 @@ #![deny(unsafe_op_in_unsafe_fn)] -#[cfg(unix)] -#[path = "unix.rs"] -mod platform; - -#[cfg(windows)] -#[path = "win32.rs"] -mod platform; - +mod eca; mod mem; use { hbvm::{mem::Address, Vm, VmRunOk}, - std::{env::args, process::exit}, + memmap2::Mmap, + std::{env::args, fs::File, io::Read, mem::MaybeUninit, process::exit}, }; +type RtVm = Vm; + fn main() -> Result<(), Box> { eprintln!("== HBĂ—RT (Holey Bytes Experimental Runtime) v0.1 =="); eprintln!("[W] Currently supporting only flat images"); - let Some(image_path) = args().nth(1) else { + let mut args = args().skip(1); + let Some(image_path) = args.next() else { eprintln!("[E] Missing image path"); exit(1); }; + 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") + } + // Allocate stack - let stack_ptr = unsafe { platform::alloc_stack(1024 * 1024 * 2) }?; - eprintln!("[I] Stack allocated at {stack_ptr:p}"); + let mut stack = Box::new(MaybeUninit::<[u8; 1024 * 1024 * 2]>::uninit()); + eprintln!("[I] Stack allocated at {:p}", stack.as_ptr()); // Load program eprintln!("[I] Loading image from \"{image_path}\""); - let ptr = unsafe { platform::mmap_bytecode(image_path) }?; - eprintln!("[I] Image loaded at {ptr:p}"); + let file_handle = File::open(image_path)?; + let mmap = unsafe { Mmap::map(&file_handle) }?; - let mut vm = unsafe { Vm::<_, 0>::new(mem::HostMemory, Address::new(ptr as u64)) }; - vm.write_reg(254, stack_ptr as u64); + eprintln!("[I] Image loaded at {:p}", mmap.as_ptr()); - unsafe { platform::catch_mafs() }?; + let mut vm = unsafe { Vm::<_, 0>::new(mem::HostMemory, Address::new(mmap.as_ptr() as u64)) }; + vm.write_reg(254, stack.as_mut_ptr() as u64); // Execute program let stat = loop { @@ -48,7 +55,7 @@ fn main() -> Result<(), Box> { vm.pc, vm.registers ), Ok(VmRunOk::Timer) => (), - Ok(VmRunOk::Ecall) => unsafe { + Ok(VmRunOk::Ecall) if dsls => unsafe { std::arch::asm!( "syscall", inlateout("rax") vm.registers[1].0, @@ -60,6 +67,10 @@ fn main() -> Result<(), Box> { in("r9") vm.registers[7].0, ) }, + Ok(VmRunOk::Ecall) => { + eprintln!("[E] General environment calls not supported"); + exit(1); + } Ok(VmRunOk::End) => break Ok(()), Err(e) => break Err(e), } diff --git a/hbxrt/src/unix.rs b/hbxrt/src/unix.rs deleted file mode 100644 index 419d014f..00000000 --- a/hbxrt/src/unix.rs +++ /dev/null @@ -1,67 +0,0 @@ -use { - nix::sys::mman::{mmap, MapFlags, ProtFlags}, - std::{fs::File, num::NonZeroUsize, path::Path, process::exit}, -}; - -/// Allocate stack for program -pub unsafe fn alloc_stack(size: usize) -> nix::Result<*mut u8> { - unsafe { - Ok(mmap::( - None, - NonZeroUsize::new(size).expect("Stack size should be > 0"), - ProtFlags::PROT_GROWSDOWN | ProtFlags::PROT_READ | ProtFlags::PROT_WRITE, - MapFlags::MAP_GROWSDOWN - | MapFlags::MAP_STACK - | MapFlags::MAP_ANON - | MapFlags::MAP_PRIVATE, - None, - 0, - )? - .cast()) - } -} - -/// Memory map bytecode -pub unsafe fn mmap_bytecode(path: impl AsRef) -> Result<*mut u8, Box> { - let file = File::open(&path)?; - Ok(unsafe { - mmap( - None, - NonZeroUsize::new(file.metadata()?.len() as usize).ok_or("File is empty")?, - ProtFlags::PROT_READ, - MapFlags::MAP_PRIVATE, - Some(&file), - 0, - )? - .cast() - }) -} - -/// Set handler for page fault -pub unsafe fn catch_mafs() -> nix::Result<()> { - unsafe { - use nix::sys::signal; - - extern "C" fn action( - _: std::ffi::c_int, - info: *mut nix::libc::siginfo_t, - _: *mut std::ffi::c_void, - ) { - unsafe { - eprintln!("[E] Memory access fault at {:p}", (*info).si_addr()); - exit(2); - } - } - - signal::sigaction( - signal::Signal::SIGSEGV, - &nix::sys::signal::SigAction::new( - signal::SigHandler::SigAction(action), - signal::SaFlags::SA_NODEFER, - nix::sys::signalfd::SigSet::empty(), - ), - )?; - } - - Ok(()) -} diff --git a/hbxrt/src/win32.rs b/hbxrt/src/win32.rs deleted file mode 100644 index 516b4a52..00000000 --- a/hbxrt/src/win32.rs +++ /dev/null @@ -1,69 +0,0 @@ -use { - std::path::Path, - windows::{ - core::PCSTR, - Win32::{ - Foundation::{GetLastError, GENERIC_READ}, - Storage::FileSystem, - System::{ - Memory::{self}, - SystemServices::{self}, - }, - }, - }, -}; - -/// Allocates tack for the program -pub unsafe fn alloc_stack(size: usize) -> windows::core::Result<*mut u8> { - let ptr = unsafe { - Memory::VirtualAlloc( - None, - size, - Memory::VIRTUAL_ALLOCATION_TYPE(SystemServices::MEM_TOP_DOWN) | Memory::MEM_COMMIT, - Memory::PAGE_READWRITE, - ) - }; - - if ptr.is_null() { - unsafe { GetLastError() }?; - } - - Ok(ptr.cast()) -} - -/// Memory map bytecode -pub unsafe fn mmap_bytecode(path: impl AsRef) -> windows::core::Result<*mut u8> { - unsafe { - let file = FileSystem::CreateFileA( - PCSTR(path.as_ref().as_os_str().as_encoded_bytes().as_ptr()), - GENERIC_READ.0, - FileSystem::FILE_SHARE_READ, - None, - FileSystem::OPEN_EXISTING, - FileSystem::FILE_ATTRIBUTE_NORMAL, - None, - )?; - - let h = Memory::CreateFileMappingA( - file, - None, - Memory::PAGE_READONLY, - 0, - 0, - PCSTR("Bytecode\0".as_ptr()), - )?; - - let addr = Memory::MapViewOfFile(h, Memory::FILE_MAP_READ, 0, 0, 0); - - if addr.Value.is_null() { - GetLastError()?; - } - - Ok(addr.Value.cast()) - } -} - -/// Catch memory access faults -pub unsafe fn catch_mafs() -> std::io::Result<()> { - Ok(()) -} diff --git a/program.hbf b/program.hbf new file mode 100644 index 00000000..cf79efc8 Binary files /dev/null and b/program.hbf differ diff --git a/test.hba b/test.hba new file mode 100644 index 00000000..f5192477 --- /dev/null +++ b/test.hba @@ -0,0 +1,9 @@ +let hello = data::str("Hello, world!"); + +li8(r1, 6); +li8(r2, 10); +lra16(r3, r0, hello); +li8(r4, hello.len); + +eca(); +tx(); \ No newline at end of file