This commit is contained in:
Erin 2023-06-11 13:47:33 +02:00 committed by ondra05
parent 2e6e6b7939
commit c873945681
4 changed files with 64 additions and 67 deletions

35
Cargo.lock generated
View file

@ -29,12 +29,6 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
name = "compiler" name = "compiler"
version = "0.1.0" version = "0.1.0"
[[package]]
name = "convert_case"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e"
[[package]] [[package]]
name = "delegate" name = "delegate"
version = "0.9.0" version = "0.9.0"
@ -46,19 +40,6 @@ dependencies = [
"syn 1.0.109", "syn 1.0.109",
] ]
[[package]]
name = "derive_more"
version = "0.99.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321"
dependencies = [
"convert_case",
"proc-macro2",
"quote",
"rustc_version",
"syn 1.0.109",
]
[[package]] [[package]]
name = "fnv" name = "fnv"
version = "1.0.7" version = "1.0.7"
@ -93,7 +74,6 @@ name = "hbvm"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"delegate", "delegate",
"derive_more",
"hashbrown", "hashbrown",
"hbbytecode", "hbbytecode",
"log", "log",
@ -186,21 +166,6 @@ version = "0.6.29"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
[[package]]
name = "rustc_version"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
dependencies = [
"semver",
]
[[package]]
name = "semver"
version = "1.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed"
[[package]] [[package]]
name = "static_assertions" name = "static_assertions"
version = "1.1.0" version = "1.1.0"

View file

@ -8,7 +8,6 @@ lto = true
[dependencies] [dependencies]
delegate = "0.9" delegate = "0.9"
derive_more = "0.99"
hashbrown = "0.13" hashbrown = "0.13"
hbbytecode.path = "../hbbytecode" hbbytecode.path = "../hbbytecode"
log = "0.4" log = "0.4"

View file

@ -57,6 +57,49 @@ impl Memory {
/// Load value from an address /// Load value from an address
pub fn load<S: MemAccessSize>(&self, addr: u64) -> Option<Value> { pub fn load<S: MemAccessSize>(&self, addr: u64) -> Option<Value> {
let lookup = self.page_lookup(addr)?;
match lookup.perm {
Permission::Empty | Permission::Node => None,
Permission::Readonly | Permission::Write | Permission::Exec => {
let mut value = MaybeUninit::<Value>::zeroed();
unsafe {
core::ptr::copy_nonoverlapping::<u8>(lookup.ptr, value.as_mut_ptr().cast(), 1);
Some(value.assume_init())
}
}
}
}
/// Store value to an address
pub fn store<S: MemAccessSize>(&mut self, addr: u64, value: Value) -> Result<(), ()> {
let lookup = self.page_lookup(addr).ok_or(())?;
match lookup.perm {
Permission::Write => {
unsafe {
core::ptr::copy_nonoverlapping::<u8>(
(&value as *const Value).cast(),
lookup.ptr,
1,
)
};
Ok(())
}
_ => Err(()),
}
}
#[inline]
pub fn root_pt(&self) -> &PageTable {
unsafe { &*self.root_pt }
}
#[inline]
pub fn root_pt_mut(&mut self) -> &mut PageTable {
unsafe { &mut *self.root_pt }
}
/// Resolve page and offset from the page
fn page_lookup(&self, addr: u64) -> Option<PageLookupResult> {
let mut current_pt = self.root_pt; let mut current_pt = self.root_pt;
for lvl in (0..5).rev() { for lvl in (0..5).rev() {
unsafe { unsafe {
@ -69,36 +112,32 @@ impl Memory {
match entry.permission() { match entry.permission() {
Permission::Empty => return None, Permission::Empty => return None,
Permission::Node => current_pt = ptr as _, Permission::Node => current_pt = ptr as _,
Permission::Readonly | Permission::Write | Permission::Exec => { _ if lvl > 2 => return None,
let mut value = MaybeUninit::<Value>::zeroed(); perm => {
core::ptr::copy_nonoverlapping::<u8>( return Some(PageLookupResult {
entry.ptr() as _, perm,
value.as_mut_ptr().cast(), ptr: ptr as _,
1, size: match lvl {
); 0 => 4096,
return Some(value.assume_init()); 1 => 1024_usize.pow(2) * 2,
2 => 4096_usize.pow(3),
_ => unreachable!(),
},
offset: addr as usize & ((1 << 12) - 1),
})
} }
} }
} }
} }
None None
} }
}
/// Store value to an address struct PageLookupResult {
pub fn store<S: MemAccessSize>(&mut self, addr: u64, value: Value) -> Result<(), ()> { perm: Permission,
Err(()) ptr: *mut u8,
} size: usize,
offset: usize,
#[inline]
pub fn root_pt(&self) -> &PageTable {
unsafe { &*self.root_pt }
}
#[inline]
pub fn root_pt_mut(&mut self) -> &mut PageTable {
unsafe { &mut *self.root_pt }
}
} }
macro_rules! size_markers { macro_rules! size_markers {

View file

@ -5,7 +5,6 @@ use core::{
slice::SliceIndex, slice::SliceIndex,
}; };
use delegate::delegate; use delegate::delegate;
use derive_more::{Deref, DerefMut};
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)] #[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
#[repr(u8)] #[repr(u8)]
@ -94,14 +93,9 @@ impl Default for PageTable {
} }
} }
/// This byte is special. It has a whole page reserved just for it.
#[derive(Clone, Copy, PartialEq, Eq, Deref, DerefMut)]
#[repr(align(4096))]
pub struct SpecialByte(u8);
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
#[repr(C)] #[repr(C, align(4096))]
pub union PtPointedData { pub union PtPointedData {
pub pt: PageTable, pub pt: PageTable,
pub page: SpecialByte, pub page: u8,
} }