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