diff options
author | Ted Unangst <tedu@cvs.openbsd.org> | 2003-07-03 00:00:05 +0000 |
---|---|---|
committer | Ted Unangst <tedu@cvs.openbsd.org> | 2003-07-03 00:00:05 +0000 |
commit | 5b289f2a4e23cf2913a693870efa299a200b65e9 (patch) | |
tree | 65a3db511e0d07aaaa8661d36d0da5b201096a6c /sys/compat | |
parent | 3a2e5adbc10e4fc5669fe70b2fbeea41a991caf9 (diff) |
add mmap2 (mmap64, take your pick) and clean up some. use MAP_TRYFIXED
since that's the way linux works. no regressions by various ports testers,
eyeballed by a few others.
Diffstat (limited to 'sys/compat')
-rw-r--r-- | sys/compat/linux/linux_dummy.c | 3 | ||||
-rw-r--r-- | sys/compat/linux/linux_misc.c | 89 | ||||
-rw-r--r-- | sys/compat/linux/syscalls.master | 6 |
3 files changed, 77 insertions, 21 deletions
diff --git a/sys/compat/linux/linux_dummy.c b/sys/compat/linux/linux_dummy.c index 5883b487338..92bd64330e7 100644 --- a/sys/compat/linux/linux_dummy.c +++ b/sys/compat/linux/linux_dummy.c @@ -1,4 +1,4 @@ -/* $OpenBSD: linux_dummy.c,v 1.10 2002/10/30 20:10:48 millert Exp $ */ +/* $OpenBSD: linux_dummy.c,v 1.11 2003/07/03 00:00:04 tedu Exp $ */ /*- * Copyright (c) 1994-1995 Søren Schmidt @@ -108,7 +108,6 @@ DUMMY(capset); /* #185 */ DUMMY(sendfile); /* #187 */ DUMMY(getpmsg); /* #188 */ DUMMY(putpmsg); /* #189 */ -DUMMY(mmap2); /* #192 */ DUMMY(lchown); /* #198 */ DUMMY(setreuid); /* #203 */ DUMMY(setregid); /* #204 */ diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c index 2f8a63b63b6..26948383bc7 100644 --- a/sys/compat/linux/linux_misc.c +++ b/sys/compat/linux/linux_misc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: linux_misc.c,v 1.49 2003/06/21 00:42:58 tedu Exp $ */ +/* $OpenBSD: linux_misc.c,v 1.50 2003/07/03 00:00:04 tedu Exp $ */ /* $NetBSD: linux_misc.c,v 1.27 1996/05/20 01:59:21 fvdl Exp $ */ /* @@ -86,6 +86,8 @@ static void bsd_to_linux_statfs(struct statfs *, struct linux_statfs *); int linux_select1(struct proc *, register_t *, int, fd_set *, fd_set *, fd_set *, struct timeval *); static int getdents_common(struct proc *, void *, register_t *, int); +static void linux_to_bsd_mmap_args(struct sys_mmap_args *, + const struct linux_sys_mmap2_args *); /* * The information on a terminated (or stopped) process needs @@ -607,31 +609,84 @@ linux_sys_mmap(p, v, retval) syscallarg(struct linux_mmap *) lmp; } */ *uap = v; struct linux_mmap lmap; + struct linux_sys_mmap2_args nlmap; struct sys_mmap_args cma; - int error, flags; + int error; if ((error = copyin(SCARG(uap, lmp), &lmap, sizeof lmap))) return error; - flags = 0; - flags |= cvtto_bsd_mask(lmap.lm_flags, LINUX_MAP_SHARED, MAP_SHARED); - flags |= cvtto_bsd_mask(lmap.lm_flags, LINUX_MAP_PRIVATE, MAP_PRIVATE); - flags |= cvtto_bsd_mask(lmap.lm_flags, LINUX_MAP_FIXED, MAP_FIXED); - flags |= cvtto_bsd_mask(lmap.lm_flags, LINUX_MAP_ANON, MAP_ANON); - - SCARG(&cma,addr) = lmap.lm_addr; - SCARG(&cma,len) = lmap.lm_len; - if (lmap.lm_prot & VM_PROT_WRITE) /* XXX */ - lmap.lm_prot |= VM_PROT_READ; - SCARG(&cma,prot) = lmap.lm_prot; - SCARG(&cma,flags) = flags; - SCARG(&cma,fd) = flags & MAP_ANON ? -1 : lmap.lm_fd; - SCARG(&cma,pad) = 0; - SCARG(&cma,pos) = lmap.lm_pos; + if (lmap.lm_pos & PAGE_MASK) + return EINVAL; + + /* repackage into something sane */ + SCARG(&nlmap,addr) = (unsigned long)lmap.lm_addr; + SCARG(&nlmap,len) = lmap.lm_len; + SCARG(&nlmap,prot) = lmap.lm_prot; + SCARG(&nlmap,flags) = lmap.lm_flags; + SCARG(&nlmap,fd) = lmap.lm_fd; + SCARG(&nlmap,offset) = (unsigned)lmap.lm_pos; + + linux_to_bsd_mmap_args(&cma, &nlmap); + SCARG(&cma, pos) = (off_t)SCARG(&nlmap, offset); return sys_mmap(p, &cma, retval); } +/* + * Guts of most architectures' mmap64() implementations. This shares + * its list of arguments with linux_sys_mmap(). + * + * The difference in linux_sys_mmap2() is that "offset" is actually + * (offset / pagesize), not an absolute byte count. This translation + * to pagesize offsets is done inside glibc between the mmap64() call + * point, and the actual syscall. + */ +int +linux_sys_mmap2(p, v, retval) + struct proc *p; + void *v; + register_t *retval; +{ + struct linux_sys_mmap2_args /* { + syscallarg(unsigned long) addr; + syscallarg(size_t) len; + syscallarg(int) prot; + syscallarg(int) flags; + syscallarg(int) fd; + syscallarg(linux_off_t) offset; + } */ *uap = v; + struct sys_mmap_args cma; + + linux_to_bsd_mmap_args(&cma, uap); + SCARG(&cma, pos) = ((off_t)SCARG(uap, offset)) << PAGE_SHIFT; + + return sys_mmap(p, &cma, retval); +} + +static void +linux_to_bsd_mmap_args(cma, uap) + struct sys_mmap_args *cma; + const struct linux_sys_mmap2_args *uap; +{ + int flags = MAP_TRYFIXED, fl = SCARG(uap, flags); + + flags |= cvtto_bsd_mask(fl, LINUX_MAP_SHARED, MAP_SHARED); + flags |= cvtto_bsd_mask(fl, LINUX_MAP_PRIVATE, MAP_PRIVATE); + flags |= cvtto_bsd_mask(fl, LINUX_MAP_FIXED, MAP_FIXED); + flags |= cvtto_bsd_mask(fl, LINUX_MAP_ANON, MAP_ANON); + /* XXX XAX ERH: Any other flags here? There are more defined... */ + + SCARG(cma, addr) = (void *)SCARG(uap, addr); + SCARG(cma, len) = SCARG(uap, len); + SCARG(cma, prot) = SCARG(uap, prot); + if (SCARG(cma, prot) & VM_PROT_WRITE) /* XXX */ + SCARG(cma, prot) |= VM_PROT_READ; + SCARG(cma, flags) = flags; + SCARG(cma, fd) = flags & MAP_ANON ? -1 : SCARG(uap, fd); + SCARG(cma, pad) = 0; +} + int linux_sys_mremap(p, v, retval) struct proc *p; diff --git a/sys/compat/linux/syscalls.master b/sys/compat/linux/syscalls.master index da7e10bf65b..2e94b4397cc 100644 --- a/sys/compat/linux/syscalls.master +++ b/sys/compat/linux/syscalls.master @@ -1,4 +1,4 @@ - $OpenBSD: syscalls.master,v 1.37 2003/05/10 17:53:57 miod Exp $ + $OpenBSD: syscalls.master,v 1.38 2003/07/03 00:00:04 tedu Exp $ ; $NetBSD: syscalls.master,v 1.15 1995/12/18 14:35:10 fvdl Exp $ ; @(#)syscalls.master 8.1 (Berkeley) 7/19/93 @@ -316,7 +316,9 @@ 190 STD { int sys_vfork(void); } 191 STD { int linux_sys_ugetrlimit(u_int which, \ struct linux_rlimit *rlp); } -192 STD { int linux_sys_mmap2(void); } +192 STD { linux_off_t linux_sys_mmap2(unsigned long addr, \ + size_t len, int prot, int flags, int fd, \ + linux_off_t offset); } 193 STD { int linux_sys_truncate64(char *path, \ off_t length); } 194 NOARGS linux_ftruncate64 { int sys_ftruncate(int fd, off_t length); } |