diff --git a/src/sys/allocator.rs b/src/sys/allocator.rs index 6e6b9cd96..ee017bcbe 100644 --- a/src/sys/allocator.rs +++ b/src/sys/allocator.rs @@ -59,7 +59,7 @@ pub fn init_heap() -> Result<(), MapToError> { } pub fn alloc_pages( - mapper: &mut OffsetPageTable, addr: u64, size: usize + mapper: &mut OffsetPageTable, addr: u64, size: usize, flags: PageTableFlags ) -> Result<(), ()> { let size = size.saturating_sub(1) as u64; let mut frame_allocator = sys::mem::frame_allocator(); @@ -70,9 +70,11 @@ pub fn alloc_pages( Page::range_inclusive(start_page, end_page) }; + /* let flags = PageTableFlags::PRESENT | PageTableFlags::WRITABLE | PageTableFlags::USER_ACCESSIBLE; + */ for page in pages { if let Some(frame) = frame_allocator.allocate_frame() { diff --git a/src/sys/idt.rs b/src/sys/idt.rs index 58bdda768..64c69baf3 100644 --- a/src/sys/idt.rs +++ b/src/sys/idt.rs @@ -12,7 +12,7 @@ use x86_64::structures::idt::{ InterruptDescriptorTable, InterruptStackFrame, InterruptStackFrameValue, PageFaultErrorCode, }; -use x86_64::structures::paging::OffsetPageTable; +use x86_64::structures::paging::{OffsetPageTable, PageTableFlags}; use x86_64::VirtAddr; const PIC1: u16 = 0x21; @@ -136,9 +136,12 @@ extern "x86-interrupt" fn page_fault_handler( let mut mapper = unsafe { OffsetPageTable::new(page_table, VirtAddr::new(phys_mem_offset)) }; + let flags = PageTableFlags::PRESENT + | PageTableFlags::WRITABLE + | PageTableFlags::USER_ACCESSIBLE; // TODO if error_code.contains(PageFaultErrorCode::CAUSED_BY_WRITE) { - if sys::allocator::alloc_pages(&mut mapper, addr, 1).is_err() { + if sys::allocator::alloc_pages(&mut mapper, addr, 1, flags).is_err() { printk!( "{}Error:{} Could not allocate page at {:#X}\n", csi_color, csi_reset, addr @@ -154,7 +157,7 @@ extern "x86-interrupt" fn page_fault_handler( // longer a simple clone of the kernel page table. Currently a process // is executed from its kernel address that is shared with the process. let start = (addr / 4096) * 4096; - if sys::allocator::alloc_pages(&mut mapper, start, 4096).is_ok() { + if sys::allocator::alloc_pages(&mut mapper, start, 4096, flags).is_ok() { if sys::process::is_userspace(start) { let code_addr = sys::process::code_addr(); let src = (code_addr + start) as *mut u8; diff --git a/src/sys/process.rs b/src/sys/process.rs index fc8042317..73d736db3 100644 --- a/src/sys/process.rs +++ b/src/sys/process.rs @@ -15,6 +15,7 @@ use core::sync::atomic::{AtomicU64, AtomicUsize, Ordering}; use lazy_static::lazy_static; use linked_list_allocator::LockedHeap; use object::{Object, ObjectSegment}; +use object::read::SegmentFlags; use spin::RwLock; use x86_64::registers::control::Cr3; use x86_64::structures::idt::InterruptStackFrameValue; @@ -375,16 +376,21 @@ impl Process { /* debug!( "{:#X}..{:#X}: {} bytes for a code segment ({:#X}..{:#X}: {} bytes)", - addr, addr + data.len() as u64, data.len(), - segment.address(), segment.address() + segment.size(), segment.size(), + addr, addr + size as u64, size, + segment.address(), segment.address() + data.len() as u64, data.len(), ); */ - load_binary(&mut mapper, addr, size, data)?; + let flags = parse_flags(segment.flags()).unwrap(); + //debug!("{:#?}", flags); + load_binary(&mut mapper, addr, size, data, flags)?; } } } } else if bin[0..4] == BIN_MAGIC { // Flat binary - load_binary(&mut mapper, code_addr, bin.len() - 4, &bin[4..])?; + let flags = PageTableFlags::PRESENT + | PageTableFlags::WRITABLE + | PageTableFlags::USER_ACCESSIBLE; // TODO + load_binary(&mut mapper, code_addr, bin.len() - 4, &bin[4..], flags)?; } else { return Err(()); } @@ -431,7 +437,10 @@ impl Process { // Copy args to user memory let args_addr = self.code_addr + (self.stack_addr - self.code_addr) / 2; - sys::allocator::alloc_pages(&mut mapper, args_addr, 1). + let flags = PageTableFlags::PRESENT + | PageTableFlags::WRITABLE + | PageTableFlags::USER_ACCESSIBLE; // TODO + sys::allocator::alloc_pages(&mut mapper, args_addr, 1, flags). expect("proc args alloc"); let args: &[&str] = unsafe { let ptr = ptr_from_addr(args_ptr as u64) as usize; @@ -523,10 +532,14 @@ impl Process { } fn load_binary( - mapper: &mut OffsetPageTable, addr: u64, size: usize, buf: &[u8] + mapper: &mut OffsetPageTable, + addr: u64, + size: usize, + buf: &[u8], + flags: PageTableFlags, ) -> Result<(), ()> { debug_assert!(size >= buf.len()); - sys::allocator::alloc_pages(mapper, addr, size)?; + sys::allocator::alloc_pages(mapper, addr, size, flags)?; let src = buf.as_ptr(); let dst = addr as *mut u8; unsafe { @@ -537,3 +550,14 @@ fn load_binary( } Ok(()) } + +fn parse_flags(flags: SegmentFlags) -> Option { + match flags { + SegmentFlags::Elf { p_flags } => { + PageTableFlags::from_bits(p_flags as u64) + } + _ => { + None + } + } +}