Skip to content

Commit 8603cc6

Browse files
committed
WIP
1 parent 0b6dd5a commit 8603cc6

File tree

8 files changed

+241
-93
lines changed

8 files changed

+241
-93
lines changed

raw_struct/src/builtins/mod.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
mod array;
2-
mod ptr;
1+
// mod array;
2+
// mod ptr;
33

4-
pub use array::{
5-
Array,
6-
SizedArray,
7-
};
8-
pub use ptr::Ptr64;
4+
// pub use array::{
5+
// Array,
6+
// SizedArray,
7+
// };
8+
// pub use ptr::Ptr64;

raw_struct/src/copy.rs

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,26 @@ use core::{
55
};
66

77
use crate::{
8-
view::Viewable,
8+
view::{
9+
SizedViewable,
10+
Viewable,
11+
},
912
ViewableImplementation,
1013
};
1114

15+
#[derive(Clone, Copy)]
16+
pub struct CopiedMemory<M>(M);
17+
1218
/// A Copy represents an owned copy of the struct binary contents
1319
#[repr(transparent)]
14-
pub struct Copy<T: ?Sized + Viewable<T>> {
15-
inner: T::Implementation<T::Memory>,
20+
pub struct Copy<T: ?Sized + SizedViewable + Viewable<CopiedMemory<T::Memory>>> {
21+
inner: T::Implementation,
1622
}
1723

18-
impl<T: ?Sized + Viewable<T>> Copy<T> {
24+
impl<T: ?Sized + SizedViewable + Viewable<CopiedMemory<T::Memory>>> Copy<T> {
1925
pub fn new(inner: T::Memory) -> Self {
2026
Self {
21-
inner: T::create(inner),
27+
inner: T::create(CopiedMemory(inner)),
2228
}
2329
}
2430

@@ -30,18 +36,18 @@ impl<T: ?Sized + Viewable<T>> Copy<T> {
3036
}
3137
}
3238

33-
impl<T: ?Sized + Viewable<T>> Deref for Copy<T> {
34-
type Target = T;
39+
impl<T: ?Sized + SizedViewable + Viewable<CopiedMemory<T::Memory>>> Deref for Copy<T> {
40+
type Target = T::Accessor;
3541

3642
fn deref(&self) -> &Self::Target {
37-
self.inner.as_trait()
43+
self.inner.accessor()
3844
}
3945
}
4046

4147
impl<T> Clone for Copy<T>
4248
where
43-
T: ?Sized + Viewable<T>,
44-
T::Implementation<T::Memory>: Clone,
49+
T: ?Sized + SizedViewable + Viewable<CopiedMemory<T::Memory>>,
50+
T::Implementation: Clone,
4551
{
4652
fn clone(&self) -> Self {
4753
Self {
@@ -52,7 +58,7 @@ where
5258

5359
impl<T> marker::Copy for Copy<T>
5460
where
55-
T: ?Sized + Viewable<T>,
56-
T::Implementation<T::Memory>: marker::Copy,
61+
T: ?Sized + SizedViewable + Viewable<CopiedMemory<T::Memory>>,
62+
T::Implementation: marker::Copy,
5763
{
5864
}

raw_struct/src/error.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,15 @@ impl AccessMode {
2727
}
2828

2929
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
30-
pub struct AccessViolation;
30+
pub struct OutOfBoundsViolation;
3131

32-
impl fmt::Display for AccessViolation {
32+
impl fmt::Display for OutOfBoundsViolation {
3333
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3434
write!(f, "memory outside of the struct has been accessed")
3535
}
3636
}
3737

38-
impl ErrorType for AccessViolation {}
38+
impl ErrorType for OutOfBoundsViolation {}
3939

4040
#[derive(Debug)]
4141
pub struct AccessError {

raw_struct/src/lib.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,30 @@
11
#![cfg_attr(feature = "no_std", no_std)]
2+
#![feature(generic_const_exprs)]
23

34
pub mod builtins;
4-
mod copy;
55
mod error;
66
mod memory;
7-
mod reference;
87
mod view;
98

9+
mod reference;
10+
pub use reference::Reference;
11+
12+
mod copy;
1013
pub use copy::Copy;
1114
pub use error::{
1215
AccessError,
1316
AccessMode,
17+
OutOfBoundsViolation,
1418
};
1519
pub use memory::{
1620
FromMemoryView,
1721
MemoryView,
1822
};
1923
pub use raw_struct_derive::raw_struct;
20-
pub use reference::Reference;
2124
pub use view::{
25+
SizedViewable,
2226
Viewable,
23-
ViewableBase,
27+
ViewableAccessor,
2428
ViewableImplementation,
2529
};
2630

raw_struct/src/memory.rs

Lines changed: 43 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,82 @@
1-
use alloc::boxed::Box;
21
use core::{
2+
convert::Infallible,
33
mem::{
44
self,
55
MaybeUninit,
66
},
77
slice,
88
};
99

10-
use crate::error::{
11-
AccessViolation,
12-
Error,
13-
};
10+
use crate::error::OutOfBoundsViolation;
1411

1512
pub trait MemoryView: Send + Sync {
16-
fn read_memory(&self, offset: u64, buffer: &mut [u8]) -> Result<(), Error>;
13+
type AccessError: 'static;
14+
15+
fn read_memory(&self, offset: u64, buffer: &mut [u8]) -> Result<(), Self::AccessError>;
1716
}
1817

1918
impl<T: Copy + Send + Sync> MemoryView for T {
20-
fn read_memory(&self, offset: u64, buffer: &mut [u8]) -> Result<(), Error> {
19+
type AccessError = OutOfBoundsViolation;
20+
21+
fn read_memory(&self, offset: u64, buffer: &mut [u8]) -> Result<(), Self::AccessError> {
2122
let src_buffer = unsafe {
2223
core::slice::from_raw_parts(self as *const _ as *const u8, core::mem::size_of_val(self))
2324
};
2425

2526
let offset = offset as usize;
2627
if offset + buffer.len() > src_buffer.len() {
27-
return Err(Box::new(AccessViolation));
28+
return Err(OutOfBoundsViolation);
2829
}
2930

3031
buffer.copy_from_slice(&src_buffer[offset..offset + buffer.len()]);
3132
Ok(())
3233
}
3334
}
3435

36+
/// Decode an object from memory view
3537
pub trait FromMemoryView: Sized {
36-
fn read_object(view: &dyn MemoryView, offset: u64) -> Result<Self, Error>;
38+
type DecodeError;
39+
40+
fn read_object<A: 'static>(
41+
view: &dyn MemoryView<AccessError = A>,
42+
offset: u64,
43+
) -> Result<Self, MemoryDecodeError<A, Self::DecodeError>>;
44+
3745
// fn read_boxed(view: &dyn MemoryView, offset: u64) -> Result<Box<Self>, Box<dyn error::ErrorType>>;
3846
}
3947

48+
/// By default all copy traits are decodeable from memory.
49+
// FIXME: Remove this as it's ub for invalid values. Explicitly implement this trait for certain types instead!
4050
impl<T: Copy> FromMemoryView for T {
41-
fn read_object(view: &dyn MemoryView, offset: u64) -> Result<Self, Error> {
51+
type DecodeError = Infallible;
52+
53+
fn read_object<A: 'static>(
54+
view: &dyn MemoryView<AccessError = A>,
55+
offset: u64,
56+
) -> Result<Self, MemoryDecodeError<A, Self::DecodeError>> {
4257
let mut result = MaybeUninit::uninit();
4358
let size = mem::size_of_val(&result);
4459

4560
let buffer = unsafe { slice::from_raw_parts_mut(&mut result as *mut _ as *mut u8, size) };
46-
view.read_memory(offset, buffer)?;
61+
view.read_memory(offset, buffer)
62+
.map_err(MemoryDecodeError::MemoryAccess)?;
4763

4864
Ok(unsafe { result.assume_init() })
4965
}
5066
}
67+
68+
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)]
69+
pub enum MemoryDecodeError<A, V> {
70+
MemoryAccess(A),
71+
ValueDecode(V),
72+
}
73+
74+
mod test {
75+
use crate::memory::FromMemoryView;
76+
77+
fn test_typing() {
78+
let memory = &[0x01u8, 0x00, 0x00, 0x00];
79+
let x = u32::read_object(&memory, 0x00);
80+
assert_eq!(x, Ok(0x01));
81+
}
82+
}

raw_struct/src/reference.rs

Lines changed: 44 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,95 +1,94 @@
11
use alloc::sync::Arc;
22
use core::{
33
self,
4-
marker,
54
ops::Deref,
65
};
76

87
use crate::{
9-
error::{
10-
AccessError,
11-
Error,
12-
},
8+
error::Error,
139
memory::MemoryView,
1410
view::ViewableImplementation,
15-
AccessMode,
16-
Copy,
17-
FromMemoryView,
1811
Viewable,
1912
};
2013

21-
pub struct ReferenceMemory {
14+
pub struct ReferencedMemory<M: ?Sized + MemoryView> {
2215
address: u64,
23-
inner: Arc<dyn MemoryView>,
16+
inner: M,
2417
}
2518

26-
impl ReferenceMemory {
19+
impl<M: ?Sized + MemoryView> ReferencedMemory<M> {
2720
pub fn address(&self) -> u64 {
2821
self.address
2922
}
3023

31-
pub fn memory_view(&self) -> &Arc<dyn MemoryView> {
24+
pub fn memory_view(&self) -> &M {
3225
&self.inner
3326
}
3427
}
3528

36-
impl MemoryView for ReferenceMemory {
37-
fn read_memory(&self, offset: u64, buffer: &mut [u8]) -> Result<(), Error> {
29+
impl<M: ?Sized + MemoryView> MemoryView for ReferencedMemory<M> {
30+
type AccessError = M::AccessError;
31+
32+
fn read_memory(&self, offset: u64, buffer: &mut [u8]) -> Result<(), Self::AccessError> {
3833
self.inner.read_memory(self.address + offset, buffer)
3934
}
4035
}
4136

4237
/// A reference to an object living in the underlying memory view.
43-
pub struct Reference<T: ?Sized + Viewable<T>> {
44-
inner: T::Implementation<ReferenceMemory>,
38+
pub struct Reference<
39+
T: ?Sized + Viewable<ReferencedMemory<M>>,
40+
M: ?Sized + MemoryView = dyn MemoryView<AccessError = Error>,
41+
> {
42+
inner: T::Implementation,
4543
}
4644

47-
impl<T: ?Sized + Viewable<T>> Reference<T> {
48-
pub fn new(memory: Arc<dyn MemoryView>, address: u64) -> Self {
45+
impl<T: ?Sized + Viewable<ReferencedMemory<M>>, M: MemoryView> Reference<T, M> {
46+
pub fn new(memory: M, address: u64) -> Self {
4947
Self {
50-
inner: T::create(ReferenceMemory {
48+
inner: T::create(ReferencedMemory {
5149
address,
5250
inner: memory,
5351
}),
5452
}
5553
}
5654

5755
pub fn reference_address(&self) -> u64 {
58-
T::Implementation::memory(&self.inner).address()
56+
self.inner.memory_view().address()
5957
}
6058

61-
pub fn reference_memory(&self) -> &Arc<dyn MemoryView> {
62-
T::Implementation::memory(&self.inner).memory_view()
59+
pub fn reference_memory(&self) -> &M {
60+
self.inner.memory_view().memory_view()
6361
}
6462

65-
pub fn cast<V: ?Sized + Viewable<V>>(&self) -> Reference<V> {
66-
Reference::<V>::new(self.reference_memory().clone(), self.reference_address())
63+
pub fn cast<V: ?Sized + Viewable<ReferencedMemory<M>>>(&self) -> Reference<V, M> {
64+
todo!()
65+
//Self::new(self.reference_memory().clone(), self.reference_address())
6766
}
6867
}
6968

70-
impl<T: ?Sized + Viewable<T>> Reference<T>
71-
where
72-
T::Implementation<T::Memory>: marker::Copy,
73-
{
74-
pub fn copy(&self) -> Result<Copy<T>, AccessError> {
75-
let memory = self.reference_memory().deref();
76-
Copy::read_object(memory, self.reference_address()).map_err(|err| AccessError {
77-
source: err,
78-
79-
object: T::name(),
80-
member: None,
81-
82-
mode: AccessMode::Read,
83-
offset: self.reference_address(),
84-
size: T::MEMORY_SIZE,
85-
})
86-
}
87-
}
69+
// impl<T: ?Sized + Viewable<T>> Reference<T>
70+
// where
71+
// T::Implementation<T::Memory>: marker::Copy,
72+
// {
73+
// pub fn copy(&self) -> Result<Copy<T>, AccessError> {
74+
// let memory = self.reference_memory().deref();
75+
// Copy::read_object(memory, self.reference_address()).map_err(|err| AccessError {
76+
// source: err,
77+
78+
// object: T::name(),
79+
// member: None,
80+
81+
// mode: AccessMode::Read,
82+
// offset: self.reference_address(),
83+
// size: T::MEMORY_SIZE,
84+
// })
85+
// }
86+
// }
8887

89-
impl<T: Viewable<T> + ?Sized> Deref for Reference<T> {
90-
type Target = T;
88+
impl<T: Viewable<ReferencedMemory<M>> + ?Sized, M: ?Sized + MemoryView> Deref for Reference<T, M> {
89+
type Target = T::Accessor;
9190

9291
fn deref(&self) -> &Self::Target {
93-
self.inner.as_trait()
92+
self.inner.accessor()
9493
}
9594
}

0 commit comments

Comments
 (0)