xref: /netbsd-src/sys/compat/netbsd32/netbsd32_compat_43.c (revision 1ca5c1b28139779176bd5c13ad7c5f25c0bcd5f8)
1 /*	$NetBSD: netbsd32_compat_43.c,v 1.20 2001/11/13 02:09:05 lukem Exp $	*/
2 
3 /*
4  * Copyright (c) 1998, 2001 Matthew R. Green
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. The name of the author may not be used to endorse or promote products
16  *    derived from this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
23  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
25  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  */
30 
31 #include <sys/cdefs.h>
32 __KERNEL_RCSID(0, "$NetBSD: netbsd32_compat_43.c,v 1.20 2001/11/13 02:09:05 lukem Exp $");
33 
34 #if defined(_KERNEL_OPT)
35 #include "opt_compat_43.h"
36 #endif
37 
38 #include <sys/param.h>
39 #include <sys/systm.h>
40 #include <sys/fcntl.h>
41 #include <sys/malloc.h>
42 #include <sys/mount.h>
43 #include <sys/proc.h>
44 #include <sys/stat.h>
45 #include <sys/syscallargs.h>
46 #include <sys/time.h>
47 #include <sys/ucred.h>
48 #include <uvm/uvm_extern.h>
49 #include <sys/sysctl.h>
50 #include <sys/swap.h>
51 
52 #include <compat/netbsd32/netbsd32.h>
53 #include <compat/netbsd32/netbsd32_syscallargs.h>
54 
55 int compat_43_netbsd32_sethostid __P((struct proc *, void *, register_t *));
56 int compat_43_netbsd32_killpg __P((struct proc *, void *, register_t *retval));
57 int compat_43_netbsd32_sigblock __P((struct proc *, void *, register_t *retval));
58 int compat_43_netbsd32_sigblock __P((struct proc *, void *, register_t *retval));
59 
60 void
61 netbsd32_from_stat43(sp43, sp32)
62 	struct stat43 *sp43;
63 	struct netbsd32_stat43 *sp32;
64 {
65 
66 	sp32->st_dev = sp43->st_dev;
67 	sp32->st_ino = sp43->st_ino;
68 	sp32->st_mode = sp43->st_mode;
69 	sp32->st_nlink = sp43->st_nlink;
70 	sp32->st_uid = sp43->st_uid;
71 	sp32->st_gid = sp43->st_gid;
72 	sp32->st_rdev = sp43->st_rdev;
73 	sp32->st_size = sp43->st_size;
74 	sp32->st_atimespec.tv_sec = sp43->st_atimespec.tv_sec;
75 	sp32->st_atimespec.tv_nsec = sp43->st_atimespec.tv_nsec;
76 	sp32->st_mtimespec.tv_sec = sp43->st_mtimespec.tv_sec;
77 	sp32->st_mtimespec.tv_nsec = sp43->st_mtimespec.tv_nsec;
78 	sp32->st_ctimespec.tv_sec = sp43->st_ctimespec.tv_sec;
79 	sp32->st_ctimespec.tv_nsec = sp43->st_ctimespec.tv_nsec;
80 	sp32->st_blksize = sp43->st_blksize;
81 	sp32->st_blocks = sp43->st_blocks;
82 	sp32->st_flags = sp43->st_flags;
83 	sp32->st_gen = sp43->st_gen;
84 }
85 
86 /* file system syscalls */
87 int
88 compat_43_netbsd32_ocreat(p, v, retval)
89 	struct proc *p;
90 	void *v;
91 	register_t *retval;
92 {
93 	struct compat_43_netbsd32_ocreat_args /* {
94 		syscallarg(const netbsd32_charp) path;
95 		syscallarg(mode_t) mode;
96 	} */ *uap = v;
97 	struct sys_open_args  ua;
98 	caddr_t sg;
99 
100 	NETBSD32TOP_UAP(path, const char);
101 	NETBSD32TO64_UAP(mode);
102 	SCARG(&ua, flags) = O_WRONLY | O_CREAT | O_TRUNC;
103 	sg = stackgap_init(p->p_emul);
104 	CHECK_ALT_EXIST(p, &sg, SCARG(&ua, path));
105 
106 	return (sys_open(p, &ua, retval));
107 }
108 
109 int
110 compat_43_netbsd32_olseek(p, v, retval)
111 	struct proc *p;
112 	void *v;
113 	register_t *retval;
114 {
115 	struct compat_43_netbsd32_olseek_args /* {
116 		syscallarg(int) fd;
117 		syscallarg(netbsd32_long) offset;
118 		syscallarg(int) whence;
119 	} */ *uap = v;
120 	struct sys_lseek_args ua;
121 	int rv;
122 	off_t rt;
123 
124 	SCARG(&ua, fd) = SCARG(uap, fd);
125 	NETBSD32TOX_UAP(offset, long);
126 	NETBSD32TO64_UAP(whence);
127 	rv = sys_lseek(p, &ua, (register_t *)&rt);
128 	*retval = rt;
129 
130 	return (rv);
131 }
132 
133 int
134 compat_43_netbsd32_stat43(p, v, retval)
135 	struct proc *p;
136 	void *v;
137 	register_t *retval;
138 {
139 	struct compat_43_netbsd32_stat43_args /* {
140 		syscallarg(const netbsd32_charp) path;
141 		syscallarg(netbsd32_stat43p_t) ub;
142 	} */ *uap = v;
143 	struct stat43 sb43, *sgsbp;
144 	struct netbsd32_stat43 sb32;
145 	struct compat_43_sys_stat_args ua;
146 	caddr_t sg = stackgap_init(p->p_emul);
147 	int rv, error;
148 
149 	NETBSD32TOP_UAP(path, const char);
150 	SCARG(&ua, ub) = sgsbp = stackgap_alloc(&sg, sizeof(sb43));
151 	CHECK_ALT_EXIST(p, &sg, SCARG(&ua, path));
152 	rv = compat_43_sys_stat(p, &ua, retval);
153 
154 	error = copyin(sgsbp, &sb43, sizeof(sb43));
155 	if (error)
156 		return error;
157 	netbsd32_from_stat43(&sb43, &sb32);
158 	error = copyout(&sb32, (char *)(u_long)SCARG(uap, ub), sizeof(sb32));
159 	if (error)
160 		return error;
161 
162 	return (rv);
163 }
164 
165 int
166 compat_43_netbsd32_lstat43(p, v, retval)
167 	struct proc *p;
168 	void *v;
169 	register_t *retval;
170 {
171 	struct compat_43_netbsd32_lstat43_args /* {
172 		syscallarg(const netbsd32_charp) path;
173 		syscallarg(netbsd32_stat43p_t) ub;
174 	} */ *uap = v;
175 	struct stat43 sb43, *sgsbp;
176 	struct netbsd32_stat43 sb32;
177 	struct compat_43_sys_lstat_args ua;
178 	caddr_t sg = stackgap_init(p->p_emul);
179 	int rv, error;
180 
181 	NETBSD32TOP_UAP(path, const char);
182 	SCARG(&ua, ub) = sgsbp = stackgap_alloc(&sg, sizeof(sb43));
183 	CHECK_ALT_EXIST(p, &sg, SCARG(&ua, path));
184 	rv = compat_43_sys_stat(p, &ua, retval);
185 
186 	error = copyin(sgsbp, &sb43, sizeof(sb43));
187 	if (error)
188 		return error;
189 	netbsd32_from_stat43(&sb43, &sb32);
190 	error = copyout(&sb32, (char *)(u_long)SCARG(uap, ub), sizeof(sb32));
191 	if (error)
192 		return error;
193 
194 	return (rv);
195 }
196 
197 int
198 compat_43_netbsd32_fstat43(p, v, retval)
199 	struct proc *p;
200 	void *v;
201 	register_t *retval;
202 {
203 	struct compat_43_netbsd32_fstat43_args /* {
204 		syscallarg(int) fd;
205 		syscallarg(netbsd32_stat43p_t) sb;
206 	} */ *uap = v;
207 	struct stat43 sb43, *sgsbp;
208 	struct netbsd32_stat43 sb32;
209 	struct compat_43_sys_fstat_args ua;
210 	caddr_t sg = stackgap_init(p->p_emul);
211 	int rv, error;
212 
213 	NETBSD32TO64_UAP(fd);
214 	SCARG(&ua, sb) = sgsbp = stackgap_alloc(&sg, sizeof(sb43));
215 	rv = compat_43_sys_fstat(p, &ua, retval);
216 
217 	error = copyin(sgsbp, &sb43, sizeof(sb43));
218 	if (error)
219 		return error;
220 	netbsd32_from_stat43(&sb43, &sb32);
221 	error = copyout(&sb32, (char *)(u_long)SCARG(uap, sb), sizeof(sb32));
222 	if (error)
223 		return error;
224 
225 	return (rv);
226 }
227 
228 int
229 compat_43_netbsd32_otruncate(p, v, retval)
230 	struct proc *p;
231 	void *v;
232 	register_t *retval;
233 {
234 	struct compat_43_netbsd32_otruncate_args /* {
235 		syscallarg(const netbsd32_charp) path;
236 		syscallarg(netbsd32_long) length;
237 	} */ *uap = v;
238 	struct sys_truncate_args ua;
239 
240 	NETBSD32TOP_UAP(path, const char);
241 	NETBSD32TO64_UAP(length);
242 	return (sys_ftruncate(p, &ua, retval));
243 }
244 
245 int
246 compat_43_netbsd32_oftruncate(p, v, retval)
247 	struct proc *p;
248 	void *v;
249 	register_t *retval;
250 {
251 	struct compat_43_netbsd32_oftruncate_args /* {
252 		syscallarg(int) fd;
253 		syscallarg(netbsd32_long) length;
254 	} */ *uap = v;
255 	struct sys_ftruncate_args ua;
256 
257 	NETBSD32TO64_UAP(fd);
258 	NETBSD32TO64_UAP(length);
259 	return (sys_ftruncate(p, &ua, retval));
260 }
261 
262 int
263 compat_43_netbsd32_ogetdirentries(p, v, retval)
264 	struct proc *p;
265 	void *v;
266 	register_t *retval;
267 {
268 	struct compat_43_netbsd32_ogetdirentries_args /* {
269 		syscallarg(int) fd;
270 		syscallarg(netbsd32_charp) buf;
271 		syscallarg(u_int) count;
272 		syscallarg(netbsd32_longp) basep;
273 	} */ *uap = v;
274 	struct compat_43_sys_getdirentries_args ua;
275 
276 	NETBSD32TO64_UAP(fd);
277 	NETBSD32TOP_UAP(buf, char);
278 	NETBSD32TO64_UAP(count);
279 	NETBSD32TOP_UAP(basep, long);
280 	return (compat_43_sys_getdirentries(p, &ua, retval));
281 }
282 
283 /* kernel syscalls */
284 int
285 compat_43_netbsd32_ogetkerninfo(p, v, retval)
286 	struct proc *p;
287 	void *v;
288 	register_t *retval;
289 {
290 	struct compat_43_netbsd32_ogetkerninfo_args /* {
291 		syscallarg(int) op;
292 		syscallarg(netbsd32_charp) where;
293 		syscallarg(netbsd32_intp) size;
294 		syscallarg(int) arg;
295 	} */ *uap = v;
296 	struct compat_43_sys_getkerninfo_args ua;
297 
298 	NETBSD32TO64_UAP(op);
299 	NETBSD32TOP_UAP(where, char);
300 	NETBSD32TOP_UAP(size, int);
301 	NETBSD32TO64_UAP(arg);
302 	return (compat_43_sys_getkerninfo(p, &ua, retval));
303 }
304 
305 int
306 compat_43_netbsd32_ogethostname(p, v, retval)
307 	struct proc *p;
308 	void *v;
309 	register_t *retval;
310 {
311 	struct compat_43_netbsd32_ogethostname_args /* {
312 		syscallarg(netbsd32_charp) hostname;
313 		syscallarg(u_int) len;
314 	} */ *uap = v;
315 	int name;
316 	size_t sz;
317 
318 	name = KERN_HOSTNAME;
319 	sz = SCARG(uap, len);
320 	return (kern_sysctl(&name, 1, (char *)(u_long)SCARG(uap, hostname),
321 	    &sz, 0, 0, p));
322 }
323 
324 int
325 compat_43_netbsd32_osethostname(p, v, retval)
326 	struct proc *p;
327 	void *v;
328 	register_t *retval;
329 {
330 	struct compat_43_netbsd32_osethostname_args /* {
331 		syscallarg(netbsd32_charp) hostname;
332 		syscallarg(u_int) len;
333 	} */ *uap = v;
334 	int name;
335 	int error;
336 
337 	if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
338 		return (error);
339 	name = KERN_HOSTNAME;
340 	return (kern_sysctl(&name, 1, 0, 0, (char *)(u_long)SCARG(uap,
341 	    hostname), SCARG(uap, len), p));
342 }
343 
344 int
345 compat_43_netbsd32_sethostid(p, v, retval)
346 	struct proc *p;
347 	void *v;
348 	register_t *retval;
349 {
350 	struct compat_43_netbsd32_sethostid_args /* {
351 		syscallarg(int32_t) hostid;
352 	} */ *uap = v;
353 	struct compat_43_sys_sethostid_args ua;
354 
355 	NETBSD32TO64_UAP(hostid);
356 	return (compat_43_sys_sethostid(p, &ua, retval));
357 }
358 
359 int
360 compat_43_netbsd32_ogetrlimit(p, v, retval)
361 	struct proc *p;
362 	void *v;
363 	register_t *retval;
364 {
365 	struct compat_43_netbsd32_ogetrlimit_args /* {
366 		syscallarg(int) which;
367 		syscallarg(netbsd32_orlimitp_t) rlp;
368 	} */ *uap = v;
369 	struct compat_43_sys_getrlimit_args ua;
370 
371 	NETBSD32TO64_UAP(which);
372 	NETBSD32TOP_UAP(rlp, struct orlimit);
373 	return (compat_43_sys_getrlimit(p, &ua, retval));
374 }
375 
376 int
377 compat_43_netbsd32_osetrlimit(p, v, retval)
378 	struct proc *p;
379 	void *v;
380 	register_t *retval;
381 {
382 	struct compat_43_netbsd32_osetrlimit_args /* {
383 		syscallarg(int) which;
384 		syscallarg(netbsd32_orlimitp_t) rlp;
385 	} */ *uap = v;
386 	struct compat_43_sys_setrlimit_args ua;
387 
388 	NETBSD32TO64_UAP(which);
389 	NETBSD32TOP_UAP(rlp, struct orlimit);
390 	return (compat_43_sys_setrlimit(p, &ua, retval));
391 }
392 
393 int
394 compat_43_netbsd32_killpg(p, v, retval)
395 	struct proc *p;
396 	void *v;
397 	register_t *retval;
398 {
399 	struct compat_43_netbsd32_killpg_args /* {
400 		syscallarg(int) pgid;
401 		syscallarg(int) signum;
402 	} */ *uap = v;
403 	struct compat_43_sys_killpg_args ua;
404 
405 	NETBSD32TO64_UAP(pgid);
406 	NETBSD32TO64_UAP(signum);
407 	return (compat_43_sys_killpg(p, &ua, retval));
408 }
409 
410 /* virtual memory syscalls */
411 int
412 compat_43_netbsd32_ommap(p, v, retval)
413 	struct proc *p;
414 	void *v;
415 	register_t *retval;
416 {
417 	struct compat_43_netbsd32_ommap_args /* {
418 		syscallarg(netbsd32_caddr_t) addr;
419 		syscallarg(netbsd32_size_t) len;
420 		syscallarg(int) prot;
421 		syscallarg(int) flags;
422 		syscallarg(int) fd;
423 		syscallarg(netbsd32_long) pos;
424 	} */ *uap = v;
425 	struct compat_43_sys_mmap_args ua;
426 
427 	NETBSD32TOX64_UAP(addr, caddr_t);
428 	NETBSD32TOX_UAP(len, size_t);
429 	NETBSD32TO64_UAP(prot);
430 	NETBSD32TO64_UAP(flags);
431 	NETBSD32TO64_UAP(fd);
432 	NETBSD32TOX_UAP(pos, long);
433 	return (compat_43_sys_mmap(p, &ua, retval));
434 }
435 
436 /* network syscalls */
437 int
438 compat_43_netbsd32_oaccept(p, v, retval)
439 	struct proc *p;
440 	void *v;
441 	register_t *retval;
442 {
443 	struct compat_43_netbsd32_oaccept_args /* {
444 		syscallarg(int) s;
445 		syscallarg(netbsd32_caddr_t) name;
446 		syscallarg(netbsd32_intp) anamelen;
447 	} */ *uap = v;
448 	struct compat_43_sys_accept_args ua;
449 
450 	NETBSD32TOX_UAP(s, int);
451 	NETBSD32TOX64_UAP(name, caddr_t);
452 	NETBSD32TOP_UAP(anamelen, int);
453 	return (compat_43_sys_accept(p, &ua, retval));
454 }
455 
456 int
457 compat_43_netbsd32_osend(p, v, retval)
458 	struct proc *p;
459 	void *v;
460 	register_t *retval;
461 {
462 	struct compat_43_netbsd32_osend_args /* {
463 		syscallarg(int) s;
464 		syscallarg(netbsd32_caddr_t) buf;
465 		syscallarg(int) len;
466 		syscallarg(int) flags;
467 	} */ *uap = v;
468 	struct compat_43_sys_send_args ua;
469 
470 	NETBSD32TO64_UAP(s);
471 	NETBSD32TOX64_UAP(buf, caddr_t);
472 	NETBSD32TO64_UAP(len);
473 	NETBSD32TO64_UAP(flags);
474 	return (compat_43_sys_send(p, &ua, retval));
475 }
476 
477 int
478 compat_43_netbsd32_orecv(p, v, retval)
479 	struct proc *p;
480 	void *v;
481 	register_t *retval;
482 {
483 	struct compat_43_netbsd32_orecv_args /* {
484 		syscallarg(int) s;
485 		syscallarg(netbsd32_caddr_t) buf;
486 		syscallarg(int) len;
487 		syscallarg(int) flags;
488 	} */ *uap = v;
489 	struct compat_43_sys_recv_args ua;
490 
491 	NETBSD32TO64_UAP(s);
492 	NETBSD32TOX64_UAP(buf, caddr_t);
493 	NETBSD32TO64_UAP(len);
494 	NETBSD32TO64_UAP(flags);
495 	return (compat_43_sys_recv(p, &ua, retval));
496 }
497 
498 /*
499  * XXX convert these to use a common iovec code to the native
500  * netbsd call.
501  */
502 int
503 compat_43_netbsd32_orecvmsg(p, v, retval)
504 	struct proc *p;
505 	void *v;
506 	register_t *retval;
507 {
508 	struct compat_43_netbsd32_orecvmsg_args /* {
509 		syscallarg(int) s;
510 		syscallarg(netbsd32_omsghdrp_t) msg;
511 		syscallarg(int) flags;
512 	} */ *uap = v;
513 	struct compat_43_sys_recvmsg_args ua;
514 	struct omsghdr omh, *sgsbp;
515 	struct netbsd32_omsghdr omh32;
516 	struct iovec iov, *sgsbp2;
517 	struct netbsd32_iovec iov32, *iovec32p;
518 	caddr_t sg = stackgap_init(p->p_emul);
519 	int i, error, rv;
520 
521 	NETBSD32TO64_UAP(s);
522 	NETBSD32TO64_UAP(flags);
523 
524 	/*
525 	 * this is annoying:
526 	 *	- copyin the msghdr32 struct
527 	 *	- stackgap_alloc a msghdr struct
528 	 *	- convert msghdr32 to msghdr:
529 	 *		- stackgap_alloc enough space for iovec's
530 	 *		- copy in each iov32, and convert to iov
531 	 *		- copyout converted iov
532 	 *	- copyout converted msghdr
533 	 *	- do real syscall
534 	 *	- copyin the msghdr struct
535 	 *	- convert msghdr to msghdr32
536 	 *		- copyin each iov and convert to iov32
537 	 *		- copyout converted iov32
538 	 *	- copyout converted msghdr32
539 	 */
540 	error = copyin((caddr_t)(u_long)SCARG(uap, msg), &omh32, sizeof(omh32));
541 	if (error)
542 		return (error);
543 
544 	SCARG(&ua, msg) = sgsbp = stackgap_alloc(&sg, sizeof(omh));
545 	omh.msg_name = (caddr_t)(u_long)omh32.msg_name;
546 	omh.msg_namelen = omh32.msg_namelen;
547 	omh.msg_iovlen = (size_t)omh32.msg_iovlen;
548 	omh.msg_iov = sgsbp2 = stackgap_alloc(&sg, sizeof(struct iovec) * omh.msg_iovlen);
549 	iovec32p = (struct netbsd32_iovec *)(u_long)omh32.msg_iov;
550 	for (i = 0; i < omh.msg_iovlen; i++, sgsbp2++, iovec32p++) {
551 		error = copyin(iovec32p, &iov32, sizeof(iov32));
552 		if (error)
553 			return (error);
554 		iov.iov_base = (struct iovec *)(u_long)iovec32p->iov_base;
555 		iov.iov_len = (size_t)iovec32p->iov_len;
556 		error = copyout(&iov, sgsbp2, sizeof(iov));
557 		if (error)
558 			return (error);
559 	}
560 	omh.msg_accrights = (caddr_t)(u_long)omh32.msg_accrights;
561 	omh.msg_accrightslen = omh32.msg_accrightslen;
562 	error = copyout(&omh, sgsbp, sizeof(omh));
563 	if (error)
564 		return (error);
565 
566 	rv = compat_43_sys_recvmsg(p, &ua, retval);
567 
568 	error = copyin(sgsbp, &omh, sizeof(omh));
569 	if (error)
570 		return error;
571 	omh32.msg_name = (netbsd32_caddr_t)(u_long)omh.msg_name;
572 	omh32.msg_namelen = omh.msg_namelen;
573 	omh32.msg_iovlen = (netbsd32_size_t)omh.msg_iovlen;
574 	iovec32p = (struct netbsd32_iovec *)(u_long)omh32.msg_iov;
575 	sgsbp2 = omh.msg_iov;
576 	for (i = 0; i < omh.msg_iovlen; i++, sgsbp2++, iovec32p++) {
577 		error = copyin(sgsbp2, &iov, sizeof(iov));
578 		if (error)
579 			return (error);
580 		iov32.iov_base = (netbsd32_iovecp_t)(u_long)iov.iov_base;
581 		iov32.iov_len = (netbsd32_size_t)iov.iov_len;
582 		error = copyout(&iov32, iovec32p, sizeof(iov32));
583 		if (error)
584 			return (error);
585 	}
586 	omh32.msg_accrights = (netbsd32_caddr_t)(u_long)omh.msg_accrights;
587 	omh32.msg_accrightslen = omh.msg_accrightslen;
588 
589 	error = copyout(&omh32, (char *)(u_long)SCARG(uap, msg), sizeof(omh32));
590 	if (error)
591 		return error;
592 
593 	return (rv);
594 }
595 
596 int
597 compat_43_netbsd32_osendmsg(p, v, retval)
598 	struct proc *p;
599 	void *v;
600 	register_t *retval;
601 {
602 	struct compat_43_netbsd32_osendmsg_args /* {
603 		syscallarg(int) s;
604 		syscallarg(netbsd32_caddr_t) msg;
605 		syscallarg(int) flags;
606 	} */ *uap = v;
607 	struct compat_43_sys_recvmsg_args ua;
608 	struct omsghdr omh, *sgsbp;
609 	struct netbsd32_omsghdr omh32;
610 	struct iovec iov, *sgsbp2;
611 	struct netbsd32_iovec iov32, *iovec32p;
612 	caddr_t sg = stackgap_init(p->p_emul);
613 	int i, error, rv;
614 
615 	NETBSD32TO64_UAP(s);
616 	NETBSD32TO64_UAP(flags);
617 
618 	/*
619 	 * this is annoying:
620 	 *	- copyin the msghdr32 struct
621 	 *	- stackgap_alloc a msghdr struct
622 	 *	- convert msghdr32 to msghdr:
623 	 *		- stackgap_alloc enough space for iovec's
624 	 *		- copy in each iov32, and convert to iov
625 	 *		- copyout converted iov
626 	 *	- copyout converted msghdr
627 	 *	- do real syscall
628 	 *	- copyin the msghdr struct
629 	 *	- convert msghdr to msghdr32
630 	 *		- copyin each iov and convert to iov32
631 	 *		- copyout converted iov32
632 	 *	- copyout converted msghdr32
633 	 */
634 	error = copyin((caddr_t)(u_long)SCARG(uap, msg), &omh32, sizeof(omh32));
635 	if (error)
636 		return (error);
637 
638 	SCARG(&ua, msg) = sgsbp = stackgap_alloc(&sg, sizeof(omh));
639 	omh.msg_name = (caddr_t)(u_long)omh32.msg_name;
640 	omh.msg_namelen = omh32.msg_namelen;
641 	omh.msg_iovlen = (size_t)omh32.msg_iovlen;
642 	omh.msg_iov = sgsbp2 = stackgap_alloc(&sg, sizeof(struct iovec) * omh.msg_iovlen);
643 	iovec32p = (struct netbsd32_iovec *)(u_long)omh32.msg_iov;
644 	for (i = 0; i < omh.msg_iovlen; i++, sgsbp2++, iovec32p++) {
645 		error = copyin(iovec32p, &iov32, sizeof(iov32));
646 		if (error)
647 			return (error);
648 		iov.iov_base = (struct iovec *)(u_long)iovec32p->iov_base;
649 		iov.iov_len = (size_t)iovec32p->iov_len;
650 		error = copyout(&iov, sgsbp2, sizeof(iov));
651 		if (error)
652 			return (error);
653 	}
654 	omh.msg_accrights = (caddr_t)(u_long)omh32.msg_accrights;
655 	omh.msg_accrightslen = omh32.msg_accrightslen;
656 	error = copyout(&omh, sgsbp, sizeof(omh));
657 	if (error)
658 		return (error);
659 
660 	rv = compat_43_sys_sendmsg(p, &ua, retval);
661 
662 	error = copyin(sgsbp, &omh, sizeof(omh));
663 	if (error)
664 		return error;
665 	omh32.msg_name = (netbsd32_caddr_t)(u_long)omh.msg_name;
666 	omh32.msg_namelen = omh.msg_namelen;
667 	omh32.msg_iovlen = (netbsd32_size_t)omh.msg_iovlen;
668 	iovec32p = (struct netbsd32_iovec *)(u_long)omh32.msg_iov;
669 	sgsbp2 = omh.msg_iov;
670 	for (i = 0; i < omh.msg_iovlen; i++, sgsbp2++, iovec32p++) {
671 		error = copyin(sgsbp2, &iov, sizeof(iov));
672 		if (error)
673 			return (error);
674 		iov32.iov_base = (netbsd32_iovecp_t)(u_long)iov.iov_base;
675 		iov32.iov_len = (netbsd32_size_t)iov.iov_len;
676 		error = copyout(&iov32, iovec32p, sizeof(iov32));
677 		if (error)
678 			return (error);
679 	}
680 	omh32.msg_accrights = (netbsd32_caddr_t)(u_long)omh.msg_accrights;
681 	omh32.msg_accrightslen = omh.msg_accrightslen;
682 
683 	error = copyout(&omh32, (char *)(u_long)SCARG(uap, msg), sizeof(omh32));
684 	if (error)
685 		return error;
686 
687 	return (rv);
688 }
689 
690 int
691 compat_43_netbsd32_orecvfrom(p, v, retval)
692 	struct proc *p;
693 	void *v;
694 	register_t *retval;
695 {
696 	struct compat_43_netbsd32_orecvfrom_args /* {
697 		syscallarg(int) s;
698 		syscallarg(netbsd32_caddr_t) buf;
699 		syscallarg(netbsd32_size_t) len;
700 		syscallarg(int) flags;
701 		syscallarg(netbsd32_caddr_t) from;
702 		syscallarg(netbsd32_intp) fromlenaddr;
703 	} */ *uap = v;
704 	struct compat_43_sys_recvfrom_args ua;
705 
706 	NETBSD32TO64_UAP(s);
707 	NETBSD32TOX64_UAP(buf, caddr_t);
708 	NETBSD32TOX_UAP(len, size_t);
709 	NETBSD32TO64_UAP(flags);
710 	NETBSD32TOX64_UAP(from, caddr_t);
711 	NETBSD32TOP_UAP(fromlenaddr, int);
712 	return (compat_43_sys_recvfrom(p, &ua, retval));
713 }
714 
715 int
716 compat_43_netbsd32_ogetsockname(p, v, retval)
717 	struct proc *p;
718 	void *v;
719 	register_t *retval;
720 {
721 	struct compat_43_netbsd32_ogetsockname_args /* {
722 		syscallarg(int) fdec;
723 		syscallarg(netbsd32_caddr_t) asa;
724 		syscallarg(netbsd32_intp) alen;
725 	} */ *uap = v;
726 	struct compat_43_sys_getsockname_args ua;
727 
728 	NETBSD32TO64_UAP(fdec);
729 	NETBSD32TOX64_UAP(asa, caddr_t);
730 	NETBSD32TOP_UAP(alen, int);
731 	return (compat_43_sys_getsockname(p, &ua, retval));
732 }
733 
734 int
735 compat_43_netbsd32_ogetpeername(p, v, retval)
736 	struct proc *p;
737 	void *v;
738 	register_t *retval;
739 {
740 	struct compat_43_netbsd32_ogetpeername_args /* {
741 		syscallarg(int) fdes;
742 		syscallarg(netbsd32_caddr_t) asa;
743 		syscallarg(netbsd32_intp) alen;
744 	} */ *uap = v;
745 	struct compat_43_sys_getpeername_args ua;
746 
747 	NETBSD32TO64_UAP(fdes);
748 	NETBSD32TOX64_UAP(asa, caddr_t);
749 	NETBSD32TOP_UAP(alen, int);
750 	return (compat_43_sys_getpeername(p, &ua, retval));
751 }
752 
753 /* signal syscalls */
754 int
755 compat_43_netbsd32_osigvec(p, v, retval)
756 	struct proc *p;
757 	void *v;
758 	register_t *retval;
759 {
760 	struct compat_43_netbsd32_osigvec_args /* {
761 		syscallarg(int) signum;
762 		syscallarg(netbsd32_sigvecp_t) nsv;
763 		syscallarg(netbsd32_sigvecp_t) osv;
764 	} */ *uap = v;
765 	struct compat_43_sys_sigvec_args ua;
766 	struct netbsd32_sigvec sv32;
767 	struct sigvec sv, *sgnsvp, *sgosvp;
768 	caddr_t sg = stackgap_init(p->p_emul);
769 	int rv, error;
770 
771 	NETBSD32TO64_UAP(signum);
772 	if (SCARG(uap, osv))
773 		SCARG(&ua, osv) = sgosvp = stackgap_alloc(&sg, sizeof(sv));
774 	else
775 		SCARG(&ua, osv) = NULL;
776 	if (SCARG(uap, nsv)) {
777 		SCARG(&ua, nsv) = sgnsvp = stackgap_alloc(&sg, sizeof(sv));
778 		error = copyin((caddr_t)(u_long)SCARG(uap, nsv), &sv32, sizeof(sv32));
779 		if (error)
780 			return (error);
781 		sv.sv_handler = (void *)(u_long)sv32.sv_handler;
782 		sv.sv_mask = sv32.sv_mask;
783 		sv.sv_flags = sv32.sv_flags;
784 		error = copyout(&sv, sgnsvp, sizeof(sv));
785 		if (error)
786 			return (error);
787 	} else
788 		SCARG(&ua, nsv) = NULL;
789 	rv = compat_43_sys_sigvec(p, &ua, retval);
790 	if (rv)
791 		return (rv);
792 
793 	if (SCARG(uap, osv)) {
794 		error = copyin(sgosvp, &sv, sizeof(sv));
795 		if (error)
796 			return (error);
797 		sv32.sv_handler = (netbsd32_sigvecp_t)(u_long)sv.sv_handler;
798 		sv32.sv_mask = sv.sv_mask;
799 		sv32.sv_flags = sv.sv_flags;
800 		error = copyout(&sv32, (caddr_t)(u_long)SCARG(uap, osv), sizeof(sv32));
801 		if (error)
802 			return (error);
803 	}
804 
805 	return (0);
806 }
807 
808 int
809 compat_43_netbsd32_sigblock(p, v, retval)
810 	struct proc *p;
811 	void *v;
812 	register_t *retval;
813 {
814 	struct compat_43_netbsd32_sigblock_args /* {
815 		syscallarg(int) mask;
816 	} */ *uap = v;
817 	struct compat_43_sys_sigblock_args ua;
818 
819 	NETBSD32TO64_UAP(mask);
820 	return (compat_43_sys_sigblock(p, &ua, retval));
821 }
822 
823 int
824 compat_43_netbsd32_sigsetmask(p, v, retval)
825 	struct proc *p;
826 	void *v;
827 	register_t *retval;
828 {
829 	struct compat_43_netbsd32_sigsetmask_args /* {
830 		syscallarg(int) mask;
831 	} */ *uap = v;
832 	struct compat_43_sys_sigsetmask_args ua;
833 
834 	NETBSD32TO64_UAP(mask);
835 	return (compat_43_sys_sigsetmask(p, &ua, retval));
836 }
837 
838 int
839 compat_43_netbsd32_osigstack(p, v, retval)
840 	struct proc *p;
841 	void *v;
842 	register_t *retval;
843 {
844 	struct compat_43_netbsd32_osigstack_args /* {
845 		syscallarg(netbsd32_sigstackp_t) nss;
846 		syscallarg(netbsd32_sigstackp_t) oss;
847 	} */ *uap = v;
848 	struct compat_43_sys_sigstack_args ua;
849 	struct netbsd32_sigstack ss32;
850 	struct sigstack ss, *sgossp, *sgnssp;
851 	caddr_t sg = stackgap_init(p->p_emul);
852 	int error, rv;
853 
854 	if (SCARG(uap, oss))
855 		SCARG(&ua, oss) = sgossp = stackgap_alloc(&sg, sizeof(ss));
856 	else
857 		SCARG(&ua, oss) = NULL;
858 	if (SCARG(uap, nss)) {
859 		SCARG(&ua, nss) = sgnssp = stackgap_alloc(&sg, sizeof(ss));
860 		error = copyin((caddr_t)(u_long)SCARG(uap, nss), &ss32, sizeof(ss32));
861 		if (error)
862 			return (error);
863 		ss.ss_sp = (void *)(u_long)ss32.ss_sp;
864 		ss.ss_onstack = ss32.ss_onstack;
865 		error = copyout(&ss, sgnssp, sizeof(ss));
866 		if (error)
867 			return (error);
868 	} else
869 		SCARG(&ua, nss) = NULL;
870 
871 	rv = compat_43_sys_sigstack(p, &ua, retval);
872 	if (rv)
873 		return (rv);
874 
875 	if (SCARG(uap, oss)) {
876 		error = copyin(sgossp, &ss, sizeof(ss));
877 		if (error)
878 			return (error);
879 		ss32.ss_sp = (netbsd32_sigstackp_t)(u_long)ss.ss_sp;
880 		ss32.ss_onstack = ss.ss_onstack;
881 		error = copyout(&ss32, (caddr_t)(u_long)SCARG(uap, oss), sizeof(ss32));
882 		if (error)
883 			return (error);
884 	}
885 
886 	return (0);
887 }
888