You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
unsigned longdo_mmap_pgoff(structfile*file, unsigned longaddr,
unsigned longlen, unsigned longprot,
unsigned longflags, unsigned longpgoff,
unsigned long*populate)
{
structmm_struct*mm=current->mm;
vm_flags_tvm_flags;
*populate=0;
if ((prot&PROT_READ) && (current->personality&READ_IMPLIES_EXEC))
if (!(file&& (file->f_path.mnt->mnt_flags&MNT_NOEXEC)))
prot |= PROT_EXEC;
if (!len)
return-EINVAL;
// 是否是FIXED mapif (!(flags&MAP_FIXED))
addr=round_hint_to_min(addr);
/* Careful about overflows.. */len=PAGE_ALIGN(len);
if (!len)
return-ENOMEM;
/* offset overflow? */if ((pgoff+ (len >> PAGE_SHIFT)) <pgoff)
return-EOVERFLOW;
/* Too many mappings? */if (mm->map_count>sysctl_max_map_count)
return-ENOMEM;
/* 从进程虚拟地址空间分配一个虚拟地址范围 */addr=get_unmapped_area(file, addr, len, pgoff, flags);
if (addr& ~PAGE_MASK)
returnaddr;
/* Do simple checking here so the lower-level routines won't have * to. we assume access permissions have been handled by the open * of the memory object, so we don't do any here. */vm_flags=calc_vm_prot_bits(prot) | calc_vm_flag_bits(flags) |
mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
if (flags&MAP_LOCKED)
if (!can_do_mlock())
return-EPERM;
if (mlock_future_check(mm, vm_flags, len))
return-EAGAIN;
if (file) {
structinode*inode=file_inode(file);
switch (flags&MAP_TYPE) {
caseMAP_SHARED:
if ((prot&PROT_WRITE) && !(file->f_mode&FMODE_WRITE))
return-EACCES;
/* * Make sure we don't allow writing to an append-only * file.. */if (IS_APPEND(inode) && (file->f_mode&FMODE_WRITE))
return-EACCES;
/* * Make sure there are no mandatory locks on the file. */if (locks_verify_locked(file))
return-EAGAIN;
vm_flags |= VM_SHARED | VM_MAYSHARE;
if (!(file->f_mode&FMODE_WRITE))
vm_flags &= ~(VM_MAYWRITE | VM_SHARED);
/* fall through */caseMAP_PRIVATE:
if (!(file->f_mode&FMODE_READ))
return-EACCES;
if (file->f_path.mnt->mnt_flags&MNT_NOEXEC) {
if (vm_flags&VM_EXEC)
return-EPERM;
vm_flags &= ~VM_MAYEXEC;
}
if (!file->f_op->mmap)
return-ENODEV;
if (vm_flags& (VM_GROWSDOWN|VM_GROWSUP))
return-EINVAL;
break;
default:
return-EINVAL;
}
} else {
switch (flags&MAP_TYPE) {
caseMAP_SHARED:
if (vm_flags& (VM_GROWSDOWN|VM_GROWSUP))
return-EINVAL;
/* * Ignore pgoff. */pgoff=0;
vm_flags |= VM_SHARED | VM_MAYSHARE;
break;
caseMAP_PRIVATE:
/* * Set pgoff according to addr for anon_vma. */pgoff=addr >> PAGE_SHIFT;
break;
default:
return-EINVAL;
}
}
/* * Set 'VM_NORESERVE' if we should not account for the * memory use of this mapping. */if (flags&MAP_NORESERVE) {
/* We honor MAP_NORESERVE if allowed to overcommit */if (sysctl_overcommit_memory!=OVERCOMMIT_NEVER)
vm_flags |= VM_NORESERVE;
/* hugetlb applies strict overcommit unless MAP_NORESERVE */if (file&&is_file_hugepages(file))
vm_flags |= VM_NORESERVE;
}
addr=mmap_region(file, addr, len, vm_flags, pgoff);
if (!IS_ERR_VALUE(addr) &&
((vm_flags&VM_LOCKED) ||
(flags& (MAP_POPULATE | MAP_NONBLOCK)) ==MAP_POPULATE))
*populate=len;
returnaddr;
}
下面以ARM64架构分析mmap映射过程
sys_mmap主要检查偏移是不是页的整数倍,然后调用
sys_mmap_pgoff
if条件判断如果是文件映射,根据文件描述符在进程的打开文件中找到file实例. 最后调用
vm_mmap_pgoff
函数处理.接着看
do_mmap_pgoff
函数下面再看
mmap_region
函数The text was updated successfully, but these errors were encountered: