1 /* $NetBSD: irix_mman.c,v 1.22 2008/04/28 20:23:41 martin Exp $ */
4 * Copyright (c) 2002, 2008 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: irix_mman.c,v 1.22 2008/04/28 20:23:41 martin Exp $");
35 #if defined(_KERNEL_OPT)
39 #include <sys/types.h>
40 #include <sys/param.h>
41 #include <sys/signal.h>
44 #include <sys/filedesc.h>
46 #include <sys/vnode.h>
47 #include <sys/vnode_if.h>
48 #include <sys/mount.h>
49 #include <sys/rwlock.h>
50 #include <sys/systm.h>
51 #include <sys/syscallargs.h>
53 #include <compat/svr4/svr4_types.h>
54 #include <compat/svr4/svr4_lwp.h>
55 #include <compat/svr4/svr4_ucontext.h>
56 #include <compat/svr4/svr4_signal.h>
57 #include <compat/svr4/svr4_syscallargs.h>
59 #include <compat/irix/irix_types.h>
60 #include <compat/irix/irix_signal.h>
61 #include <compat/irix/irix_mman.h>
62 #include <compat/irix/irix_prctl.h>
63 #include <compat/irix/irix_exec.h>
64 #include <compat/irix/irix_syscallargs.h>
66 static int irix_mmap(struct lwp
*, void *, size_t, int ,
67 int, int, off_t
, register_t
*);
70 irix_sys_mmap(struct lwp
*l
, const struct irix_sys_mmap_args
*uap
, register_t
*retval
)
73 syscallarg(void *) addr;
74 syscallarg(irix_size_t) len;
76 syscallarg(int) flags;
78 syscallarg(irix_off_t) pos;
81 return irix_mmap(l
, SCARG(uap
, addr
), SCARG(uap
, len
),
82 SCARG(uap
, prot
), SCARG(uap
, flags
), SCARG(uap
, fd
),
83 SCARG(uap
, pos
), retval
);
87 irix_sys_mmap64(struct lwp
*l
, const struct irix_sys_mmap64_args
*uap
, register_t
*retval
)
90 syscallarg(void *) addr;
91 syscallarg(irix_size_t) len;
93 syscallarg(int) flags;
96 syscallarg(irix_off64_t) pos;
99 return irix_mmap(l
, SCARG(uap
, addr
), SCARG(uap
, len
),
100 SCARG(uap
, prot
), SCARG(uap
, flags
), SCARG(uap
, fd
),
101 SCARG(uap
, pos
), retval
);
105 irix_mmap(struct lwp
*l
, void *addr
, size_t len
, int prot
, int flags
, int fd
, off_t pos
, register_t
*retval
)
107 struct proc
*p
= l
->l_proc
;
108 struct sys_mmap_args cup
;
113 printf("irix_sys_mmap(): addr = %p, len = 0x%x, prot = 0x%x ",
115 printf("flags = 0x%x, fd = %d, pos = 0x%lx\n", flags
, fd
, (long)pos
);
118 if (flags
& IRIX_MAP_SHARED
)
119 bsd_flags
|= MAP_SHARED
;
120 if (flags
& IRIX_MAP_PRIVATE
)
121 bsd_flags
|= MAP_PRIVATE
;
122 if (flags
& IRIX_MAP_COPY
)
123 bsd_flags
|= MAP_PRIVATE
;
126 * Note about MAP_FIXED: IRIX's mmap(2) states that
127 * when MAP_FIXED is unset, range 0x30000000 to 0x40000000
128 * will not be used except if MAP_SGI_ANYADDR is set
129 * or if syssgi(SGI_UNSUPPORTED_MAP_RESERVED_RANGE) was
130 * enabled. We do not emulate this behavior for now.
132 if (flags
& IRIX_MAP_FIXED
)
133 bsd_flags
|= MAP_FIXED
;
134 if (flags
& IRIX_MAP_RENAME
)
135 bsd_flags
|= MAP_RENAME
;
137 if (flags
& IRIX_MAP_AUTORESRV
)
138 printf("Warning: unsupported IRIX mmap() flag MAP_AUTORESV\n");
139 if (flags
& IRIX_MAP_TEXT
)
140 printf("Warning: unsupported IRIX mmap() flag MAP_TEXT\n");
141 if (flags
& IRIX_MAP_BRK
)
142 printf("Warning: unsupported IRIX mmap() flag MAP_BRK\n");
143 if (flags
& IRIX_MAP_PRIMARY
)
144 printf("Warning: unsupported IRIX mmap() flag MAP_PRIMARY\n");
145 if (flags
& IRIX_MAP_SGI_ANYADDR
)
146 printf("Warning: unsupported IRIX mmap() flag IRIX_MAP_SGI_ANYADDR\n");
149 * When AUTOGROW is set and the mapping is bigger than
150 * the file, if pages beyond the end of file are touched,
151 * IRIX will increase the file size accordingly. We are
152 * not able to emulate this (yet), hence we immediatly
153 * grow the file to fit the mapping, before mapping it.
155 if (flags
& IRIX_MAP_AUTOGROW
) {
160 if ((error
= fd_getvnode(fd
, &fp
)) != 0)
163 if ((fp
->f_flag
& FWRITE
) == 0) {
169 if (vp
->v_type
== VFIFO
) {
174 if (vp
->v_type
== VDIR
) {
179 if ((error
= VOP_GETATTR(vp
, &vattr
, l
->l_cred
)) != 0)
182 if (pos
+ len
> vattr
.va_size
) {
184 vattr
.va_size
= round_page(pos
+ len
);
186 vn_lock(vp
, LK_EXCLUSIVE
| LK_RETRY
);
188 error
= VOP_SETATTR(vp
, &vattr
, l
->l_cred
);
199 SCARG(&cup
, addr
) = addr
;
200 SCARG(&cup
, len
) = len
;
201 SCARG(&cup
, prot
) = prot
;
202 SCARG(&cup
, flags
) = bsd_flags
;
203 SCARG(&cup
, fd
) = fd
;
204 SCARG(&cup
, pos
) = pos
;
206 /* A private mapping that should not be visible to the share group */
207 if (flags
& IRIX_MAP_LOCAL
) {
208 if ((error
= sys_mmap(l
, &cup
, retval
)) != 0)
210 addr
= (void *)*retval
;
211 irix_isrr_insert((vaddr_t
)addr
, len
, IRIX_ISRR_PRIVATE
, p
);
215 IRIX_VM_SYNC(p
, error
= sys_mmap(l
, &cup
, retval
));
221 irix_sys_munmap(struct lwp
*l
, const struct irix_sys_munmap_args
*uap
, register_t
*retval
)
224 syscallarg(void *) addr;
225 syscallarg(size_t) len;
227 struct proc
*p
= l
->l_proc
;
230 IRIX_VM_SYNC(p
, error
= sys_munmap(l
, (const void *)uap
, retval
));
232 irix_isrr_insert((vaddr_t
)SCARG(uap
, addr
),
233 SCARG(uap
, len
), IRIX_ISRR_SHARED
, p
);
239 irix_sys_break(struct lwp
*l
, const struct irix_sys_break_args
*uap
, register_t
*retval
)
241 struct proc
*p
= l
->l_proc
;
244 IRIX_VM_SYNC(p
, error
= svr4_sys_break(l
, (const void *)uap
, retval
));
250 irix_sys_shmsys(struct lwp
*l
, const struct irix_sys_shmsys_args
*uap
, register_t
*retval
)
252 struct proc
*p
= l
->l_proc
;
255 IRIX_VM_SYNC(p
, error
= svr4_sys_shmsys(l
, (const void *)uap
, retval
));
261 irix_sys_mprotect(struct lwp
*l
, const struct irix_sys_mprotect_args
*uap
, register_t
*retval
)
263 struct proc
*p
= l
->l_proc
;
266 IRIX_VM_SYNC(p
, error
= sys_mprotect(l
, (const void *)uap
, retval
));