Пример #1
0
static unsigned long get_mmap_base(elf_bin_t *elf)
{
	unsigned long addr, pg_start, pg_end, mmap_min = ULONG_MAX, mmap_max = 0;
	int i;

	for (i=0; i<elf->hdr.e_phnum; i++) 
		if ( elf->phdr[i].p_type == PT_LOAD)
		{
			pg_start = PAGE_BASE(elf->phdr[i].p_vaddr);
			pg_end   = PAGE_NEXT(elf->phdr[i].p_vaddr + elf->phdr[i].p_memsz);

			if (pg_start < mmap_min)
				mmap_min = pg_start;

			if (pg_end > mmap_max)
				mmap_max = pg_end;
		}

	if (mmap_min > mmap_max)
		mmap_min = mmap_max;

	addr = do_mmap2(mmap_min, mmap_max-mmap_min, PROT_NONE,
	                MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);

	if (addr & PG_MASK) /* not on page boundary -> error code */
		return addr;

	sys_munmap(addr, mmap_max-mmap_min);

	return addr-mmap_min;
}
Пример #2
0
/*
 * mmap2() is like mmap() except that the offset is expressed in units
 * of PAGE_SIZE (instead of bytes).  This allows to mmap2() (pieces
 * of) files that are larger than the address space of the CPU.
 */
asmlinkage unsigned long
sys_mmap2 (unsigned long addr, unsigned long len, int prot, int flags, int fd, long pgoff)
{
	addr = do_mmap2(addr, len, prot, flags, fd, pgoff);
	if (!IS_ERR((void *) addr))
		force_successful_syscall_return();
	return addr;
}
Пример #3
0
static int alloc_user_stack(elf_prog_t *prog, int prot)
{
	long err = do_mmap2(prog->task_size-prog->stack_size, prog->stack_size,prot,
	                    MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0);

	if (err & PG_MASK)
		return -1;

	return 0;
}
Пример #4
0
asmlinkage long sys_mmap2(struct mmap_arg_struct *arg)
{
	struct mmap_arg_struct a;
	int error = -EFAULT;

	if (copy_from_user(&a, arg, sizeof(a)))
		goto out;
	error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset);
out:
	return error;
}
Пример #5
0
/*
 * mmap2() is like mmap() except that the offset is expressed in units
 * of PAGE_SIZE (instead of bytes).  This allows to mmap2() (pieces
 * of) files that are larger than the address space of the CPU.
 */
asmlinkage unsigned long
sys_mmap2 (unsigned long addr, unsigned long len, int prot, int flags, int fd, long pgoff,
	   long arg6, long arg7, long stack)
{
	struct pt_regs *regs = (struct pt_regs *) &stack;

	addr = do_mmap2(addr, len, prot, flags, fd, pgoff);
	if (!IS_ERR((void *) addr))
		regs->r8 = 0;	/* ensure large addresses are not mistaken as failures... */
	return addr;
}
Пример #6
0
static long zerofill(unsigned long start, unsigned long end, int prot)
{
	unsigned long pg_start = PAGE_NEXT(start),
	              pg_end   = PAGE_NEXT(end),
	              padd_len = pg_start-start;

	if (start > end)
		return -1;

	if (prot & PROT_WRITE)
		memset((void *)start, 0, padd_len);

	return do_mmap2(pg_start, pg_end-pg_start, prot,
	                MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0);
}
Пример #7
0
static long mmap_prog_section(elf_bin_t *elf, Elf32_Phdr *p)
{
	unsigned long base = elf->base, brk_, bss, addr, pg_off, size;
	int prot = 0;

	if (p->p_flags & PF_R)
		prot |= PROT_READ;		
	if (p->p_flags & PF_W)
		prot |= PROT_WRITE;		
	if (p->p_flags & PF_X)
		prot |= PROT_EXEC;

	addr = PAGE_BASE(base+p->p_vaddr);
	size = PAGE_NEXT(base+p->p_vaddr + p->p_filesz) - addr;
	pg_off = p->p_offset/PG_SIZE;

	bss = base + p->p_vaddr + p->p_filesz;
	brk_ = base + p->p_vaddr + p->p_memsz;

	if ( ((p->p_vaddr-p->p_offset) & PG_MASK) || (bss > brk_) )
		return -1;

	addr = do_mmap2(addr, size, prot, MAP_PRIVATE|MAP_FIXED, elf->fd, pg_off);

	if (addr & PG_MASK) /* not on page boundary -> error code */
		return addr;

	if (elf->brk < brk_)
		elf->brk = brk_;

	if (elf->bss < bss)
		elf->bss = bss;

	/* linux does not fill in bss sections
	 * between load segments for interpreters;
	 * makes no difference to the standard ld.so
	 */
	addr = zerofill(bss, brk_, prot);

	if (addr & PG_MASK) /* not on page boundary -> error code */
		return addr;

	return 0;
}
Пример #8
0
asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
    unsigned long prot, unsigned long flags,
    unsigned long fd, unsigned long pgoff)
{
    return do_mmap2(addr, len, prot, flags, fd, pgoff);
}
Пример #9
0
long sys_mmap2(unsigned long addr, unsigned long len,
	       unsigned long prot, unsigned long flags,
	       unsigned long fd, unsigned long pgoff)
{
	return do_mmap2(current->mm, addr, len, prot, flags, fd, pgoff);
}
Пример #10
0
unsigned long sys_mmap2(unsigned long addr, size_t len,
			unsigned long prot, unsigned long flags,
			unsigned long fd, unsigned long pgoff)
{
	return do_mmap2(addr, len, prot, flags, fd, pgoff);
}