From 22d86f6686970a1473984a743135d9ea0fe0a30f Mon Sep 17 00:00:00 2001 From: "David P. Reese, Jr." Date: Sat, 15 Nov 2003 03:52:33 +0000 Subject: [PATCH] Implement linux_mmap2(). FreeBSD PR: kern/45785 --- sys/emulation/linux/i386/linux_dummy.c | 3 +- sys/emulation/linux/i386/linux_machdep.c | 150 ++++++++++++++--------- sys/emulation/linux/i386/linux_sysvec.c | 3 +- 3 files changed, 96 insertions(+), 60 deletions(-) diff --git a/sys/emulation/linux/i386/linux_dummy.c b/sys/emulation/linux/i386/linux_dummy.c index 927757839e..8b94be388f 100644 --- a/sys/emulation/linux/i386/linux_dummy.c +++ b/sys/emulation/linux/i386/linux_dummy.c @@ -26,7 +26,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD: src/sys/i386/linux/linux_dummy.c,v 1.21.2.7 2003/01/02 20:41:33 kan Exp $ - * $DragonFly: src/sys/emulation/linux/i386/linux_dummy.c,v 1.4 2003/11/15 03:23:34 daver Exp $ + * $DragonFly: src/sys/emulation/linux/i386/linux_dummy.c,v 1.5 2003/11/15 03:52:33 daver Exp $ */ #include @@ -65,7 +65,6 @@ DUMMY(rt_sigqueueinfo); DUMMY(capget); DUMMY(capset); DUMMY(sendfile); -DUMMY(mmap2); DUMMY(setfsuid); DUMMY(setfsgid); DUMMY(pivot_root); diff --git a/sys/emulation/linux/i386/linux_machdep.c b/sys/emulation/linux/i386/linux_machdep.c index d0013e9d36..9b6ba30eee 100644 --- a/sys/emulation/linux/i386/linux_machdep.c +++ b/sys/emulation/linux/i386/linux_machdep.c @@ -26,7 +26,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD: src/sys/i386/linux/linux_machdep.c,v 1.6.2.4 2001/11/05 19:08:23 marcel Exp $ - * $DragonFly: src/sys/emulation/linux/i386/linux_machdep.c,v 1.11 2003/11/13 04:04:42 daver Exp $ + * $DragonFly: src/sys/emulation/linux/i386/linux_machdep.c,v 1.12 2003/11/15 03:52:33 daver Exp $ */ #include @@ -444,40 +444,30 @@ struct l_mmap_argv { #define STACK_SIZE (2 * 1024 * 1024) #define GUARD_SIZE (4 * PAGE_SIZE) -int -linux_mmap(struct linux_mmap_args *args) +static int +linux_mmap_common(caddr_t linux_addr, size_t linux_len, int linux_prot, + int linux_flags, int linux_fd, off_t pos, void **res) { - struct proc *p = curproc; - struct mmap_args bsd_args; - int error; - struct l_mmap_argv linux_args; - - error = copyin((caddr_t)args->ptr, &linux_args, sizeof(linux_args)); - if (error) - return (error); - -#ifdef DEBUG - if (ldebug(mmap)) - printf(ARGS(mmap, "%p, %d, %d, 0x%08x, %d, %d"), - (void *)linux_args.addr, linux_args.len, linux_args.prot, - linux_args.flags, linux_args.fd, linux_args.pos); -#endif - - bsd_args.flags = 0; - bsd_args.sysmsg_resultp = NULL; - if (linux_args.flags & LINUX_MAP_SHARED) - bsd_args.flags |= MAP_SHARED; - if (linux_args.flags & LINUX_MAP_PRIVATE) - bsd_args.flags |= MAP_PRIVATE; - if (linux_args.flags & LINUX_MAP_FIXED) - bsd_args.flags |= MAP_FIXED; - if (linux_args.flags & LINUX_MAP_ANON) - bsd_args.flags |= MAP_ANON; - else - bsd_args.flags |= MAP_NOSYNC; - if (linux_args.flags & LINUX_MAP_GROWSDOWN) { - bsd_args.flags |= MAP_STACK; - + struct thread *td = curthread; + struct proc *p = td->td_proc; + caddr_t addr; + void *new; + int error, flags, len, prot, fd; + + flags = 0; + if (linux_flags & LINUX_MAP_SHARED) + flags |= MAP_SHARED; + if (linux_flags & LINUX_MAP_PRIVATE) + flags |= MAP_PRIVATE; + if (linux_flags & LINUX_MAP_FIXED) + flags |= MAP_FIXED; + if (linux_flags & LINUX_MAP_ANON) { + flags |= MAP_ANON; + } else { + flags |= MAP_NOSYNC; + } + if (linux_flags & LINUX_MAP_GROWSDOWN) { + flags |= MAP_STACK; /* The linux MAP_GROWSDOWN option does not limit auto * growth of the region. Linux mmap with this option * takes as addr the inital BOS, and as len, the initial @@ -500,9 +490,9 @@ linux_mmap(struct linux_mmap_args *args) */ /* This gives us TOS */ - bsd_args.addr = linux_args.addr + linux_args.len; + addr = linux_addr + linux_len; - if (bsd_args.addr > p->p_vmspace->vm_maxsaddr) { + if (addr > p->p_vmspace->vm_maxsaddr) { /* Some linux apps will attempt to mmap * thread stacks near the top of their * address space. If their TOS is greater @@ -523,43 +513,89 @@ linux_mmap(struct linux_mmap_args *args) } /* This gives us our maximum stack size */ - if (linux_args.len > STACK_SIZE - GUARD_SIZE) - bsd_args.len = linux_args.len; - else - bsd_args.len = STACK_SIZE - GUARD_SIZE; - + if (linux_len > STACK_SIZE - GUARD_SIZE) { + len = linux_len; + } else { + len = STACK_SIZE - GUARD_SIZE; + } /* This gives us a new BOS. If we're using VM_STACK, then * mmap will just map the top SGROWSIZ bytes, and let * the stack grow down to the limit at BOS. If we're * not using VM_STACK we map the full stack, since we * don't have a way to autogrow it. */ - bsd_args.addr -= bsd_args.len; + addr -= len; + } else { + addr = linux_addr; + len = linux_len; + } + + prot = linux_prot | PROT_READ; + if (linux_flags & LINUX_MAP_ANON) { + fd = -1; } else { - bsd_args.addr = linux_args.addr; - bsd_args.len = linux_args.len; + fd = linux_fd; } + +#ifdef DEBUG + if (ldebug(mmap) || ldebug(mmap2)) + printf("-> (%p, %d, %d, 0x%08x, %d, %lld)\n", + addr, len, prot, flags, fd, pos); +#endif + error = kern_mmap(addr, len, prot, flags, fd, pos, &new); + + if (error == 0) + *res = new; + return (error); +} - bsd_args.prot = linux_args.prot | PROT_READ; /* always required */ - if (linux_args.flags & LINUX_MAP_ANON) - bsd_args.fd = -1; - else - bsd_args.fd = linux_args.fd; - bsd_args.pos = linux_args.pos; - bsd_args.pad = 0; +int +linux_mmap(struct linux_mmap_args *args) +{ + struct l_mmap_argv linux_args; + int error; + error = copyin((caddr_t)args->ptr, &linux_args, sizeof(linux_args)); + if (error) + return (error); + +#ifdef DEBUG + if (ldebug(mmap)) + printf(ARGS(mmap, "%p, %d, %d, 0x%08x, %d, %d"), + (void *)linux_args.addr, linux_args.len, linux_args.prot, + linux_args.flags, linux_args.fd, linux_args.pos); +#endif + error = linux_mmap_common(linux_args.addr, linux_args.len, + linux_args.prot, linux_args.flags, linux_args.fd, + linux_args.pos, &args->sysmsg_resultp); #ifdef DEBUG if (ldebug(mmap)) - printf("-> (%p, %d, %d, 0x%08x, %d, %d)\n", - (void *)bsd_args.addr, bsd_args.len, bsd_args.prot, - bsd_args.flags, bsd_args.fd, (int)bsd_args.pos); + printf("-> %p\n", args->sysmsg_resultp); #endif - - error = mmap(&bsd_args); - args->sysmsg_resultp = bsd_args.sysmsg_resultp; return(error); } +int +linux_mmap2(struct linux_mmap2_args *args) +{ + int error; + +#ifdef DEBUG + if (ldebug(mmap2)) + printf(ARGS(mmap2, "%p, %d, %d, 0x%08x, %d, %d"), + (void *)args->addr, args->len, args->prot, args->flags, + args->fd, args->pgoff); +#endif + error = linux_mmap_common((void *)args->addr, args->len, args->prot, + args->flags, args->fd, args->pgoff * PAGE_SIZE, + &args->sysmsg_resultp); +#ifdef DEBUG + if (ldebug(mmap2)) + printf("-> %p\n", args->sysmsg_resultp); +#endif + return (error); +} + int linux_pipe(struct linux_pipe_args *args) { diff --git a/sys/emulation/linux/i386/linux_sysvec.c b/sys/emulation/linux/i386/linux_sysvec.c index 5a6bd3f10b..9f447aaa18 100644 --- a/sys/emulation/linux/i386/linux_sysvec.c +++ b/sys/emulation/linux/i386/linux_sysvec.c @@ -26,7 +26,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD: src/sys/i386/linux/linux_sysvec.c,v 1.55.2.9 2002/01/12 11:03:30 bde Exp $ - * $DragonFly: src/sys/emulation/linux/i386/linux_sysvec.c,v 1.14 2003/11/14 21:18:41 daver Exp $ + * $DragonFly: src/sys/emulation/linux/i386/linux_sysvec.c,v 1.15 2003/11/15 03:52:33 daver Exp $ */ /* XXX we use functions that might not exist. */ @@ -717,6 +717,7 @@ linux_prepsyscall(struct trapframe *tf, int *args, u_int *code, caddr_t *params) args[2] = tf->tf_edx; args[3] = tf->tf_esi; args[4] = tf->tf_edi; + args[5] = tf->tf_ebp; *params = NULL; /* no copyin */ } -- 2.41.0