mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-24 18:03:25 +00:00
Modify the behavior of mapping segment vmo
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
33c8727a13
commit
afc4bf7520
@ -27,7 +27,7 @@ use crate::{
|
|||||||
vm::{
|
vm::{
|
||||||
perms::VmPerms,
|
perms::VmPerms,
|
||||||
vmar::Vmar,
|
vmar::Vmar,
|
||||||
vmo::{Vmo, VmoFlags, VmoOptions, VmoRightsOp},
|
vmo::{Vmo, VmoOptions, VmoRightsOp},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -198,8 +198,14 @@ pub fn map_segment_vmos(elf: &Elf, root_vmar: &Vmar<Full>, elf_file: &Dentry) ->
|
|||||||
.map_err(|_| Error::with_message(Errno::ENOEXEC, "parse program header type fails"))?;
|
.map_err(|_| Error::with_message(Errno::ENOEXEC, "parse program header type fails"))?;
|
||||||
if type_ == program::Type::Load {
|
if type_ == program::Type::Load {
|
||||||
check_segment_align(program_header)?;
|
check_segment_align(program_header)?;
|
||||||
let vmo = init_segment_vmo(program_header, elf_file)?;
|
let (vmo, anonymous_map_size) = init_segment_vmo(program_header, elf_file)?;
|
||||||
map_segment_vmo(program_header, vmo, root_vmar, base_addr)?;
|
map_segment_vmo(
|
||||||
|
program_header,
|
||||||
|
vmo,
|
||||||
|
anonymous_map_size,
|
||||||
|
root_vmar,
|
||||||
|
base_addr,
|
||||||
|
)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(base_addr)
|
Ok(base_addr)
|
||||||
@ -234,6 +240,7 @@ fn base_map_addr(elf: &Elf, root_vmar: &Vmar<Full>) -> Result<Vaddr> {
|
|||||||
fn map_segment_vmo(
|
fn map_segment_vmo(
|
||||||
program_header: &ProgramHeader64,
|
program_header: &ProgramHeader64,
|
||||||
vmo: Vmo,
|
vmo: Vmo,
|
||||||
|
anonymous_map_size: usize,
|
||||||
root_vmar: &Vmar<Full>,
|
root_vmar: &Vmar<Full>,
|
||||||
base_addr: Vaddr,
|
base_addr: Vaddr,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
@ -245,15 +252,28 @@ fn map_segment_vmo(
|
|||||||
program_header.mem_size,
|
program_header.mem_size,
|
||||||
perms
|
perms
|
||||||
);
|
);
|
||||||
|
let vmo_size = vmo.size();
|
||||||
let mut vm_map_options = root_vmar.new_map(vmo, perms)?.can_overwrite(true);
|
let mut vm_map_options = root_vmar.new_map(vmo, perms)?.can_overwrite(true);
|
||||||
let offset = base_addr + offset;
|
let offset = base_addr + offset;
|
||||||
vm_map_options = vm_map_options.offset(offset);
|
vm_map_options = vm_map_options.offset(offset);
|
||||||
let map_addr = vm_map_options.build()?;
|
let map_addr = vm_map_options.build()?;
|
||||||
|
|
||||||
|
if anonymous_map_size > 0 {
|
||||||
|
let anonymous_vmo = {
|
||||||
|
let options: VmoOptions<Rights> = VmoOptions::new(anonymous_map_size);
|
||||||
|
options.alloc()?
|
||||||
|
};
|
||||||
|
let mut anonymous_map_options =
|
||||||
|
root_vmar.new_map(anonymous_vmo, perms)?.can_overwrite(true);
|
||||||
|
anonymous_map_options = anonymous_map_options.offset(offset + vmo_size);
|
||||||
|
let anonymous_map_addr = anonymous_map_options.build()?;
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// create vmo for each segment
|
/// Create VMO for each segment. Return the segment VMO and the size of
|
||||||
fn init_segment_vmo(program_header: &ProgramHeader64, elf_file: &Dentry) -> Result<Vmo> {
|
/// additional anonymous mapping it needs.
|
||||||
|
fn init_segment_vmo(program_header: &ProgramHeader64, elf_file: &Dentry) -> Result<(Vmo, usize)> {
|
||||||
trace!(
|
trace!(
|
||||||
"mem range = 0x{:x} - 0x{:x}, mem_size = 0x{:x}",
|
"mem range = 0x{:x} - 0x{:x}, mem_size = 0x{:x}",
|
||||||
program_header.virtual_addr,
|
program_header.virtual_addr,
|
||||||
@ -277,6 +297,11 @@ fn init_segment_vmo(program_header: &ProgramHeader64, elf_file: &Dentry) -> Resu
|
|||||||
"executable has no page cache",
|
"executable has no page cache",
|
||||||
))?
|
))?
|
||||||
};
|
};
|
||||||
|
let vmo_size = {
|
||||||
|
let vmap_start = virtual_addr.align_down(PAGE_SIZE);
|
||||||
|
let vmap_end = (virtual_addr + program_header.mem_size as usize).align_up(PAGE_SIZE);
|
||||||
|
vmap_end - vmap_start
|
||||||
|
};
|
||||||
|
|
||||||
let segment_vmo = {
|
let segment_vmo = {
|
||||||
let parent_range = {
|
let parent_range = {
|
||||||
@ -284,20 +309,14 @@ fn init_segment_vmo(program_header: &ProgramHeader64, elf_file: &Dentry) -> Resu
|
|||||||
let end = (file_offset + program_header.file_size as usize).align_up(PAGE_SIZE);
|
let end = (file_offset + program_header.file_size as usize).align_up(PAGE_SIZE);
|
||||||
start..end
|
start..end
|
||||||
};
|
};
|
||||||
let vmo_size = {
|
|
||||||
let vmap_start = virtual_addr.align_down(PAGE_SIZE);
|
|
||||||
let vmap_end = (virtual_addr + program_header.mem_size as usize).align_up(PAGE_SIZE);
|
|
||||||
vmap_end - vmap_start
|
|
||||||
};
|
|
||||||
debug_assert!(vmo_size >= (program_header.file_size as usize).align_up(PAGE_SIZE));
|
debug_assert!(vmo_size >= (program_header.file_size as usize).align_up(PAGE_SIZE));
|
||||||
let segment_vmo = page_cache_vmo
|
page_cache_vmo.new_cow_child(parent_range)?.alloc()?
|
||||||
.new_cow_child(parent_range)?
|
};
|
||||||
.flags(VmoFlags::RESIZABLE)
|
|
||||||
.alloc()?;
|
let anonymous_map_size: usize = if vmo_size > segment_vmo.size() {
|
||||||
if vmo_size > segment_vmo.size() {
|
vmo_size - segment_vmo.size()
|
||||||
segment_vmo.resize(vmo_size)?;
|
} else {
|
||||||
};
|
0
|
||||||
segment_vmo
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Write zero as paddings. There are head padding and tail padding.
|
// Write zero as paddings. There are head padding and tail padding.
|
||||||
@ -319,7 +338,7 @@ fn init_segment_vmo(program_header: &ProgramHeader64, elf_file: &Dentry) -> Resu
|
|||||||
let buffer = vec![0u8; (segment_vmo_size - tail_padding_offset) % PAGE_SIZE];
|
let buffer = vec![0u8; (segment_vmo_size - tail_padding_offset) % PAGE_SIZE];
|
||||||
segment_vmo.write_bytes(tail_padding_offset, &buffer)?;
|
segment_vmo.write_bytes(tail_padding_offset, &buffer)?;
|
||||||
}
|
}
|
||||||
Ok(segment_vmo.to_dyn())
|
Ok((segment_vmo.to_dyn(), anonymous_map_size))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_segment_perm(flags: xmas_elf::program::Flags) -> VmPerm {
|
fn parse_segment_perm(flags: xmas_elf::program::Flags) -> VmPerm {
|
||||||
|
Reference in New Issue
Block a user