1
0
mirror of https://github.com/rcore-os/rCore.git synced 2024-11-22 08:06:17 +04:00

Re-construct vm in place in sys_exec

This commit is contained in:
Jiajie Chen 2020-06-19 12:59:12 +08:00
parent e8046ec728
commit 39e750517c
3 changed files with 19 additions and 17 deletions

View File

@ -61,8 +61,8 @@ impl ToMemoryAttr for Flags {
/// Helper functions to process ELF file
pub trait ElfExt {
/// Generate a MemorySet according to the ELF file.
fn make_memory_set(&self, inode: &Arc<dyn INode>) -> (MemorySet, usize);
/// Setup MemorySet according to the ELF file.
fn make_memory_set(&self, ms: &mut MemorySet, inode: &Arc<dyn INode>) -> usize;
/// Get interpreter string if it has.
fn get_interpreter(&self) -> Result<&str, &str>;
@ -81,9 +81,8 @@ pub trait ElfExt {
}
impl ElfExt for ElfFile<'_> {
fn make_memory_set(&self, inode: &Arc<dyn INode>) -> (MemorySet, usize) {
fn make_memory_set(&self, ms: &mut MemorySet, inode: &Arc<dyn INode>) -> usize {
debug!("creating MemorySet from ELF");
let mut ms = MemorySet::new();
let mut farthest_memory: usize = 0;
for ph in self.program_iter() {
if ph.get_type() != Ok(Type::Load) {
@ -106,10 +105,8 @@ impl ElfExt for ElfFile<'_> {
farthest_memory = ph.virtual_addr() as usize + ph.mem_size() as usize;
}
}
(
ms,
(Page::of_addr(farthest_memory + PAGE_SIZE)).start_address(),
)
Page::of_addr(farthest_memory + PAGE_SIZE).start_address()
}
fn append_as_interpreter(&self, inode: &Arc<dyn INode>, ms: &mut MemorySet, bias: usize) {
debug!("inserting interpreter from ELF");

View File

@ -81,7 +81,8 @@ impl Thread {
inode: &Arc<dyn INode>,
args: Vec<String>,
envs: Vec<String>,
) -> Result<(MemorySet, usize, usize), &'static str> {
vm: &mut MemorySet,
) -> Result<(usize, usize), &'static str> {
// Read ELF header
// 0x3c0: magic number from ld-musl.so
let mut data = [0u8; 0x3c0];
@ -127,7 +128,7 @@ impl Thread {
// entry point
let mut entry_addr = elf.header.pt2.entry_point() as usize;
// Make page table
let (mut vm, bias) = elf.make_memory_set(inode);
let bias = elf.make_memory_set(vm, inode);
// Check interpreter (for dynamic link)
// When interpreter is used, map both dynamic linker and executable
@ -143,7 +144,7 @@ impl Thread {
.read_at(0, &mut interp_data)
.map_err(|_| "failed to read from INode")?;
let elf_interp = ElfFile::new(&interp_data)?;
elf_interp.append_as_interpreter(&interp_inode, &mut vm, bias);
elf_interp.append_as_interpreter(&interp_inode, vm, bias);
// update auxiliary vector
auxv.insert(abi::AT_ENTRY, elf.header.pt2.entry_point() as usize);
@ -186,7 +187,7 @@ impl Thread {
vm.with(|| ustack_top = init_info.push_at(ustack_top));
}
Ok((vm, entry_addr, ustack_top))
Ok((entry_addr, ustack_top))
}
/// Make a new user process from ELF `data`
@ -197,7 +198,8 @@ impl Thread {
envs: Vec<String>,
) -> Arc<Thread> {
/// get virtual memory info
let (vm, entry_addr, ustack_top) = Self::new_user_vm(inode, args, envs).unwrap();
let mut vm = MemorySet::new();
let (entry_addr, ustack_top) = Self::new_user_vm(inode, args, envs, &mut vm).unwrap();
let vm_token = vm.token();
let vm = Arc::new(Mutex::new(vm));

View File

@ -233,8 +233,11 @@ impl Syscall<'_> {
let inode = proc.lookup_inode(&path)?;
// Make new Thread
let (mut vm, entry_addr, ustack_top) =
Thread::new_user_vm(&inode, args, envs).map_err(|_| SysError::EINVAL)?;
// Re-create vm
let mut vm = self.vm();
vm.clear();
let (entry_addr, ustack_top) =
Thread::new_user_vm(&inode, args, envs, &mut vm).map_err(|_| SysError::EINVAL)?;
// close file that FD_CLOEXEC is set
let close_fds = proc
@ -257,10 +260,10 @@ impl Syscall<'_> {
}
// Activate new page table
core::mem::swap(&mut *self.vm(), &mut vm);
unsafe {
self.vm().activate();
vm.activate();
}
drop(vm);
// Modify exec path
proc.exec_path = path.clone();