mm: add flags to map_memory

This commit is contained in:
Mark Poliakov 2024-11-14 16:24:45 +02:00
parent c65b06fadb
commit 6dc77143b0
11 changed files with 56 additions and 18 deletions

View File

@ -4,7 +4,7 @@ pub(crate) use abi::{
DirectoryEntry, FileAttr, FileMode, MountOptions, OpenOptions, PipeOptions, PollControl,
RawFd, TerminalOptions, TerminalSize, TimerOptions, UnmountOptions,
},
mem::MappingSource,
mem::{MappingFlags, MappingSource},
net::SocketType,
process::{Signal, SignalEntryData, SpawnOptions},
system::SystemInfo,

View File

@ -3,7 +3,7 @@ use core::{num::NonZeroUsize, sync::atomic::AtomicU32, time::Duration};
use abi::{
error::Error,
io::DeviceRequest,
mem::MappingSource,
mem::{MappingFlags, MappingSource},
process::{
ExitCode, MutexOperation, ProcessGroupId, ProcessId, Signal, SpawnFlags, SpawnOption,
SpawnOptions, ThreadSpawnOptions,
@ -29,6 +29,7 @@ use crate::{arch::L3, proc, syscall::run_with_io, util::IteratorExt};
pub(crate) fn map_memory(
_hint: Option<NonZeroUsize>,
len: usize,
flags: MappingFlags,
source: &MappingSource,
) -> Result<usize, Error> {
let thread = Thread::current();

View File

@ -43,6 +43,15 @@ enum SocketType(u32) {
UdpPacket = 2,
}
// abi::mem
bitfield MappingFlags(u32) {
/// Process write access
WRITE: 0,
/// Executable access
EXEC: 1,
}
// TODO allow splitting types into separate modules
syscall get_random(buffer: &mut [u8]);
@ -52,7 +61,12 @@ syscall unmount(opts: &UnmountOptions) -> Result<()>;
syscall load_module(path: &str) -> Result<()>;
// Memory management
syscall map_memory(hint: Option<NonZeroUsize>, len: usize, source: &MappingSource) -> Result<usize>;
syscall map_memory(
hint: Option<NonZeroUsize>,
len: usize,
flags: MappingFlags,
source: &MappingSource
) -> Result<usize>;
syscall unmap_memory(address: usize, len: usize) -> Result<()>;
// Process/thread management

View File

@ -2,6 +2,8 @@
use crate::io::RawFd;
pub use crate::generated::MappingFlags;
/// Defines the MapMemory function
#[derive(Clone, Copy, Debug)]
pub enum MappingSource {

View File

@ -39,10 +39,15 @@ impl PageProvider for OsPageProvider {
#[cfg(any(all(not(unix), not(feature = "dep-of-kernel")), rust_analyzer))]
impl PageProvider for OsPageProvider {
fn map_pages(count: usize) -> Option<NonNull<u8>> {
use yggdrasil_rt::mem::MappingSource;
use yggdrasil_rt::mem::{MappingFlags, MappingSource};
let address = unsafe {
yggdrasil_rt::sys::map_memory(None, count * PAGE_SIZE, &MappingSource::Anonymous)
yggdrasil_rt::sys::map_memory(
None,
count * PAGE_SIZE,
MappingFlags::WRITE,
&MappingSource::Anonymous,
)
}
.ok()?;

View File

@ -21,7 +21,7 @@ pub mod time;
pub mod mem {
//! Memory-related data structures
pub use abi::mem::MappingSource;
pub use abi::mem::{MappingFlags, MappingSource};
}
pub mod system {

View File

@ -1,6 +1,6 @@
//! Process management data types
use abi::mem::MappingSource;
use abi::mem::{MappingFlags, MappingSource};
pub use abi::process::{
ExecveOptions, ExitCode, MutexOperation, ProcessGroupId, ProcessId, ProcessInfoElement,
ProgramArgumentInner, Signal, SignalEntryData, SpawnFlags, SpawnOption, SpawnOptions, ThreadId,
@ -22,8 +22,9 @@ unsafe fn thread_local_area_common(tp: usize) -> &'static mut [*mut u8] {
let (base, len) = if unsafe { (*ptr).is_null() } {
// If segment is NULL, allocate some memory and map it here
let base = unsafe { sys::map_memory(None, 4096, &MappingSource::Anonymous) }
.expect("Could not allocate TLS storage");
let base =
unsafe { sys::map_memory(None, 4096, MappingFlags::WRITE, &MappingSource::Anonymous) }
.expect("Could not allocate TLS storage");
let base = core::ptr::with_exposed_provenance_mut::<*mut u8>(base);
unsafe {

View File

@ -20,7 +20,7 @@ mod generated {
PipeOptions, PollControl, RawFd, TerminalOptions, TerminalSize, TimerOptions,
UnmountOptions,
},
mem::MappingSource,
mem::{MappingFlags, MappingSource},
net::SocketType,
process::{
ExecveOptions, ProcessGroupId, ProcessId, Signal, SignalEntryData, SpawnOptions,

View File

@ -3,7 +3,7 @@ use std::{
ptr::NonNull,
};
use yggdrasil_rt::mem::MappingSource;
use yggdrasil_rt::mem::{MappingFlags, MappingSource};
use crate::error::Error;
@ -12,9 +12,9 @@ pub struct Mapping {
}
impl Mapping {
pub fn new(size: usize) -> Result<Mapping, Error> {
pub fn new(size: usize, flags: MappingFlags) -> Result<Mapping, Error> {
let size = (size + 0xFFF) & !0xFFF;
let base = unsafe { yggdrasil_rt::sys::map_memory(None, size, &MappingSource::Anonymous) }
let base = unsafe { yggdrasil_rt::sys::map_memory(None, size, flags, &MappingSource::Anonymous) }
.map_err(|e| Error::MemoryMap(e))?;
let base_ptr =
unsafe { NonNull::new_unchecked(core::ptr::with_exposed_provenance_mut(base)) };

View File

@ -15,6 +15,7 @@ use elf::{
symbol::Symbol,
ElfStream,
};
use yggdrasil_rt::mem::MappingFlags;
use crate::{
error::Error,
@ -153,9 +154,10 @@ impl Object {
debug_trace!("Load {:?}", self.path);
debug_trace!("Image range: {:#x?}", self.vma_start..self.vma_end);
// TODO segment granularity mappings
let mapping_size = self.vma_end - self.vma_start;
let mut mapping = match self.ty {
ElfType::Relocatable(_) => Mapping::new(mapping_size)?,
ElfType::Relocatable(_) => Mapping::new(mapping_size, MappingFlags::WRITE | MappingFlags::EXEC)?,
// TODO fixed mapping for this one
ElfType::Static => todo!(),
};

View File

@ -1,9 +1,15 @@
use core::{
alloc::{GlobalAlloc, Layout}, cmp::Ordering, ffi::c_void, ptr::{self, null_mut, NonNull}
alloc::{GlobalAlloc, Layout},
cmp::Ordering,
ffi::c_void,
ptr::{self, null_mut, NonNull},
};
use libyalloc::{allocator::BucketAllocator, sys::PageProvider};
use yggdrasil_rt::{mem::MappingSource, sys as syscall};
use yggdrasil_rt::{
mem::{MappingFlags, MappingSource},
sys as syscall,
};
use crate::{
error::{EResult, OptionExt},
@ -34,7 +40,14 @@ unsafe impl GlobalAlloc for Allocator {
impl PageProvider for PageProviderImpl {
fn map_pages(count: usize) -> Option<NonNull<u8>> {
match unsafe { syscall::map_memory(None, count * 0x1000, &MappingSource::Anonymous) } {
match unsafe {
syscall::map_memory(
None,
count * 0x1000,
MappingFlags::WRITE,
&MappingSource::Anonymous,
)
} {
Ok(address) => {
let pointer = ptr::with_exposed_provenance_mut(address);
NonNull::new(pointer)
@ -100,7 +113,7 @@ pub unsafe fn c_realloc(old_ptr: Option<NonNull<c_void>>, size: usize) -> EResul
YALLOC.lock().free(real_old_ptr, old_layout);
EResult::Ok(new_ptr)
},
}
None => c_alloc(size, 16, false),
}
}