forked from koniifer/ableos
Moved module
This commit is contained in:
parent
b161d46a5b
commit
5dd0e22c0d
67
hbxrt/src/linux.rs
Normal file
67
hbxrt/src/linux.rs
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
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::<std::fs::File>(
|
||||||
|
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<Path>) -> Result<*mut u8, Box<dyn std::error::Error>> {
|
||||||
|
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 hook_pagefault() -> 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(())
|
||||||
|
}
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#![deny(unsafe_op_in_unsafe_fn)]
|
#![deny(unsafe_op_in_unsafe_fn)]
|
||||||
|
|
||||||
|
mod linux;
|
||||||
mod mem;
|
mod mem;
|
||||||
|
|
||||||
use {
|
use {
|
||||||
|
@ -20,67 +21,18 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Allocate stack
|
// Allocate stack
|
||||||
const STACK_SIZE: usize = 1024 * 1024 * 2;
|
let stack_ptr = unsafe { linux::alloc_stack(1024 * 1024 * 2) }?;
|
||||||
|
|
||||||
let stack_ptr = unsafe {
|
|
||||||
mmap::<std::fs::File>(
|
|
||||||
None,
|
|
||||||
NonZeroUsize::new(STACK_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,
|
|
||||||
)
|
|
||||||
}?;
|
|
||||||
|
|
||||||
eprintln!("[I] Stack allocated at {stack_ptr:p}");
|
eprintln!("[I] Stack allocated at {stack_ptr:p}");
|
||||||
|
|
||||||
// Load program
|
// Load program
|
||||||
eprintln!("[I] Loading image from \"{image_path}\"");
|
eprintln!("[I] Loading image from \"{image_path}\"");
|
||||||
let file = File::open(image_path)?;
|
let ptr = unsafe { linux::mmap_bytecode(image_path) }?;
|
||||||
let ptr = unsafe {
|
|
||||||
mmap(
|
|
||||||
None,
|
|
||||||
NonZeroUsize::new(file.metadata()?.len() as usize).ok_or("File is empty")?,
|
|
||||||
ProtFlags::PROT_READ,
|
|
||||||
MapFlags::MAP_PRIVATE,
|
|
||||||
Some(&file),
|
|
||||||
0,
|
|
||||||
)?
|
|
||||||
};
|
|
||||||
|
|
||||||
eprintln!("[I] Image loaded at {ptr:p}");
|
eprintln!("[I] Image loaded at {ptr:p}");
|
||||||
|
|
||||||
let mut vm = unsafe { Vm::<_, 0>::new(mem::HostMemory, Address::new(ptr as u64)) };
|
let mut vm = unsafe { Vm::<_, 0>::new(mem::HostMemory, Address::new(ptr as u64)) };
|
||||||
vm.write_reg(254, stack_ptr as u64);
|
vm.write_reg(254, stack_ptr as u64);
|
||||||
|
|
||||||
// Memory access fault handling
|
unsafe { linux::hook_pagefault() }?;
|
||||||
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(),
|
|
||||||
),
|
|
||||||
)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Execute program
|
// Execute program
|
||||||
let stat = loop {
|
let stat = loop {
|
||||||
|
|
Loading…
Reference in a new issue