mirror of
https://github.com/hexagonal-sun/moss-kernel.git
synced 2026-04-20 15:18:26 -04:00
procfs: implement /proc/<PID>/maps
Implement the `maps` file which shows a process's VMA entries. Example output: ``` [root@moss-machine /]# cat /proc/1/maps 500000000000-500000117000 r-xp 0000000000 /bin/bash 50000012b000-500000130000 r--p 000011b000 /bin/bash 500000130000-50000013e000 rw-p 0000120000 /bin/bash 700000000000-70000002b000 r-xp 0000000000 /lib/ld-linux-aarch64.so.1 70000003e000-700000040000 r--p 000002e000 /lib/ld-linux-aarch64.so.1 700000040000-700000042000 rw-p 0000030000 /lib/ld-linux-aarch64.so.1 7fffff510000-7fffff585000 r-xp 0000000000 /usr/lib/libncursesw.so.6 7fffff585000-7fffff59b000 ---p 0000075000 /usr/lib/libncursesw.so.6 7fffff59b000-7fffff5a0000 r--p 000007b000 /usr/lib/libncursesw.so.6 7fffff5a0000-7fffff5a1000 rw-p 0000080000 /usr/lib/libncursesw.so.6 7fffff5b0000-7fffff760000 r-xp 0000000000 /usr/lib/libc.so.6 7fffff760000-7fffff76d000 ---p 00001b0000 /usr/lib/libc.so.6 7fffff76d000-7fffff770000 r--p 00001bd000 /usr/lib/libc.so.6 7fffff770000-7fffff772000 rw-p 00001c0000 /usr/lib/libc.so.6 7fffff772000-7fffff779000 rw-p 0000000000 7fffff780000-7fffff7d9000 r-xp 0000000000 /usr/lib/libreadline.so.8 7fffff7d9000-7fffff7ed000 ---p 0000059000 /usr/lib/libreadline.so.8 7fffff7ed000-7fffff7f0000 r--p 000005d000 /usr/lib/libreadline.so.8 7fffff7f0000-7fffff7f6000 rw-p 0000060000 /usr/lib/libreadline.so.8 7fffff7f6000-7fffff7fb000 rw-p 0000000000 7fffff800000-800000063000 rw-p 0000000000 [stack] ```
This commit is contained in:
@@ -7,7 +7,7 @@ use crate::{
|
||||
region::VirtMemoryRegion,
|
||||
},
|
||||
};
|
||||
use alloc::{collections::BTreeMap, vec::Vec};
|
||||
use alloc::{collections::BTreeMap, string::String, vec::Vec};
|
||||
|
||||
const MMAP_BASE: usize = 0x4000_0000_0000;
|
||||
|
||||
@@ -85,6 +85,7 @@ impl<AS: UserAddressSpace> MemoryMap<AS> {
|
||||
mut len: usize,
|
||||
perms: VMAPermissions,
|
||||
kind: VMAreaKind,
|
||||
name: String,
|
||||
) -> Result<VA> {
|
||||
if len == 0 {
|
||||
return Err(KernelError::InvalidValue);
|
||||
@@ -133,7 +134,9 @@ impl<AS: UserAddressSpace> MemoryMap<AS> {
|
||||
|
||||
// At this point, `start_addr` points to a valid, free region.
|
||||
// We can now create and insert the new VMA, handling merges.
|
||||
let new_vma = VMArea::new(region, kind, perms);
|
||||
let mut new_vma = VMArea::new(region, kind, perms);
|
||||
|
||||
new_vma.set_name(name);
|
||||
|
||||
self.insert_and_merge(new_vma);
|
||||
|
||||
@@ -502,6 +505,10 @@ impl<AS: UserAddressSpace> MemoryMap<AS> {
|
||||
pub fn vma_count(&self) -> usize {
|
||||
self.vmas.len()
|
||||
}
|
||||
|
||||
pub fn iter_vmas(&self) -> impl Iterator<Item = &VMArea> {
|
||||
self.vmas.values()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
@@ -194,6 +194,7 @@ fn test_mmap_any_empty() {
|
||||
size,
|
||||
VMAPermissions::rw(),
|
||||
VMAreaKind::Anon,
|
||||
String::new(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
@@ -218,6 +219,7 @@ fn test_mmap_any_with_existing() {
|
||||
size,
|
||||
VMAPermissions::ro(),
|
||||
VMAreaKind::Anon,
|
||||
String::new(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
@@ -231,6 +233,7 @@ fn test_mmap_any_with_existing() {
|
||||
size,
|
||||
VMAPermissions::ro(), // different permissions to prevent merge.
|
||||
VMAreaKind::Anon,
|
||||
String::new(),
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(bottom_addr.value(), existing_addr - size);
|
||||
@@ -254,6 +257,7 @@ fn test_mmap_hint_free() {
|
||||
size,
|
||||
VMAPermissions::rw(),
|
||||
VMAreaKind::Anon,
|
||||
String::new(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
@@ -282,6 +286,7 @@ fn test_mmap_hint_taken() {
|
||||
size,
|
||||
VMAPermissions::rw(),
|
||||
VMAreaKind::Anon,
|
||||
String::new(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
@@ -309,6 +314,7 @@ fn test_mmap_fixed_clobber_complete_overlap() {
|
||||
3 * PAGE_SIZE,
|
||||
VMAPermissions::rw(),
|
||||
VMAreaKind::Anon,
|
||||
String::new(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
@@ -345,6 +351,7 @@ fn test_mmap_fixed_clobber_partial_end() {
|
||||
new_size,
|
||||
VMAPermissions::rw(),
|
||||
VMAreaKind::Anon,
|
||||
String::new(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
@@ -378,6 +385,7 @@ fn test_mmap_fixed_clobber_partial_end_spill() {
|
||||
new_size,
|
||||
VMAPermissions::rw(),
|
||||
VMAreaKind::Anon,
|
||||
String::new(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
@@ -413,6 +421,7 @@ fn test_mmap_fixed_no_clobber_fails() {
|
||||
new_size,
|
||||
VMAPermissions::rw(),
|
||||
VMAreaKind::Anon,
|
||||
String::new(),
|
||||
)
|
||||
.is_err()
|
||||
);
|
||||
@@ -438,6 +447,7 @@ fn test_mmap_fixed_clobber_punch_hole() {
|
||||
new_size,
|
||||
VMAPermissions::ro(),
|
||||
VMAreaKind::Anon,
|
||||
String::new(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ use crate::{
|
||||
UserAddressSpace,
|
||||
error::{KernelError, Result},
|
||||
};
|
||||
use alloc::string::ToString;
|
||||
use memory_map::{AddressRequest, MemoryMap};
|
||||
use vmarea::{AccessKind, FaultValidation, VMAPermissions, VMArea, VMAreaKind};
|
||||
|
||||
@@ -137,6 +138,7 @@ impl<AS: UserAddressSpace> ProcessVM<AS> {
|
||||
growth_size,
|
||||
BRK_PERMISSIONS,
|
||||
VMAreaKind::Anon,
|
||||
"[heap]".to_string(),
|
||||
)?;
|
||||
|
||||
self.brk = new_brk_region;
|
||||
@@ -174,6 +176,7 @@ mod tests {
|
||||
region: VirtMemoryRegion::new(VA::from_value(0x1000), PAGE_SIZE),
|
||||
kind: VMAreaKind::Anon, // Simplification for test
|
||||
permissions: VMAPermissions::rx(),
|
||||
name: String::new(),
|
||||
};
|
||||
|
||||
ProcessVM::from_vma(text_vma).unwrap()
|
||||
@@ -329,6 +332,7 @@ mod tests {
|
||||
region: VirtMemoryRegion::new(obstacle_addr, PAGE_SIZE),
|
||||
kind: VMAreaKind::Anon,
|
||||
permissions: VMAPermissions::ro(),
|
||||
name: String::new(),
|
||||
};
|
||||
vm.mm.insert_and_merge(obstacle_vma);
|
||||
assert_eq!(vm.mm.vma_count(), 2);
|
||||
|
||||
@@ -12,9 +12,10 @@
|
||||
use core::cmp;
|
||||
|
||||
use crate::{
|
||||
fs::Inode,
|
||||
fs::{Inode, InodeId},
|
||||
memory::{PAGE_MASK, PAGE_SIZE, address::VA, region::VirtMemoryRegion},
|
||||
};
|
||||
use alloc::string::{String, ToString};
|
||||
use alloc::sync::Arc;
|
||||
use object::{
|
||||
Endian,
|
||||
@@ -173,6 +174,7 @@ impl VMAreaKind {
|
||||
#[derive(Clone, PartialEq)]
|
||||
pub struct VMArea {
|
||||
pub region: VirtMemoryRegion,
|
||||
pub(super) name: String,
|
||||
pub(super) kind: VMAreaKind,
|
||||
pub(super) permissions: VMAPermissions,
|
||||
}
|
||||
@@ -189,9 +191,14 @@ impl VMArea {
|
||||
region,
|
||||
kind,
|
||||
permissions,
|
||||
name: String::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_name<S: AsRef<str>>(&mut self, s: S) {
|
||||
self.name = s.as_ref().to_string();
|
||||
}
|
||||
|
||||
/// Creates a file-backed `VMArea` directly from an ELF program header.
|
||||
///
|
||||
/// This is a convenience function used by the ELF loader. It parses the
|
||||
@@ -246,6 +253,7 @@ impl VMArea {
|
||||
len: hdr.p_filesz(endian) + mappable_region.offset() as u64,
|
||||
}),
|
||||
permissions,
|
||||
name: String::new(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -455,6 +463,24 @@ impl VMArea {
|
||||
pub fn region(&self) -> VirtMemoryRegion {
|
||||
self.region
|
||||
}
|
||||
|
||||
pub fn file_offset(&self) -> Option<u64> {
|
||||
match self.kind {
|
||||
VMAreaKind::File(ref vmfile_mapping) => Some(vmfile_mapping.offset()),
|
||||
VMAreaKind::Anon => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn inode_id(&self) -> Option<InodeId> {
|
||||
match self.kind {
|
||||
VMAreaKind::File(ref vmfile_mapping) => Some(vmfile_mapping.file().id()),
|
||||
VMAreaKind::Anon => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn name(&self) -> &str {
|
||||
&self.name
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
Reference in New Issue
Block a user