Exemple #1
0
void *linux_regfile_mmap2(void *addr, size_t len, int prot, int flags, int fd,
			  size_t off)
{
	int subret = -E_INVAL;
	struct mm_struct *mm = current->mm;
	assert(mm != NULL);
	if (len == 0) {
		return -1;
	}
	lock_mm(mm);

	uintptr_t start = ROUNDDOWN(addr, PGSIZE);
	len = ROUNDUP(len, PGSIZE);

	uint32_t vm_flags = VM_READ;
	if (prot & PROT_WRITE) {
		vm_flags |= VM_WRITE;
	}
	if (prot & PROT_EXEC) {
		vm_flags |= VM_EXEC;
	}
	if (flags & MAP_STACK) {
		vm_flags |= VM_STACK;
	}
	if (flags & MAP_ANONYMOUS) {
		vm_flags |= VM_ANONYMOUS;
	}

	subret = -E_NO_MEM;
	if (start == 0 && (start = get_unmapped_area(mm, len)) == 0) {
		goto out_unlock;
	}
	uintptr_t end = start + len;
	struct vma_struct *vma = find_vma(mm, start);
	if (vma == NULL || vma->vm_start >= end) {
		vma = NULL;
	} else if (!(flags & MAP_FIXED)) {
		start = get_unmapped_area(mm, len);
		vma = NULL;
	} else if (!(vma->vm_flags & VM_ANONYMOUS)) {
		goto out_unlock;
	} else if (vma->vm_start == start && end == vma->vm_end) {
		vma->vm_flags = vm_flags;
	} else {
		assert(vma->vm_start <= start && end <= vma->vm_end);
		if ((subret = mm_unmap_keep_pages(mm, start, len)) != 0) {
			goto out_unlock;
		}
		vma = NULL;
	}
	if (vma == NULL
	    && (subret = mm_map(mm, start, len, vm_flags, &vma)) != 0) {
		goto out_unlock;
	}
	if (!(flags & MAP_ANONYMOUS)) {
		vma_mapfile(vma, fd, off << 12, NULL);
	}
	subret = 0;
out_unlock:
	unlock_mm(mm);
	return subret == 0 ? start : -1;
}
Exemple #2
0
int do_mprotect(void *addr, size_t len, int prot)
{

	/*
	   return 0; 
	 */

	struct mm_struct *mm = current->mm;
	assert(mm != NULL);
	if (len == 0) {
		return -E_INVAL;
	}
	uintptr_t start = ROUNDDOWN(addr, PGSIZE);
	uintptr_t end = ROUNDUP(addr + len, PGSIZE);

	int ret = -E_INVAL;
	lock_mm(mm);

	while (1) {
		struct vma_struct *vma = find_vma(mm, start);
		uintptr_t last_end;
		if (vma != NULL) {
			last_end = vma->vm_end;
		}
		if (vma == NULL) {
			goto out;
		} else if (vma->vm_start == start && vma->vm_end == end) {
			if (prot & PROT_WRITE) {
				vma->vm_flags |= VM_WRITE;
			} else {
				vma->vm_flags &= ~VM_WRITE;
			}
		} else {
			uintptr_t this_end =
			    (end <= vma->vm_end) ? end : vma->vm_end;
			uintptr_t this_start =
			    (start >= vma->vm_start) ? start : vma->vm_start;

			struct mapped_file_struct mfile = vma->mfile;
			mfile.offset += this_start - vma->vm_start;
			uint32_t flags = vma->vm_flags;
			if ((ret =
			     mm_unmap_keep_pages(mm, this_start,
						 this_end - this_start)) != 0) {
				goto out;
			}
			if (prot & PROT_WRITE) {
				flags |= VM_WRITE;
			} else {
				flags &= ~VM_WRITE;
			}
			if ((ret =
			     mm_map(mm, this_start, this_end - this_start,
				    flags, &vma)) != 0) {
				goto out;
			}
			vma->mfile = mfile;
			if (vma->mfile.file != NULL) {
				filemap_acquire(mfile.file);
			}
		}

		ret = 0;

		if (end <= last_end)
			break;
		start = last_end;
	}

out:
	unlock_mm(mm);
	return ret;
}