You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The Mem type is used to model "the x86 memory". In the x86-64 case that means it just conceptually is a slice from address 0 to 2^32. However, it cannot actually be a slice starting at address 0 because Rust doesn't allow this.
I originally introduced this Mem type for a few reasons:
to add the various .get_pod() etc attributes that are used for accessing data at a given address
because in principle if we eventually implement an MMU we'll need to centralize every virtual address access to map it to physical
because I completely break Rust rules around aliasing muts 😬 because lots of things have pointers into mem
However, a better approach (I think?) for (1) is to instead extend slices with these getters, via the memory::Extensions trait I (later) added. So one idea I have for fixing this in general is to say: Mem always only represents "all of memory", get rid of like mem.sub() which returns a sliced Mem subregion in favor of making that return a slice.
One thing to keep in mind is that for MMU reasons, we don't want to have code rely on creating "big" slices. E.g. if we had some code like mem.slice(ofs..) that returned a &[u8] then that would require all memory from ofs forward to be contiguous, which may not be true with an MMU. In particular this pattern comes up when:
reading nul-terminated strings, because we don't know how long to slice until we start reading bytes
PE handling, where many addresses are relative to "the image base"
You can grep the code for _todo() to see all the places this slicing is done. So I think my vague plan is to fix those, then get rid of the .as_slice methods in favor of making mem.sub() return a slice directly.
Finally, regarding the aliasing muts, I think using more .get_pod (copying from memory) and fewer .view_* (creating pointers into memory) methods will reduce aliasing and is generally a better approach because it also avoids alignment problems.
The text was updated successfully, but these errors were encountered:
One big place where aliasing is a problem is if you grab some pointer into memory, mem.view::<Foo>(addr) and then later cause memory to grow (on web for example memory is backed by a Vec that can grow), that invalidates the pointer. However, with an MMU maybe we could handle growing memory differently. And on web it's possible we could put the x86 heap last in memory such that it can always grow without moving. I'm still not sure if it is a good idea to make it possible to invalidate pointers in this way, but so far retrowin32 (painfully) handles it.
evmar
changed the title
Cannot create a slice starting at memory offset 0
Rethink Mem (cannot create a slice starting at memory offset 0)
Jul 26, 2024
The
Mem
type is used to model "the x86 memory". In the x86-64 case that means it just conceptually is a slice from address 0 to 2^32. However, it cannot actually be a slice starting at address 0 because Rust doesn't allow this.I originally introduced this Mem type for a few reasons:
.get_pod()
etc attributes that are used for accessing data at a given addressHowever, a better approach (I think?) for (1) is to instead extend slices with these getters, via the
memory::Extensions
trait I (later) added. So one idea I have for fixing this in general is to say: Mem always only represents "all of memory", get rid of like mem.sub() which returns a sliced Mem subregion in favor of making that return a slice.One thing to keep in mind is that for MMU reasons, we don't want to have code rely on creating "big" slices. E.g. if we had some code like
mem.slice(ofs..)
that returned a&[u8]
then that would require all memory fromofs
forward to be contiguous, which may not be true with an MMU. In particular this pattern comes up when:You can grep the code for
_todo()
to see all the places this slicing is done. So I think my vague plan is to fix those, then get rid of the.as_slice
methods in favor of making mem.sub() return a slice directly.Finally, regarding the aliasing muts, I think using more
.get_pod
(copying from memory) and fewer.view_*
(creating pointers into memory) methods will reduce aliasing and is generally a better approach because it also avoids alignment problems.The text was updated successfully, but these errors were encountered: