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