Sync usage with man page.
[netbsd-mini2440.git] / sys / compat / osf1 / osf1_mmap.c
blob34eeba2c792ea926f2e9dfbd67fca8a4a0df898b
1 /* $NetBSD: osf1_mmap.c,v 1.13 2007/12/20 23:03:03 dsl Exp $ */
3 /*
4 * Copyright (c) 1999 Christopher G. Demetriou. All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. All advertising materials mentioning features or use of this software
15 * must display the following acknowledgement:
16 * This product includes software developed by Christopher G. Demetriou
17 * for the NetBSD Project.
18 * 4. The name of the author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 #include <sys/cdefs.h>
34 __KERNEL_RCSID(0, "$NetBSD: osf1_mmap.c,v 1.13 2007/12/20 23:03:03 dsl Exp $");
36 #include <sys/param.h>
37 #include <sys/systm.h>
38 #include <sys/proc.h>
39 #include <sys/mman.h>
40 #include <sys/mount.h>
41 #include <sys/syscallargs.h>
42 #include <uvm/uvm.h> /* XXX see mmap emulation */
44 #include <compat/osf1/osf1.h>
45 #include <compat/osf1/osf1_syscallargs.h>
46 #include <compat/osf1/osf1_cvt.h>
48 int
49 osf1_sys_madvise(struct lwp *l, const struct osf1_sys_madvise_args *uap, register_t *retval)
51 struct sys_madvise_args a;
52 int error;
54 SCARG(&a, addr) = SCARG(uap, addr);
55 SCARG(&a, len) = SCARG(uap, len);
57 error = 0;
58 switch (SCARG(uap, behav)) {
59 case OSF1_MADV_NORMAL:
60 SCARG(&a, behav) = MADV_NORMAL;
61 break;
63 case OSF1_MADV_RANDOM:
64 SCARG(&a, behav) = MADV_RANDOM;
65 break;
67 case OSF1_MADV_SEQUENTIAL:
68 SCARG(&a, behav) = MADV_SEQUENTIAL;
69 break;
71 case OSF1_MADV_WILLNEED:
72 SCARG(&a, behav) = MADV_WILLNEED;
73 break;
75 case OSF1_MADV_DONTNEED_COMPAT:
76 SCARG(&a, behav) = MADV_DONTNEED;
77 break;
79 case OSF1_MADV_SPACEAVAIL:
80 SCARG(&a, behav) = MADV_SPACEAVAIL;
81 break;
83 case OSF1_MADV_DONTNEED:
85 * XXX not supported. In Digital UNIX, this flushes all
86 * XXX data in the region and replaces it with ZFOD pages.
88 error = EINVAL;
89 break;
91 default:
92 error = EINVAL;
93 break;
96 if (error == 0) {
97 error = sys_madvise(l, &a, retval);
100 * NetBSD madvise() currently always returns ENOSYS.
101 * Digital UNIX says that non-operational requests (i.e.
102 * valid, but unimplemented 'behav') will return success.
104 if (error == ENOSYS)
105 error = 0;
107 return (error);
111 osf1_sys_mmap(struct lwp *l, const struct osf1_sys_mmap_args *uap, register_t *retval)
113 struct proc *p = l->l_proc;
114 struct sys_mmap_args a;
115 unsigned long leftovers;
117 SCARG(&a, addr) = SCARG(uap, addr);
118 SCARG(&a, len) = SCARG(uap, len);
119 SCARG(&a, fd) = SCARG(uap, fd);
120 SCARG(&a, PAD) = 0;
121 SCARG(&a, pos) = SCARG(uap, pos);
123 /* translate prot */
124 SCARG(&a, prot) = emul_flags_translate(osf1_mmap_prot_xtab,
125 SCARG(uap, prot), &leftovers);
126 if (leftovers != 0)
127 return (EINVAL);
129 /* translate flags */
130 SCARG(&a, flags) = emul_flags_translate(osf1_mmap_flags_xtab,
131 SCARG(uap, flags), &leftovers);
132 if (leftovers != 0)
133 return (EINVAL);
136 * XXX The following code is evil.
138 * The OSF/1 mmap() function attempts to map non-fixed entries
139 * near the address that the user specified. Therefore, for
140 * non-fixed entires we try to find space in the address space
141 * starting at that address. If the user specified zero, we
142 * start looking at at least PAGE_SIZE, so that programs can't
143 * accidentally live through deferencing NULL.
145 * The need for this kludgery is increased by the fact that
146 * the loader data segment is mapped at
147 * (end of user address space) - 1G, MAXDSIZ is 1G, and
148 * the VM system tries allocate non-fixed mappings _AFTER_
149 * (start of data) + MAXDSIZ. With the loader, of course,
150 * that means that it'll start trying at
151 * (end of user address space), and will never succeed!
153 * Notes:
155 * * Though we find space here, if something else (e.g. a second
156 * thread) were mucking with the address space the mapping
157 * we found might be used by another mmap(), and this call
158 * would clobber that region.
160 * * In general, tricks like this only work for MAP_ANON mappings,
161 * because of sharing/cache issues. That's not a problem on
162 * the Alpha, and though it's not good style to abuse that fact,
163 * there's little choice.
165 * * In order for this to be done right, the VM system should
166 * really try to use the requested 'addr' passed in to mmap()
167 * as a hint, even if non-fixed. If it's passed as zero,
168 * _maybe_ then try (start of data) + MAXDSIZ, or maybe
169 * provide a better way to avoid the data region altogether.
171 if ((SCARG(&a, flags) & MAP_FIXED) == 0) {
172 vaddr_t addr = round_page((vaddr_t)SCARG(&a, addr));
173 vsize_t size = round_page((vsize_t)SCARG(&a, len));
174 int fixed = 0;
176 vm_map_lock(&p->p_vmspace->vm_map);
178 /* if non-NULL address given, start looking there */
179 if (addr != 0 && uvm_map_findspace(&p->p_vmspace->vm_map,
180 addr, size, &addr, NULL, 0, 0, 0) != NULL) {
181 fixed = 1;
182 goto done;
185 /* didn't find anything. take it again from the top. */
186 if (uvm_map_findspace(&p->p_vmspace->vm_map, PAGE_SIZE, size,
187 &addr, NULL, 0, 0, 0) != NULL) {
188 fixed = 1;
189 goto done;
192 done:
193 vm_map_unlock(&p->p_vmspace->vm_map);
194 if (fixed) {
195 SCARG(&a, flags) |= MAP_FIXED;
196 SCARG(&a, addr) = (void *)addr;
200 return sys_mmap(l, &a, retval);
204 osf1_sys_mprotect(struct lwp *l, const struct osf1_sys_mprotect_args *uap, register_t *retval)
206 struct sys_mprotect_args a;
207 unsigned long leftovers;
209 SCARG(&a, addr) = SCARG(uap, addr);
210 SCARG(&a, len) = SCARG(uap, len);
212 /* translate prot */
213 SCARG(&a, prot) = emul_flags_translate(osf1_mmap_prot_xtab,
214 SCARG(uap, prot), &leftovers);
215 if (leftovers != 0)
216 return (EINVAL);
218 return sys_mprotect(l, &a, retval);