summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/compat/linux/linux_dummy.c3
-rw-r--r--sys/compat/linux/linux_misc.c89
-rw-r--r--sys/compat/linux/syscalls.master6
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); }