]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/compat/freebsd32/freebsd32_misc.c
Merge OpenBSM 1.2-alpha2 from vendor branch to FreeBSD 10-CURRENT; the
[FreeBSD/FreeBSD.git] / sys / compat / freebsd32 / freebsd32_misc.c
1 /*-
2  * Copyright (c) 2002 Doug Rabson
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  */
26
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
29
30 #include "opt_compat.h"
31 #include "opt_inet.h"
32 #include "opt_inet6.h"
33
34 #define __ELF_WORD_SIZE 32
35
36 #include <sys/param.h>
37 #include <sys/bus.h>
38 #include <sys/clock.h>
39 #include <sys/exec.h>
40 #include <sys/fcntl.h>
41 #include <sys/filedesc.h>
42 #include <sys/imgact.h>
43 #include <sys/jail.h>
44 #include <sys/kernel.h>
45 #include <sys/limits.h>
46 #include <sys/linker.h>
47 #include <sys/lock.h>
48 #include <sys/malloc.h>
49 #include <sys/file.h>           /* Must come after sys/malloc.h */
50 #include <sys/imgact.h>
51 #include <sys/mbuf.h>
52 #include <sys/mman.h>
53 #include <sys/module.h>
54 #include <sys/mount.h>
55 #include <sys/mutex.h>
56 #include <sys/namei.h>
57 #include <sys/proc.h>
58 #include <sys/reboot.h>
59 #include <sys/resource.h>
60 #include <sys/resourcevar.h>
61 #include <sys/selinfo.h>
62 #include <sys/eventvar.h>       /* Must come after sys/selinfo.h */
63 #include <sys/pipe.h>           /* Must come after sys/selinfo.h */
64 #include <sys/signal.h>
65 #include <sys/signalvar.h>
66 #include <sys/socket.h>
67 #include <sys/socketvar.h>
68 #include <sys/stat.h>
69 #include <sys/syscall.h>
70 #include <sys/syscallsubr.h>
71 #include <sys/sysctl.h>
72 #include <sys/sysent.h>
73 #include <sys/sysproto.h>
74 #include <sys/systm.h>
75 #include <sys/thr.h>
76 #include <sys/unistd.h>
77 #include <sys/ucontext.h>
78 #include <sys/vnode.h>
79 #include <sys/wait.h>
80 #include <sys/ipc.h>
81 #include <sys/msg.h>
82 #include <sys/sem.h>
83 #include <sys/shm.h>
84
85 #ifdef INET
86 #include <netinet/in.h>
87 #endif
88
89 #include <vm/vm.h>
90 #include <vm/vm_param.h>
91 #include <vm/pmap.h>
92 #include <vm/vm_map.h>
93 #include <vm/vm_object.h>
94 #include <vm/vm_extern.h>
95
96 #include <machine/cpu.h>
97 #include <machine/elf.h>
98
99 #include <security/audit/audit.h>
100
101 #include <compat/freebsd32/freebsd32_util.h>
102 #include <compat/freebsd32/freebsd32.h>
103 #include <compat/freebsd32/freebsd32_ipc.h>
104 #include <compat/freebsd32/freebsd32_signal.h>
105 #include <compat/freebsd32/freebsd32_proto.h>
106
107 #ifndef __mips__
108 CTASSERT(sizeof(struct timeval32) == 8);
109 CTASSERT(sizeof(struct timespec32) == 8);
110 CTASSERT(sizeof(struct itimerval32) == 16);
111 #endif
112 CTASSERT(sizeof(struct statfs32) == 256);
113 #ifndef __mips__
114 CTASSERT(sizeof(struct rusage32) == 72);
115 #endif
116 CTASSERT(sizeof(struct sigaltstack32) == 12);
117 CTASSERT(sizeof(struct kevent32) == 20);
118 CTASSERT(sizeof(struct iovec32) == 8);
119 CTASSERT(sizeof(struct msghdr32) == 28);
120 #ifndef __mips__
121 CTASSERT(sizeof(struct stat32) == 96);
122 #endif
123 CTASSERT(sizeof(struct sigaction32) == 24);
124
125 static int freebsd32_kevent_copyout(void *arg, struct kevent *kevp, int count);
126 static int freebsd32_kevent_copyin(void *arg, struct kevent *kevp, int count);
127
128 #if BYTE_ORDER == BIG_ENDIAN
129 #define PAIR32TO64(type, name) ((name ## 2) | ((type)(name ## 1) << 32))
130 #define RETVAL_HI 0     
131 #define RETVAL_LO 1     
132 #else
133 #define PAIR32TO64(type, name) ((name ## 1) | ((type)(name ## 2) << 32))
134 #define RETVAL_HI 1     
135 #define RETVAL_LO 0     
136 #endif
137
138 void
139 freebsd32_rusage_out(const struct rusage *s, struct rusage32 *s32)
140 {
141
142         TV_CP(*s, *s32, ru_utime);
143         TV_CP(*s, *s32, ru_stime);
144         CP(*s, *s32, ru_maxrss);
145         CP(*s, *s32, ru_ixrss);
146         CP(*s, *s32, ru_idrss);
147         CP(*s, *s32, ru_isrss);
148         CP(*s, *s32, ru_minflt);
149         CP(*s, *s32, ru_majflt);
150         CP(*s, *s32, ru_nswap);
151         CP(*s, *s32, ru_inblock);
152         CP(*s, *s32, ru_oublock);
153         CP(*s, *s32, ru_msgsnd);
154         CP(*s, *s32, ru_msgrcv);
155         CP(*s, *s32, ru_nsignals);
156         CP(*s, *s32, ru_nvcsw);
157         CP(*s, *s32, ru_nivcsw);
158 }
159
160 int
161 freebsd32_wait4(struct thread *td, struct freebsd32_wait4_args *uap)
162 {
163         int error, status;
164         struct rusage32 ru32;
165         struct rusage ru, *rup;
166
167         if (uap->rusage != NULL)
168                 rup = &ru;
169         else
170                 rup = NULL;
171         error = kern_wait(td, uap->pid, &status, uap->options, rup);
172         if (error)
173                 return (error);
174         if (uap->status != NULL)
175                 error = copyout(&status, uap->status, sizeof(status));
176         if (uap->rusage != NULL && error == 0) {
177                 freebsd32_rusage_out(&ru, &ru32);
178                 error = copyout(&ru32, uap->rusage, sizeof(ru32));
179         }
180         return (error);
181 }
182
183 int
184 freebsd32_wait6(struct thread *td, struct freebsd32_wait6_args *uap)
185 {
186         struct wrusage32 wru32;
187         struct __wrusage wru, *wrup;
188         struct siginfo32 si32;
189         struct __siginfo si, *sip;
190         int error, status;
191
192         if (uap->wrusage != NULL)
193                 wrup = &wru;
194         else
195                 wrup = NULL;
196         if (uap->info != NULL) {
197                 sip = &si;
198                 bzero(sip, sizeof(*sip));
199         } else
200                 sip = NULL;
201         error = kern_wait6(td, uap->idtype, uap->id, &status, uap->options,
202             wrup, sip);
203         if (error != 0)
204                 return (error);
205         if (uap->status != NULL)
206                 error = copyout(&status, uap->status, sizeof(status));
207         if (uap->wrusage != NULL && error == 0) {
208                 freebsd32_rusage_out(&wru.wru_self, &wru32.wru_self);
209                 freebsd32_rusage_out(&wru.wru_children, &wru32.wru_children);
210                 error = copyout(&wru32, uap->wrusage, sizeof(wru32));
211         }
212         if (uap->info != NULL && error == 0) {
213                 siginfo_to_siginfo32 (&si, &si32);
214                 error = copyout(&si32, uap->info, sizeof(si32));
215         }
216         return (error);
217 }
218
219 #ifdef COMPAT_FREEBSD4
220 static void
221 copy_statfs(struct statfs *in, struct statfs32 *out)
222 {
223
224         statfs_scale_blocks(in, INT32_MAX);
225         bzero(out, sizeof(*out));
226         CP(*in, *out, f_bsize);
227         out->f_iosize = MIN(in->f_iosize, INT32_MAX);
228         CP(*in, *out, f_blocks);
229         CP(*in, *out, f_bfree);
230         CP(*in, *out, f_bavail);
231         out->f_files = MIN(in->f_files, INT32_MAX);
232         out->f_ffree = MIN(in->f_ffree, INT32_MAX);
233         CP(*in, *out, f_fsid);
234         CP(*in, *out, f_owner);
235         CP(*in, *out, f_type);
236         CP(*in, *out, f_flags);
237         out->f_syncwrites = MIN(in->f_syncwrites, INT32_MAX);
238         out->f_asyncwrites = MIN(in->f_asyncwrites, INT32_MAX);
239         strlcpy(out->f_fstypename,
240               in->f_fstypename, MFSNAMELEN);
241         strlcpy(out->f_mntonname,
242               in->f_mntonname, min(MNAMELEN, FREEBSD4_MNAMELEN));
243         out->f_syncreads = MIN(in->f_syncreads, INT32_MAX);
244         out->f_asyncreads = MIN(in->f_asyncreads, INT32_MAX);
245         strlcpy(out->f_mntfromname,
246               in->f_mntfromname, min(MNAMELEN, FREEBSD4_MNAMELEN));
247 }
248 #endif
249
250 #ifdef COMPAT_FREEBSD4
251 int
252 freebsd4_freebsd32_getfsstat(struct thread *td, struct freebsd4_freebsd32_getfsstat_args *uap)
253 {
254         struct statfs *buf, *sp;
255         struct statfs32 stat32;
256         size_t count, size;
257         int error;
258
259         count = uap->bufsize / sizeof(struct statfs32);
260         size = count * sizeof(struct statfs);
261         error = kern_getfsstat(td, &buf, size, UIO_SYSSPACE, uap->flags);
262         if (size > 0) {
263                 count = td->td_retval[0];
264                 sp = buf;
265                 while (count > 0 && error == 0) {
266                         copy_statfs(sp, &stat32);
267                         error = copyout(&stat32, uap->buf, sizeof(stat32));
268                         sp++;
269                         uap->buf++;
270                         count--;
271                 }
272                 free(buf, M_TEMP);
273         }
274         return (error);
275 }
276 #endif
277
278 int
279 freebsd32_sigaltstack(struct thread *td,
280                       struct freebsd32_sigaltstack_args *uap)
281 {
282         struct sigaltstack32 s32;
283         struct sigaltstack ss, oss, *ssp;
284         int error;
285
286         if (uap->ss != NULL) {
287                 error = copyin(uap->ss, &s32, sizeof(s32));
288                 if (error)
289                         return (error);
290                 PTRIN_CP(s32, ss, ss_sp);
291                 CP(s32, ss, ss_size);
292                 CP(s32, ss, ss_flags);
293                 ssp = &ss;
294         } else
295                 ssp = NULL;
296         error = kern_sigaltstack(td, ssp, &oss);
297         if (error == 0 && uap->oss != NULL) {
298                 PTROUT_CP(oss, s32, ss_sp);
299                 CP(oss, s32, ss_size);
300                 CP(oss, s32, ss_flags);
301                 error = copyout(&s32, uap->oss, sizeof(s32));
302         }
303         return (error);
304 }
305
306 /*
307  * Custom version of exec_copyin_args() so that we can translate
308  * the pointers.
309  */
310 int
311 freebsd32_exec_copyin_args(struct image_args *args, char *fname,
312     enum uio_seg segflg, u_int32_t *argv, u_int32_t *envv)
313 {
314         char *argp, *envp;
315         u_int32_t *p32, arg;
316         size_t length;
317         int error;
318
319         bzero(args, sizeof(*args));
320         if (argv == NULL)
321                 return (EFAULT);
322
323         /*
324          * Allocate demand-paged memory for the file name, argument, and
325          * environment strings.
326          */
327         error = exec_alloc_args(args);
328         if (error != 0)
329                 return (error);
330
331         /*
332          * Copy the file name.
333          */
334         if (fname != NULL) {
335                 args->fname = args->buf;
336                 error = (segflg == UIO_SYSSPACE) ?
337                     copystr(fname, args->fname, PATH_MAX, &length) :
338                     copyinstr(fname, args->fname, PATH_MAX, &length);
339                 if (error != 0)
340                         goto err_exit;
341         } else
342                 length = 0;
343
344         args->begin_argv = args->buf + length;
345         args->endp = args->begin_argv;
346         args->stringspace = ARG_MAX;
347
348         /*
349          * extract arguments first
350          */
351         p32 = argv;
352         for (;;) {
353                 error = copyin(p32++, &arg, sizeof(arg));
354                 if (error)
355                         goto err_exit;
356                 if (arg == 0)
357                         break;
358                 argp = PTRIN(arg);
359                 error = copyinstr(argp, args->endp, args->stringspace, &length);
360                 if (error) {
361                         if (error == ENAMETOOLONG)
362                                 error = E2BIG;
363                         goto err_exit;
364                 }
365                 args->stringspace -= length;
366                 args->endp += length;
367                 args->argc++;
368         }
369                         
370         args->begin_envv = args->endp;
371
372         /*
373          * extract environment strings
374          */
375         if (envv) {
376                 p32 = envv;
377                 for (;;) {
378                         error = copyin(p32++, &arg, sizeof(arg));
379                         if (error)
380                                 goto err_exit;
381                         if (arg == 0)
382                                 break;
383                         envp = PTRIN(arg);
384                         error = copyinstr(envp, args->endp, args->stringspace,
385                             &length);
386                         if (error) {
387                                 if (error == ENAMETOOLONG)
388                                         error = E2BIG;
389                                 goto err_exit;
390                         }
391                         args->stringspace -= length;
392                         args->endp += length;
393                         args->envc++;
394                 }
395         }
396
397         return (0);
398
399 err_exit:
400         exec_free_args(args);
401         return (error);
402 }
403
404 int
405 freebsd32_execve(struct thread *td, struct freebsd32_execve_args *uap)
406 {
407         struct image_args eargs;
408         int error;
409
410         error = freebsd32_exec_copyin_args(&eargs, uap->fname, UIO_USERSPACE,
411             uap->argv, uap->envv);
412         if (error == 0)
413                 error = kern_execve(td, &eargs, NULL);
414         return (error);
415 }
416
417 int
418 freebsd32_fexecve(struct thread *td, struct freebsd32_fexecve_args *uap)
419 {
420         struct image_args eargs;
421         int error;
422
423         error = freebsd32_exec_copyin_args(&eargs, NULL, UIO_SYSSPACE,
424             uap->argv, uap->envv);
425         if (error == 0) {
426                 eargs.fd = uap->fd;
427                 error = kern_execve(td, &eargs, NULL);
428         }
429         return (error);
430 }
431
432 #ifdef __ia64__
433 static int
434 freebsd32_mmap_partial(struct thread *td, vm_offset_t start, vm_offset_t end,
435                        int prot, int fd, off_t pos)
436 {
437         vm_map_t map;
438         vm_map_entry_t entry;
439         int rv;
440
441         map = &td->td_proc->p_vmspace->vm_map;
442         if (fd != -1)
443                 prot |= VM_PROT_WRITE;
444
445         if (vm_map_lookup_entry(map, start, &entry)) {
446                 if ((entry->protection & prot) != prot) {
447                         rv = vm_map_protect(map,
448                                             trunc_page(start),
449                                             round_page(end),
450                                             entry->protection | prot,
451                                             FALSE);
452                         if (rv != KERN_SUCCESS)
453                                 return (EINVAL);
454                 }
455         } else {
456                 vm_offset_t addr = trunc_page(start);
457                 rv = vm_map_find(map, 0, 0,
458                                  &addr, PAGE_SIZE, FALSE, prot,
459                                  VM_PROT_ALL, 0);
460                 if (rv != KERN_SUCCESS)
461                         return (EINVAL);
462         }
463
464         if (fd != -1) {
465                 struct pread_args r;
466                 r.fd = fd;
467                 r.buf = (void *) start;
468                 r.nbyte = end - start;
469                 r.offset = pos;
470                 return (sys_pread(td, &r));
471         } else {
472                 while (start < end) {
473                         subyte((void *) start, 0);
474                         start++;
475                 }
476                 return (0);
477         }
478 }
479 #endif
480
481 int
482 freebsd32_mprotect(struct thread *td, struct freebsd32_mprotect_args *uap)
483 {
484         struct mprotect_args ap;
485
486         ap.addr = PTRIN(uap->addr);
487         ap.len = uap->len;
488         ap.prot = uap->prot;
489 #if defined(__amd64__) || defined(__ia64__)
490         if (i386_read_exec && (ap.prot & PROT_READ) != 0)
491                 ap.prot |= PROT_EXEC;
492 #endif
493         return (sys_mprotect(td, &ap));
494 }
495
496 int
497 freebsd32_mmap(struct thread *td, struct freebsd32_mmap_args *uap)
498 {
499         struct mmap_args ap;
500         vm_offset_t addr = (vm_offset_t) uap->addr;
501         vm_size_t len    = uap->len;
502         int prot         = uap->prot;
503         int flags        = uap->flags;
504         int fd           = uap->fd;
505         off_t pos        = PAIR32TO64(off_t,uap->pos);
506 #ifdef __ia64__
507         vm_size_t pageoff;
508         int error;
509
510         /*
511          * Attempt to handle page size hassles.
512          */
513         pageoff = (pos & PAGE_MASK);
514         if (flags & MAP_FIXED) {
515                 vm_offset_t start, end;
516                 start = addr;
517                 end = addr + len;
518
519                 if (start != trunc_page(start)) {
520                         error = freebsd32_mmap_partial(td, start,
521                                                        round_page(start), prot,
522                                                        fd, pos);
523                         if (fd != -1)
524                                 pos += round_page(start) - start;
525                         start = round_page(start);
526                 }
527                 if (end != round_page(end)) {
528                         vm_offset_t t = trunc_page(end);
529                         error = freebsd32_mmap_partial(td, t, end,
530                                                   prot, fd,
531                                                   pos + t - start);
532                         end = trunc_page(end);
533                 }
534                 if (end > start && fd != -1 && (pos & PAGE_MASK)) {
535                         /*
536                          * We can't map this region at all. The specified
537                          * address doesn't have the same alignment as the file
538                          * position. Fake the mapping by simply reading the
539                          * entire region into memory. First we need to make
540                          * sure the region exists.
541                          */
542                         vm_map_t map;
543                         struct pread_args r;
544                         int rv;
545
546                         prot |= VM_PROT_WRITE;
547                         map = &td->td_proc->p_vmspace->vm_map;
548                         rv = vm_map_remove(map, start, end);
549                         if (rv != KERN_SUCCESS)
550                                 return (EINVAL);
551                         rv = vm_map_find(map, 0, 0,
552                                          &start, end - start, FALSE,
553                                          prot, VM_PROT_ALL, 0);
554                         if (rv != KERN_SUCCESS)
555                                 return (EINVAL);
556                         r.fd = fd;
557                         r.buf = (void *) start;
558                         r.nbyte = end - start;
559                         r.offset = pos;
560                         error = sys_pread(td, &r);
561                         if (error)
562                                 return (error);
563
564                         td->td_retval[0] = addr;
565                         return (0);
566                 }
567                 if (end == start) {
568                         /*
569                          * After dealing with the ragged ends, there
570                          * might be none left.
571                          */
572                         td->td_retval[0] = addr;
573                         return (0);
574                 }
575                 addr = start;
576                 len = end - start;
577         }
578 #endif
579
580 #if defined(__amd64__) || defined(__ia64__)
581         if (i386_read_exec && (prot & PROT_READ))
582                 prot |= PROT_EXEC;
583 #endif
584
585         ap.addr = (void *) addr;
586         ap.len = len;
587         ap.prot = prot;
588         ap.flags = flags;
589         ap.fd = fd;
590         ap.pos = pos;
591
592         return (sys_mmap(td, &ap));
593 }
594
595 #ifdef COMPAT_FREEBSD6
596 int
597 freebsd6_freebsd32_mmap(struct thread *td, struct freebsd6_freebsd32_mmap_args *uap)
598 {
599         struct freebsd32_mmap_args ap;
600
601         ap.addr = uap->addr;
602         ap.len = uap->len;
603         ap.prot = uap->prot;
604         ap.flags = uap->flags;
605         ap.fd = uap->fd;
606         ap.pos1 = uap->pos1;
607         ap.pos2 = uap->pos2;
608
609         return (freebsd32_mmap(td, &ap));
610 }
611 #endif
612
613 int
614 freebsd32_setitimer(struct thread *td, struct freebsd32_setitimer_args *uap)
615 {
616         struct itimerval itv, oitv, *itvp;      
617         struct itimerval32 i32;
618         int error;
619
620         if (uap->itv != NULL) {
621                 error = copyin(uap->itv, &i32, sizeof(i32));
622                 if (error)
623                         return (error);
624                 TV_CP(i32, itv, it_interval);
625                 TV_CP(i32, itv, it_value);
626                 itvp = &itv;
627         } else
628                 itvp = NULL;
629         error = kern_setitimer(td, uap->which, itvp, &oitv);
630         if (error || uap->oitv == NULL)
631                 return (error);
632         TV_CP(oitv, i32, it_interval);
633         TV_CP(oitv, i32, it_value);
634         return (copyout(&i32, uap->oitv, sizeof(i32)));
635 }
636
637 int
638 freebsd32_getitimer(struct thread *td, struct freebsd32_getitimer_args *uap)
639 {
640         struct itimerval itv;
641         struct itimerval32 i32;
642         int error;
643
644         error = kern_getitimer(td, uap->which, &itv);
645         if (error || uap->itv == NULL)
646                 return (error);
647         TV_CP(itv, i32, it_interval);
648         TV_CP(itv, i32, it_value);
649         return (copyout(&i32, uap->itv, sizeof(i32)));
650 }
651
652 int
653 freebsd32_select(struct thread *td, struct freebsd32_select_args *uap)
654 {
655         struct timeval32 tv32;
656         struct timeval tv, *tvp;
657         int error;
658
659         if (uap->tv != NULL) {
660                 error = copyin(uap->tv, &tv32, sizeof(tv32));
661                 if (error)
662                         return (error);
663                 CP(tv32, tv, tv_sec);
664                 CP(tv32, tv, tv_usec);
665                 tvp = &tv;
666         } else
667                 tvp = NULL;
668         /*
669          * XXX Do pointers need PTRIN()?
670          */
671         return (kern_select(td, uap->nd, uap->in, uap->ou, uap->ex, tvp,
672             sizeof(int32_t) * 8));
673 }
674
675 int
676 freebsd32_pselect(struct thread *td, struct freebsd32_pselect_args *uap)
677 {
678         struct timespec32 ts32;
679         struct timespec ts;
680         struct timeval tv, *tvp;
681         sigset_t set, *uset;
682         int error;
683
684         if (uap->ts != NULL) {
685                 error = copyin(uap->ts, &ts32, sizeof(ts32));
686                 if (error != 0)
687                         return (error);
688                 CP(ts32, ts, tv_sec);
689                 CP(ts32, ts, tv_nsec);
690                 TIMESPEC_TO_TIMEVAL(&tv, &ts);
691                 tvp = &tv;
692         } else
693                 tvp = NULL;
694         if (uap->sm != NULL) {
695                 error = copyin(uap->sm, &set, sizeof(set));
696                 if (error != 0)
697                         return (error);
698                 uset = &set;
699         } else
700                 uset = NULL;
701         /*
702          * XXX Do pointers need PTRIN()?
703          */
704         error = kern_pselect(td, uap->nd, uap->in, uap->ou, uap->ex, tvp,
705             uset, sizeof(int32_t) * 8);
706         return (error);
707 }
708
709 /*
710  * Copy 'count' items into the destination list pointed to by uap->eventlist.
711  */
712 static int
713 freebsd32_kevent_copyout(void *arg, struct kevent *kevp, int count)
714 {
715         struct freebsd32_kevent_args *uap;
716         struct kevent32 ks32[KQ_NEVENTS];
717         int i, error = 0;
718
719         KASSERT(count <= KQ_NEVENTS, ("count (%d) > KQ_NEVENTS", count));
720         uap = (struct freebsd32_kevent_args *)arg;
721
722         for (i = 0; i < count; i++) {
723                 CP(kevp[i], ks32[i], ident);
724                 CP(kevp[i], ks32[i], filter);
725                 CP(kevp[i], ks32[i], flags);
726                 CP(kevp[i], ks32[i], fflags);
727                 CP(kevp[i], ks32[i], data);
728                 PTROUT_CP(kevp[i], ks32[i], udata);
729         }
730         error = copyout(ks32, uap->eventlist, count * sizeof *ks32);
731         if (error == 0)
732                 uap->eventlist += count;
733         return (error);
734 }
735
736 /*
737  * Copy 'count' items from the list pointed to by uap->changelist.
738  */
739 static int
740 freebsd32_kevent_copyin(void *arg, struct kevent *kevp, int count)
741 {
742         struct freebsd32_kevent_args *uap;
743         struct kevent32 ks32[KQ_NEVENTS];
744         int i, error = 0;
745
746         KASSERT(count <= KQ_NEVENTS, ("count (%d) > KQ_NEVENTS", count));
747         uap = (struct freebsd32_kevent_args *)arg;
748
749         error = copyin(uap->changelist, ks32, count * sizeof *ks32);
750         if (error)
751                 goto done;
752         uap->changelist += count;
753
754         for (i = 0; i < count; i++) {
755                 CP(ks32[i], kevp[i], ident);
756                 CP(ks32[i], kevp[i], filter);
757                 CP(ks32[i], kevp[i], flags);
758                 CP(ks32[i], kevp[i], fflags);
759                 CP(ks32[i], kevp[i], data);
760                 PTRIN_CP(ks32[i], kevp[i], udata);
761         }
762 done:
763         return (error);
764 }
765
766 int
767 freebsd32_kevent(struct thread *td, struct freebsd32_kevent_args *uap)
768 {
769         struct timespec32 ts32;
770         struct timespec ts, *tsp;
771         struct kevent_copyops k_ops = { uap,
772                                         freebsd32_kevent_copyout,
773                                         freebsd32_kevent_copyin};
774         int error;
775
776
777         if (uap->timeout) {
778                 error = copyin(uap->timeout, &ts32, sizeof(ts32));
779                 if (error)
780                         return (error);
781                 CP(ts32, ts, tv_sec);
782                 CP(ts32, ts, tv_nsec);
783                 tsp = &ts;
784         } else
785                 tsp = NULL;
786         error = kern_kevent(td, uap->fd, uap->nchanges, uap->nevents,
787             &k_ops, tsp);
788         return (error);
789 }
790
791 int
792 freebsd32_gettimeofday(struct thread *td,
793                        struct freebsd32_gettimeofday_args *uap)
794 {
795         struct timeval atv;
796         struct timeval32 atv32;
797         struct timezone rtz;
798         int error = 0;
799
800         if (uap->tp) {
801                 microtime(&atv);
802                 CP(atv, atv32, tv_sec);
803                 CP(atv, atv32, tv_usec);
804                 error = copyout(&atv32, uap->tp, sizeof (atv32));
805         }
806         if (error == 0 && uap->tzp != NULL) {
807                 rtz.tz_minuteswest = tz_minuteswest;
808                 rtz.tz_dsttime = tz_dsttime;
809                 error = copyout(&rtz, uap->tzp, sizeof (rtz));
810         }
811         return (error);
812 }
813
814 int
815 freebsd32_getrusage(struct thread *td, struct freebsd32_getrusage_args *uap)
816 {
817         struct rusage32 s32;
818         struct rusage s;
819         int error;
820
821         error = kern_getrusage(td, uap->who, &s);
822         if (error)
823                 return (error);
824         if (uap->rusage != NULL) {
825                 freebsd32_rusage_out(&s, &s32);
826                 error = copyout(&s32, uap->rusage, sizeof(s32));
827         }
828         return (error);
829 }
830
831 static int
832 freebsd32_copyinuio(struct iovec32 *iovp, u_int iovcnt, struct uio **uiop)
833 {
834         struct iovec32 iov32;
835         struct iovec *iov;
836         struct uio *uio;
837         u_int iovlen;
838         int error, i;
839
840         *uiop = NULL;
841         if (iovcnt > UIO_MAXIOV)
842                 return (EINVAL);
843         iovlen = iovcnt * sizeof(struct iovec);
844         uio = malloc(iovlen + sizeof *uio, M_IOV, M_WAITOK);
845         iov = (struct iovec *)(uio + 1);
846         for (i = 0; i < iovcnt; i++) {
847                 error = copyin(&iovp[i], &iov32, sizeof(struct iovec32));
848                 if (error) {
849                         free(uio, M_IOV);
850                         return (error);
851                 }
852                 iov[i].iov_base = PTRIN(iov32.iov_base);
853                 iov[i].iov_len = iov32.iov_len;
854         }
855         uio->uio_iov = iov;
856         uio->uio_iovcnt = iovcnt;
857         uio->uio_segflg = UIO_USERSPACE;
858         uio->uio_offset = -1;
859         uio->uio_resid = 0;
860         for (i = 0; i < iovcnt; i++) {
861                 if (iov->iov_len > INT_MAX - uio->uio_resid) {
862                         free(uio, M_IOV);
863                         return (EINVAL);
864                 }
865                 uio->uio_resid += iov->iov_len;
866                 iov++;
867         }
868         *uiop = uio;
869         return (0);
870 }
871
872 int
873 freebsd32_readv(struct thread *td, struct freebsd32_readv_args *uap)
874 {
875         struct uio *auio;
876         int error;
877
878         error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
879         if (error)
880                 return (error);
881         error = kern_readv(td, uap->fd, auio);
882         free(auio, M_IOV);
883         return (error);
884 }
885
886 int
887 freebsd32_writev(struct thread *td, struct freebsd32_writev_args *uap)
888 {
889         struct uio *auio;
890         int error;
891
892         error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
893         if (error)
894                 return (error);
895         error = kern_writev(td, uap->fd, auio);
896         free(auio, M_IOV);
897         return (error);
898 }
899
900 int
901 freebsd32_preadv(struct thread *td, struct freebsd32_preadv_args *uap)
902 {
903         struct uio *auio;
904         int error;
905
906         error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
907         if (error)
908                 return (error);
909         error = kern_preadv(td, uap->fd, auio, PAIR32TO64(off_t,uap->offset));
910         free(auio, M_IOV);
911         return (error);
912 }
913
914 int
915 freebsd32_pwritev(struct thread *td, struct freebsd32_pwritev_args *uap)
916 {
917         struct uio *auio;
918         int error;
919
920         error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
921         if (error)
922                 return (error);
923         error = kern_pwritev(td, uap->fd, auio, PAIR32TO64(off_t,uap->offset));
924         free(auio, M_IOV);
925         return (error);
926 }
927
928 int
929 freebsd32_copyiniov(struct iovec32 *iovp32, u_int iovcnt, struct iovec **iovp,
930     int error)
931 {
932         struct iovec32 iov32;
933         struct iovec *iov;
934         u_int iovlen;
935         int i;
936
937         *iovp = NULL;
938         if (iovcnt > UIO_MAXIOV)
939                 return (error);
940         iovlen = iovcnt * sizeof(struct iovec);
941         iov = malloc(iovlen, M_IOV, M_WAITOK);
942         for (i = 0; i < iovcnt; i++) {
943                 error = copyin(&iovp32[i], &iov32, sizeof(struct iovec32));
944                 if (error) {
945                         free(iov, M_IOV);
946                         return (error);
947                 }
948                 iov[i].iov_base = PTRIN(iov32.iov_base);
949                 iov[i].iov_len = iov32.iov_len;
950         }
951         *iovp = iov;
952         return (0);
953 }
954
955 static int
956 freebsd32_copyinmsghdr(struct msghdr32 *msg32, struct msghdr *msg)
957 {
958         struct msghdr32 m32;
959         int error;
960
961         error = copyin(msg32, &m32, sizeof(m32));
962         if (error)
963                 return (error);
964         msg->msg_name = PTRIN(m32.msg_name);
965         msg->msg_namelen = m32.msg_namelen;
966         msg->msg_iov = PTRIN(m32.msg_iov);
967         msg->msg_iovlen = m32.msg_iovlen;
968         msg->msg_control = PTRIN(m32.msg_control);
969         msg->msg_controllen = m32.msg_controllen;
970         msg->msg_flags = m32.msg_flags;
971         return (0);
972 }
973
974 static int
975 freebsd32_copyoutmsghdr(struct msghdr *msg, struct msghdr32 *msg32)
976 {
977         struct msghdr32 m32;
978         int error;
979
980         m32.msg_name = PTROUT(msg->msg_name);
981         m32.msg_namelen = msg->msg_namelen;
982         m32.msg_iov = PTROUT(msg->msg_iov);
983         m32.msg_iovlen = msg->msg_iovlen;
984         m32.msg_control = PTROUT(msg->msg_control);
985         m32.msg_controllen = msg->msg_controllen;
986         m32.msg_flags = msg->msg_flags;
987         error = copyout(&m32, msg32, sizeof(m32));
988         return (error);
989 }
990
991 #ifndef __mips__
992 #define FREEBSD32_ALIGNBYTES    (sizeof(int) - 1)
993 #else
994 #define FREEBSD32_ALIGNBYTES    (sizeof(long) - 1)
995 #endif
996 #define FREEBSD32_ALIGN(p)      \
997         (((u_long)(p) + FREEBSD32_ALIGNBYTES) & ~FREEBSD32_ALIGNBYTES)
998 #define FREEBSD32_CMSG_SPACE(l) \
999         (FREEBSD32_ALIGN(sizeof(struct cmsghdr)) + FREEBSD32_ALIGN(l))
1000
1001 #define FREEBSD32_CMSG_DATA(cmsg)       ((unsigned char *)(cmsg) + \
1002                                  FREEBSD32_ALIGN(sizeof(struct cmsghdr)))
1003 static int
1004 freebsd32_copy_msg_out(struct msghdr *msg, struct mbuf *control)
1005 {
1006         struct cmsghdr *cm;
1007         void *data;
1008         socklen_t clen, datalen;
1009         int error;
1010         caddr_t ctlbuf;
1011         int len, maxlen, copylen;
1012         struct mbuf *m;
1013         error = 0;
1014
1015         len    = msg->msg_controllen;
1016         maxlen = msg->msg_controllen;
1017         msg->msg_controllen = 0;
1018
1019         m = control;
1020         ctlbuf = msg->msg_control;
1021       
1022         while (m && len > 0) {
1023                 cm = mtod(m, struct cmsghdr *);
1024                 clen = m->m_len;
1025
1026                 while (cm != NULL) {
1027
1028                         if (sizeof(struct cmsghdr) > clen ||
1029                             cm->cmsg_len > clen) {
1030                                 error = EINVAL;
1031                                 break;
1032                         }       
1033
1034                         data   = CMSG_DATA(cm);
1035                         datalen = (caddr_t)cm + cm->cmsg_len - (caddr_t)data;
1036
1037                         /* Adjust message length */
1038                         cm->cmsg_len = FREEBSD32_ALIGN(sizeof(struct cmsghdr)) +
1039                             datalen;
1040
1041
1042                         /* Copy cmsghdr */
1043                         copylen = sizeof(struct cmsghdr);
1044                         if (len < copylen) {
1045                                 msg->msg_flags |= MSG_CTRUNC;
1046                                 copylen = len;
1047                         }
1048
1049                         error = copyout(cm,ctlbuf,copylen);
1050                         if (error)
1051                                 goto exit;
1052
1053                         ctlbuf += FREEBSD32_ALIGN(copylen);
1054                         len    -= FREEBSD32_ALIGN(copylen);
1055
1056                         if (len <= 0)
1057                                 break;
1058
1059                         /* Copy data */
1060                         copylen = datalen;
1061                         if (len < copylen) {
1062                                 msg->msg_flags |= MSG_CTRUNC;
1063                                 copylen = len;
1064                         }
1065
1066                         error = copyout(data,ctlbuf,copylen);
1067                         if (error)
1068                                 goto exit;
1069
1070                         ctlbuf += FREEBSD32_ALIGN(copylen);
1071                         len    -= FREEBSD32_ALIGN(copylen);
1072
1073                         if (CMSG_SPACE(datalen) < clen) {
1074                                 clen -= CMSG_SPACE(datalen);
1075                                 cm = (struct cmsghdr *)
1076                                         ((caddr_t)cm + CMSG_SPACE(datalen));
1077                         } else {
1078                                 clen = 0;
1079                                 cm = NULL;
1080                         }
1081                 }       
1082                 m = m->m_next;
1083         }
1084
1085         msg->msg_controllen = (len <= 0) ? maxlen :  ctlbuf - (caddr_t)msg->msg_control;
1086         
1087 exit:
1088         return (error);
1089
1090 }
1091
1092 int
1093 freebsd32_recvmsg(td, uap)
1094         struct thread *td;
1095         struct freebsd32_recvmsg_args /* {
1096                 int     s;
1097                 struct  msghdr32 *msg;
1098                 int     flags;
1099         } */ *uap;
1100 {
1101         struct msghdr msg;
1102         struct msghdr32 m32;
1103         struct iovec *uiov, *iov;
1104         struct mbuf *control = NULL;
1105         struct mbuf **controlp;
1106
1107         int error;
1108         error = copyin(uap->msg, &m32, sizeof(m32));
1109         if (error)
1110                 return (error);
1111         error = freebsd32_copyinmsghdr(uap->msg, &msg);
1112         if (error)
1113                 return (error);
1114         error = freebsd32_copyiniov(PTRIN(m32.msg_iov), m32.msg_iovlen, &iov,
1115             EMSGSIZE);
1116         if (error)
1117                 return (error);
1118         msg.msg_flags = uap->flags;
1119         uiov = msg.msg_iov;
1120         msg.msg_iov = iov;
1121
1122         controlp = (msg.msg_control != NULL) ?  &control : NULL;
1123         error = kern_recvit(td, uap->s, &msg, UIO_USERSPACE, controlp);
1124         if (error == 0) {
1125                 msg.msg_iov = uiov;
1126                 
1127                 if (control != NULL)
1128                         error = freebsd32_copy_msg_out(&msg, control);
1129                 else
1130                         msg.msg_controllen = 0;
1131                 
1132                 if (error == 0)
1133                         error = freebsd32_copyoutmsghdr(&msg, uap->msg);
1134         }
1135         free(iov, M_IOV);
1136
1137         if (control != NULL)
1138                 m_freem(control);
1139
1140         return (error);
1141 }
1142
1143
1144 static int
1145 freebsd32_convert_msg_in(struct mbuf **controlp)
1146 {
1147         struct mbuf *control = *controlp;
1148         struct cmsghdr *cm = mtod(control, struct cmsghdr *);
1149         void *data;
1150         socklen_t clen = control->m_len, datalen;
1151         int error;
1152
1153         error = 0;
1154         *controlp = NULL;
1155
1156         while (cm != NULL) {
1157                 if (sizeof(struct cmsghdr) > clen || cm->cmsg_len > clen) {
1158                         error = EINVAL;
1159                         break;
1160                 }
1161
1162                 data = FREEBSD32_CMSG_DATA(cm);
1163                 datalen = (caddr_t)cm + cm->cmsg_len - (caddr_t)data;
1164
1165                 *controlp = sbcreatecontrol(data, datalen, cm->cmsg_type,
1166                     cm->cmsg_level);
1167                 controlp = &(*controlp)->m_next;
1168
1169                 if (FREEBSD32_CMSG_SPACE(datalen) < clen) {
1170                         clen -= FREEBSD32_CMSG_SPACE(datalen);
1171                         cm = (struct cmsghdr *)
1172                                 ((caddr_t)cm + FREEBSD32_CMSG_SPACE(datalen));
1173                 } else {
1174                         clen = 0;
1175                         cm = NULL;
1176                 }
1177         }
1178
1179         m_freem(control);
1180         return (error);
1181 }
1182
1183
1184 int
1185 freebsd32_sendmsg(struct thread *td,
1186                   struct freebsd32_sendmsg_args *uap)
1187 {
1188         struct msghdr msg;
1189         struct msghdr32 m32;
1190         struct iovec *iov;
1191         struct mbuf *control = NULL;
1192         struct sockaddr *to = NULL;
1193         int error;
1194
1195         error = copyin(uap->msg, &m32, sizeof(m32));
1196         if (error)
1197                 return (error);
1198         error = freebsd32_copyinmsghdr(uap->msg, &msg);
1199         if (error)
1200                 return (error);
1201         error = freebsd32_copyiniov(PTRIN(m32.msg_iov), m32.msg_iovlen, &iov,
1202             EMSGSIZE);
1203         if (error)
1204                 return (error);
1205         msg.msg_iov = iov;
1206         if (msg.msg_name != NULL) {
1207                 error = getsockaddr(&to, msg.msg_name, msg.msg_namelen);
1208                 if (error) {
1209                         to = NULL;
1210                         goto out;
1211                 }
1212                 msg.msg_name = to;
1213         }
1214
1215         if (msg.msg_control) {
1216                 if (msg.msg_controllen < sizeof(struct cmsghdr)) {
1217                         error = EINVAL;
1218                         goto out;
1219                 }
1220
1221                 error = sockargs(&control, msg.msg_control,
1222                     msg.msg_controllen, MT_CONTROL);
1223                 if (error)
1224                         goto out;
1225                 
1226                 error = freebsd32_convert_msg_in(&control);
1227                 if (error)
1228                         goto out;
1229         }
1230
1231         error = kern_sendit(td, uap->s, &msg, uap->flags, control,
1232             UIO_USERSPACE);
1233
1234 out:
1235         free(iov, M_IOV);
1236         if (to)
1237                 free(to, M_SONAME);
1238         return (error);
1239 }
1240
1241 int
1242 freebsd32_recvfrom(struct thread *td,
1243                    struct freebsd32_recvfrom_args *uap)
1244 {
1245         struct msghdr msg;
1246         struct iovec aiov;
1247         int error;
1248
1249         if (uap->fromlenaddr) {
1250                 error = copyin(PTRIN(uap->fromlenaddr), &msg.msg_namelen,
1251                     sizeof(msg.msg_namelen));
1252                 if (error)
1253                         return (error);
1254         } else {
1255                 msg.msg_namelen = 0;
1256         }
1257
1258         msg.msg_name = PTRIN(uap->from);
1259         msg.msg_iov = &aiov;
1260         msg.msg_iovlen = 1;
1261         aiov.iov_base = PTRIN(uap->buf);
1262         aiov.iov_len = uap->len;
1263         msg.msg_control = NULL;
1264         msg.msg_flags = uap->flags;
1265         error = kern_recvit(td, uap->s, &msg, UIO_USERSPACE, NULL);
1266         if (error == 0 && uap->fromlenaddr)
1267                 error = copyout(&msg.msg_namelen, PTRIN(uap->fromlenaddr),
1268                     sizeof (msg.msg_namelen));
1269         return (error);
1270 }
1271
1272 int
1273 freebsd32_settimeofday(struct thread *td,
1274                        struct freebsd32_settimeofday_args *uap)
1275 {
1276         struct timeval32 tv32;
1277         struct timeval tv, *tvp;
1278         struct timezone tz, *tzp;
1279         int error;
1280
1281         if (uap->tv) {
1282                 error = copyin(uap->tv, &tv32, sizeof(tv32));
1283                 if (error)
1284                         return (error);
1285                 CP(tv32, tv, tv_sec);
1286                 CP(tv32, tv, tv_usec);
1287                 tvp = &tv;
1288         } else
1289                 tvp = NULL;
1290         if (uap->tzp) {
1291                 error = copyin(uap->tzp, &tz, sizeof(tz));
1292                 if (error)
1293                         return (error);
1294                 tzp = &tz;
1295         } else
1296                 tzp = NULL;
1297         return (kern_settimeofday(td, tvp, tzp));
1298 }
1299
1300 int
1301 freebsd32_utimes(struct thread *td, struct freebsd32_utimes_args *uap)
1302 {
1303         struct timeval32 s32[2];
1304         struct timeval s[2], *sp;
1305         int error;
1306
1307         if (uap->tptr != NULL) {
1308                 error = copyin(uap->tptr, s32, sizeof(s32));
1309                 if (error)
1310                         return (error);
1311                 CP(s32[0], s[0], tv_sec);
1312                 CP(s32[0], s[0], tv_usec);
1313                 CP(s32[1], s[1], tv_sec);
1314                 CP(s32[1], s[1], tv_usec);
1315                 sp = s;
1316         } else
1317                 sp = NULL;
1318         return (kern_utimes(td, uap->path, UIO_USERSPACE, sp, UIO_SYSSPACE));
1319 }
1320
1321 int
1322 freebsd32_lutimes(struct thread *td, struct freebsd32_lutimes_args *uap)
1323 {
1324         struct timeval32 s32[2];
1325         struct timeval s[2], *sp;
1326         int error;
1327
1328         if (uap->tptr != NULL) {
1329                 error = copyin(uap->tptr, s32, sizeof(s32));
1330                 if (error)
1331                         return (error);
1332                 CP(s32[0], s[0], tv_sec);
1333                 CP(s32[0], s[0], tv_usec);
1334                 CP(s32[1], s[1], tv_sec);
1335                 CP(s32[1], s[1], tv_usec);
1336                 sp = s;
1337         } else
1338                 sp = NULL;
1339         return (kern_lutimes(td, uap->path, UIO_USERSPACE, sp, UIO_SYSSPACE));
1340 }
1341
1342 int
1343 freebsd32_futimes(struct thread *td, struct freebsd32_futimes_args *uap)
1344 {
1345         struct timeval32 s32[2];
1346         struct timeval s[2], *sp;
1347         int error;
1348
1349         if (uap->tptr != NULL) {
1350                 error = copyin(uap->tptr, s32, sizeof(s32));
1351                 if (error)
1352                         return (error);
1353                 CP(s32[0], s[0], tv_sec);
1354                 CP(s32[0], s[0], tv_usec);
1355                 CP(s32[1], s[1], tv_sec);
1356                 CP(s32[1], s[1], tv_usec);
1357                 sp = s;
1358         } else
1359                 sp = NULL;
1360         return (kern_futimes(td, uap->fd, sp, UIO_SYSSPACE));
1361 }
1362
1363 int
1364 freebsd32_futimesat(struct thread *td, struct freebsd32_futimesat_args *uap)
1365 {
1366         struct timeval32 s32[2];
1367         struct timeval s[2], *sp;
1368         int error;
1369
1370         if (uap->times != NULL) {
1371                 error = copyin(uap->times, s32, sizeof(s32));
1372                 if (error)
1373                         return (error);
1374                 CP(s32[0], s[0], tv_sec);
1375                 CP(s32[0], s[0], tv_usec);
1376                 CP(s32[1], s[1], tv_sec);
1377                 CP(s32[1], s[1], tv_usec);
1378                 sp = s;
1379         } else
1380                 sp = NULL;
1381         return (kern_utimesat(td, uap->fd, uap->path, UIO_USERSPACE,
1382                 sp, UIO_SYSSPACE));
1383 }
1384
1385 int
1386 freebsd32_adjtime(struct thread *td, struct freebsd32_adjtime_args *uap)
1387 {
1388         struct timeval32 tv32;
1389         struct timeval delta, olddelta, *deltap;
1390         int error;
1391
1392         if (uap->delta) {
1393                 error = copyin(uap->delta, &tv32, sizeof(tv32));
1394                 if (error)
1395                         return (error);
1396                 CP(tv32, delta, tv_sec);
1397                 CP(tv32, delta, tv_usec);
1398                 deltap = &delta;
1399         } else
1400                 deltap = NULL;
1401         error = kern_adjtime(td, deltap, &olddelta);
1402         if (uap->olddelta && error == 0) {
1403                 CP(olddelta, tv32, tv_sec);
1404                 CP(olddelta, tv32, tv_usec);
1405                 error = copyout(&tv32, uap->olddelta, sizeof(tv32));
1406         }
1407         return (error);
1408 }
1409
1410 #ifdef COMPAT_FREEBSD4
1411 int
1412 freebsd4_freebsd32_statfs(struct thread *td, struct freebsd4_freebsd32_statfs_args *uap)
1413 {
1414         struct statfs32 s32;
1415         struct statfs s;
1416         int error;
1417
1418         error = kern_statfs(td, uap->path, UIO_USERSPACE, &s);
1419         if (error)
1420                 return (error);
1421         copy_statfs(&s, &s32);
1422         return (copyout(&s32, uap->buf, sizeof(s32)));
1423 }
1424 #endif
1425
1426 #ifdef COMPAT_FREEBSD4
1427 int
1428 freebsd4_freebsd32_fstatfs(struct thread *td, struct freebsd4_freebsd32_fstatfs_args *uap)
1429 {
1430         struct statfs32 s32;
1431         struct statfs s;
1432         int error;
1433
1434         error = kern_fstatfs(td, uap->fd, &s);
1435         if (error)
1436                 return (error);
1437         copy_statfs(&s, &s32);
1438         return (copyout(&s32, uap->buf, sizeof(s32)));
1439 }
1440 #endif
1441
1442 #ifdef COMPAT_FREEBSD4
1443 int
1444 freebsd4_freebsd32_fhstatfs(struct thread *td, struct freebsd4_freebsd32_fhstatfs_args *uap)
1445 {
1446         struct statfs32 s32;
1447         struct statfs s;
1448         fhandle_t fh;
1449         int error;
1450
1451         if ((error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t))) != 0)
1452                 return (error);
1453         error = kern_fhstatfs(td, fh, &s);
1454         if (error)
1455                 return (error);
1456         copy_statfs(&s, &s32);
1457         return (copyout(&s32, uap->buf, sizeof(s32)));
1458 }
1459 #endif
1460
1461 int
1462 freebsd32_pread(struct thread *td, struct freebsd32_pread_args *uap)
1463 {
1464         struct pread_args ap;
1465
1466         ap.fd = uap->fd;
1467         ap.buf = uap->buf;
1468         ap.nbyte = uap->nbyte;
1469         ap.offset = PAIR32TO64(off_t,uap->offset);
1470         return (sys_pread(td, &ap));
1471 }
1472
1473 int
1474 freebsd32_pwrite(struct thread *td, struct freebsd32_pwrite_args *uap)
1475 {
1476         struct pwrite_args ap;
1477
1478         ap.fd = uap->fd;
1479         ap.buf = uap->buf;
1480         ap.nbyte = uap->nbyte;
1481         ap.offset = PAIR32TO64(off_t,uap->offset);
1482         return (sys_pwrite(td, &ap));
1483 }
1484
1485 #ifdef COMPAT_43
1486 int
1487 ofreebsd32_lseek(struct thread *td, struct ofreebsd32_lseek_args *uap)
1488 {
1489         struct lseek_args nuap;
1490
1491         nuap.fd = uap->fd;
1492         nuap.offset = uap->offset;
1493         nuap.whence = uap->whence;
1494         return (sys_lseek(td, &nuap));
1495 }
1496 #endif
1497
1498 int
1499 freebsd32_lseek(struct thread *td, struct freebsd32_lseek_args *uap)
1500 {
1501         int error;
1502         struct lseek_args ap;
1503         off_t pos;
1504
1505         ap.fd = uap->fd;
1506         ap.offset = PAIR32TO64(off_t,uap->offset);
1507         ap.whence = uap->whence;
1508         error = sys_lseek(td, &ap);
1509         /* Expand the quad return into two parts for eax and edx */
1510         pos = *(off_t *)(td->td_retval);
1511         td->td_retval[RETVAL_LO] = pos & 0xffffffff;    /* %eax */
1512         td->td_retval[RETVAL_HI] = pos >> 32;           /* %edx */
1513         return error;
1514 }
1515
1516 int
1517 freebsd32_truncate(struct thread *td, struct freebsd32_truncate_args *uap)
1518 {
1519         struct truncate_args ap;
1520
1521         ap.path = uap->path;
1522         ap.length = PAIR32TO64(off_t,uap->length);
1523         return (sys_truncate(td, &ap));
1524 }
1525
1526 int
1527 freebsd32_ftruncate(struct thread *td, struct freebsd32_ftruncate_args *uap)
1528 {
1529         struct ftruncate_args ap;
1530
1531         ap.fd = uap->fd;
1532         ap.length = PAIR32TO64(off_t,uap->length);
1533         return (sys_ftruncate(td, &ap));
1534 }
1535
1536 #ifdef COMPAT_43
1537 int
1538 ofreebsd32_getdirentries(struct thread *td,
1539     struct ofreebsd32_getdirentries_args *uap)
1540 {
1541         struct ogetdirentries_args ap;
1542         int error;
1543         long loff;
1544         int32_t loff_cut;
1545
1546         ap.fd = uap->fd;
1547         ap.buf = uap->buf;
1548         ap.count = uap->count;
1549         ap.basep = NULL;
1550         error = kern_ogetdirentries(td, &ap, &loff);
1551         if (error == 0) {
1552                 loff_cut = loff;
1553                 error = copyout(&loff_cut, uap->basep, sizeof(int32_t));
1554         }
1555         return (error);
1556 }
1557 #endif
1558
1559 int
1560 freebsd32_getdirentries(struct thread *td,
1561     struct freebsd32_getdirentries_args *uap)
1562 {
1563         long base;
1564         int32_t base32;
1565         int error;
1566
1567         error = kern_getdirentries(td, uap->fd, uap->buf, uap->count, &base,
1568             NULL, UIO_USERSPACE);
1569         if (error)
1570                 return (error);
1571         if (uap->basep != NULL) {
1572                 base32 = base;
1573                 error = copyout(&base32, uap->basep, sizeof(int32_t));
1574         }
1575         return (error);
1576 }
1577
1578 #ifdef COMPAT_FREEBSD6
1579 /* versions with the 'int pad' argument */
1580 int
1581 freebsd6_freebsd32_pread(struct thread *td, struct freebsd6_freebsd32_pread_args *uap)
1582 {
1583         struct pread_args ap;
1584
1585         ap.fd = uap->fd;
1586         ap.buf = uap->buf;
1587         ap.nbyte = uap->nbyte;
1588         ap.offset = PAIR32TO64(off_t,uap->offset);
1589         return (sys_pread(td, &ap));
1590 }
1591
1592 int
1593 freebsd6_freebsd32_pwrite(struct thread *td, struct freebsd6_freebsd32_pwrite_args *uap)
1594 {
1595         struct pwrite_args ap;
1596
1597         ap.fd = uap->fd;
1598         ap.buf = uap->buf;
1599         ap.nbyte = uap->nbyte;
1600         ap.offset = PAIR32TO64(off_t,uap->offset);
1601         return (sys_pwrite(td, &ap));
1602 }
1603
1604 int
1605 freebsd6_freebsd32_lseek(struct thread *td, struct freebsd6_freebsd32_lseek_args *uap)
1606 {
1607         int error;
1608         struct lseek_args ap;
1609         off_t pos;
1610
1611         ap.fd = uap->fd;
1612         ap.offset = PAIR32TO64(off_t,uap->offset);
1613         ap.whence = uap->whence;
1614         error = sys_lseek(td, &ap);
1615         /* Expand the quad return into two parts for eax and edx */
1616         pos = *(off_t *)(td->td_retval);
1617         td->td_retval[RETVAL_LO] = pos & 0xffffffff;    /* %eax */
1618         td->td_retval[RETVAL_HI] = pos >> 32;           /* %edx */
1619         return error;
1620 }
1621
1622 int
1623 freebsd6_freebsd32_truncate(struct thread *td, struct freebsd6_freebsd32_truncate_args *uap)
1624 {
1625         struct truncate_args ap;
1626
1627         ap.path = uap->path;
1628         ap.length = PAIR32TO64(off_t,uap->length);
1629         return (sys_truncate(td, &ap));
1630 }
1631
1632 int
1633 freebsd6_freebsd32_ftruncate(struct thread *td, struct freebsd6_freebsd32_ftruncate_args *uap)
1634 {
1635         struct ftruncate_args ap;
1636
1637         ap.fd = uap->fd;
1638         ap.length = PAIR32TO64(off_t,uap->length);
1639         return (sys_ftruncate(td, &ap));
1640 }
1641 #endif /* COMPAT_FREEBSD6 */
1642
1643 struct sf_hdtr32 {
1644         uint32_t headers;
1645         int hdr_cnt;
1646         uint32_t trailers;
1647         int trl_cnt;
1648 };
1649
1650 static int
1651 freebsd32_do_sendfile(struct thread *td,
1652     struct freebsd32_sendfile_args *uap, int compat)
1653 {
1654         struct sendfile_args ap;
1655         struct sf_hdtr32 hdtr32;
1656         struct sf_hdtr hdtr;
1657         struct uio *hdr_uio, *trl_uio;
1658         struct iovec32 *iov32;
1659         int error;
1660
1661         hdr_uio = trl_uio = NULL;
1662
1663         ap.fd = uap->fd;
1664         ap.s = uap->s;
1665         ap.offset = PAIR32TO64(off_t,uap->offset);
1666         ap.nbytes = uap->nbytes;
1667         ap.hdtr = (struct sf_hdtr *)uap->hdtr;          /* XXX not used */
1668         ap.sbytes = uap->sbytes;
1669         ap.flags = uap->flags;
1670
1671         if (uap->hdtr != NULL) {
1672                 error = copyin(uap->hdtr, &hdtr32, sizeof(hdtr32));
1673                 if (error)
1674                         goto out;
1675                 PTRIN_CP(hdtr32, hdtr, headers);
1676                 CP(hdtr32, hdtr, hdr_cnt);
1677                 PTRIN_CP(hdtr32, hdtr, trailers);
1678                 CP(hdtr32, hdtr, trl_cnt);
1679
1680                 if (hdtr.headers != NULL) {
1681                         iov32 = PTRIN(hdtr32.headers);
1682                         error = freebsd32_copyinuio(iov32,
1683                             hdtr32.hdr_cnt, &hdr_uio);
1684                         if (error)
1685                                 goto out;
1686                 }
1687                 if (hdtr.trailers != NULL) {
1688                         iov32 = PTRIN(hdtr32.trailers);
1689                         error = freebsd32_copyinuio(iov32,
1690                             hdtr32.trl_cnt, &trl_uio);
1691                         if (error)
1692                                 goto out;
1693                 }
1694         }
1695
1696         error = kern_sendfile(td, &ap, hdr_uio, trl_uio, compat);
1697 out:
1698         if (hdr_uio)
1699                 free(hdr_uio, M_IOV);
1700         if (trl_uio)
1701                 free(trl_uio, M_IOV);
1702         return (error);
1703 }
1704
1705 #ifdef COMPAT_FREEBSD4
1706 int
1707 freebsd4_freebsd32_sendfile(struct thread *td,
1708     struct freebsd4_freebsd32_sendfile_args *uap)
1709 {
1710         return (freebsd32_do_sendfile(td,
1711             (struct freebsd32_sendfile_args *)uap, 1));
1712 }
1713 #endif
1714
1715 int
1716 freebsd32_sendfile(struct thread *td, struct freebsd32_sendfile_args *uap)
1717 {
1718
1719         return (freebsd32_do_sendfile(td, uap, 0));
1720 }
1721
1722 static void
1723 copy_stat(struct stat *in, struct stat32 *out)
1724 {
1725
1726         CP(*in, *out, st_dev);
1727         CP(*in, *out, st_ino);
1728         CP(*in, *out, st_mode);
1729         CP(*in, *out, st_nlink);
1730         CP(*in, *out, st_uid);
1731         CP(*in, *out, st_gid);
1732         CP(*in, *out, st_rdev);
1733         TS_CP(*in, *out, st_atim);
1734         TS_CP(*in, *out, st_mtim);
1735         TS_CP(*in, *out, st_ctim);
1736         CP(*in, *out, st_size);
1737         CP(*in, *out, st_blocks);
1738         CP(*in, *out, st_blksize);
1739         CP(*in, *out, st_flags);
1740         CP(*in, *out, st_gen);
1741         TS_CP(*in, *out, st_birthtim);
1742 }
1743
1744 #ifdef COMPAT_43
1745 static void
1746 copy_ostat(struct stat *in, struct ostat32 *out)
1747 {
1748
1749         CP(*in, *out, st_dev);
1750         CP(*in, *out, st_ino);
1751         CP(*in, *out, st_mode);
1752         CP(*in, *out, st_nlink);
1753         CP(*in, *out, st_uid);
1754         CP(*in, *out, st_gid);
1755         CP(*in, *out, st_rdev);
1756         CP(*in, *out, st_size);
1757         TS_CP(*in, *out, st_atim);
1758         TS_CP(*in, *out, st_mtim);
1759         TS_CP(*in, *out, st_ctim);
1760         CP(*in, *out, st_blksize);
1761         CP(*in, *out, st_blocks);
1762         CP(*in, *out, st_flags);
1763         CP(*in, *out, st_gen);
1764 }
1765 #endif
1766
1767 int
1768 freebsd32_stat(struct thread *td, struct freebsd32_stat_args *uap)
1769 {
1770         struct stat sb;
1771         struct stat32 sb32;
1772         int error;
1773
1774         error = kern_stat(td, uap->path, UIO_USERSPACE, &sb);
1775         if (error)
1776                 return (error);
1777         copy_stat(&sb, &sb32);
1778         error = copyout(&sb32, uap->ub, sizeof (sb32));
1779         return (error);
1780 }
1781
1782 #ifdef COMPAT_43
1783 int
1784 ofreebsd32_stat(struct thread *td, struct ofreebsd32_stat_args *uap)
1785 {
1786         struct stat sb;
1787         struct ostat32 sb32;
1788         int error;
1789
1790         error = kern_stat(td, uap->path, UIO_USERSPACE, &sb);
1791         if (error)
1792                 return (error);
1793         copy_ostat(&sb, &sb32);
1794         error = copyout(&sb32, uap->ub, sizeof (sb32));
1795         return (error);
1796 }
1797 #endif
1798
1799 int
1800 freebsd32_fstat(struct thread *td, struct freebsd32_fstat_args *uap)
1801 {
1802         struct stat ub;
1803         struct stat32 ub32;
1804         int error;
1805
1806         error = kern_fstat(td, uap->fd, &ub);
1807         if (error)
1808                 return (error);
1809         copy_stat(&ub, &ub32);
1810         error = copyout(&ub32, uap->ub, sizeof(ub32));
1811         return (error);
1812 }
1813
1814 #ifdef COMPAT_43
1815 int
1816 ofreebsd32_fstat(struct thread *td, struct ofreebsd32_fstat_args *uap)
1817 {
1818         struct stat ub;
1819         struct ostat32 ub32;
1820         int error;
1821
1822         error = kern_fstat(td, uap->fd, &ub);
1823         if (error)
1824                 return (error);
1825         copy_ostat(&ub, &ub32);
1826         error = copyout(&ub32, uap->ub, sizeof(ub32));
1827         return (error);
1828 }
1829 #endif
1830
1831 int
1832 freebsd32_fstatat(struct thread *td, struct freebsd32_fstatat_args *uap)
1833 {
1834         struct stat ub;
1835         struct stat32 ub32;
1836         int error;
1837
1838         error = kern_statat(td, uap->flag, uap->fd, uap->path, UIO_USERSPACE, &ub);
1839         if (error)
1840                 return (error);
1841         copy_stat(&ub, &ub32);
1842         error = copyout(&ub32, uap->buf, sizeof(ub32));
1843         return (error);
1844 }
1845
1846 int
1847 freebsd32_lstat(struct thread *td, struct freebsd32_lstat_args *uap)
1848 {
1849         struct stat sb;
1850         struct stat32 sb32;
1851         int error;
1852
1853         error = kern_lstat(td, uap->path, UIO_USERSPACE, &sb);
1854         if (error)
1855                 return (error);
1856         copy_stat(&sb, &sb32);
1857         error = copyout(&sb32, uap->ub, sizeof (sb32));
1858         return (error);
1859 }
1860
1861 #ifdef COMPAT_43
1862 int
1863 ofreebsd32_lstat(struct thread *td, struct ofreebsd32_lstat_args *uap)
1864 {
1865         struct stat sb;
1866         struct ostat32 sb32;
1867         int error;
1868
1869         error = kern_lstat(td, uap->path, UIO_USERSPACE, &sb);
1870         if (error)
1871                 return (error);
1872         copy_ostat(&sb, &sb32);
1873         error = copyout(&sb32, uap->ub, sizeof (sb32));
1874         return (error);
1875 }
1876 #endif
1877
1878 int
1879 freebsd32_sysctl(struct thread *td, struct freebsd32_sysctl_args *uap)
1880 {
1881         int error, name[CTL_MAXNAME];
1882         size_t j, oldlen;
1883
1884         if (uap->namelen > CTL_MAXNAME || uap->namelen < 2)
1885                 return (EINVAL);
1886         error = copyin(uap->name, name, uap->namelen * sizeof(int));
1887         if (error)
1888                 return (error);
1889         if (uap->oldlenp)
1890                 oldlen = fuword32(uap->oldlenp);
1891         else
1892                 oldlen = 0;
1893         error = userland_sysctl(td, name, uap->namelen,
1894                 uap->old, &oldlen, 1,
1895                 uap->new, uap->newlen, &j, SCTL_MASK32);
1896         if (error && error != ENOMEM)
1897                 return (error);
1898         if (uap->oldlenp)
1899                 suword32(uap->oldlenp, j);
1900         return (0);
1901 }
1902
1903 int
1904 freebsd32_jail(struct thread *td, struct freebsd32_jail_args *uap)
1905 {
1906         uint32_t version;
1907         int error;
1908         struct jail j;
1909
1910         error = copyin(uap->jail, &version, sizeof(uint32_t));
1911         if (error)
1912                 return (error);
1913
1914         switch (version) {
1915         case 0:
1916         {
1917                 /* FreeBSD single IPv4 jails. */
1918                 struct jail32_v0 j32_v0;
1919
1920                 bzero(&j, sizeof(struct jail));
1921                 error = copyin(uap->jail, &j32_v0, sizeof(struct jail32_v0));
1922                 if (error)
1923                         return (error);
1924                 CP(j32_v0, j, version);
1925                 PTRIN_CP(j32_v0, j, path);
1926                 PTRIN_CP(j32_v0, j, hostname);
1927                 j.ip4s = j32_v0.ip_number;
1928                 break;
1929         }
1930
1931         case 1:
1932                 /*
1933                  * Version 1 was used by multi-IPv4 jail implementations
1934                  * that never made it into the official kernel.
1935                  */
1936                 return (EINVAL);
1937
1938         case 2: /* JAIL_API_VERSION */
1939         {
1940                 /* FreeBSD multi-IPv4/IPv6,noIP jails. */
1941                 struct jail32 j32;
1942
1943                 error = copyin(uap->jail, &j32, sizeof(struct jail32));
1944                 if (error)
1945                         return (error);
1946                 CP(j32, j, version);
1947                 PTRIN_CP(j32, j, path);
1948                 PTRIN_CP(j32, j, hostname);
1949                 PTRIN_CP(j32, j, jailname);
1950                 CP(j32, j, ip4s);
1951                 CP(j32, j, ip6s);
1952                 PTRIN_CP(j32, j, ip4);
1953                 PTRIN_CP(j32, j, ip6);
1954                 break;
1955         }
1956
1957         default:
1958                 /* Sci-Fi jails are not supported, sorry. */
1959                 return (EINVAL);
1960         }
1961         return (kern_jail(td, &j));
1962 }
1963
1964 int
1965 freebsd32_jail_set(struct thread *td, struct freebsd32_jail_set_args *uap)
1966 {
1967         struct uio *auio;
1968         int error;
1969
1970         /* Check that we have an even number of iovecs. */
1971         if (uap->iovcnt & 1)
1972                 return (EINVAL);
1973
1974         error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
1975         if (error)
1976                 return (error);
1977         error = kern_jail_set(td, auio, uap->flags);
1978         free(auio, M_IOV);
1979         return (error);
1980 }
1981
1982 int
1983 freebsd32_jail_get(struct thread *td, struct freebsd32_jail_get_args *uap)
1984 {
1985         struct iovec32 iov32;
1986         struct uio *auio;
1987         int error, i;
1988
1989         /* Check that we have an even number of iovecs. */
1990         if (uap->iovcnt & 1)
1991                 return (EINVAL);
1992
1993         error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
1994         if (error)
1995                 return (error);
1996         error = kern_jail_get(td, auio, uap->flags);
1997         if (error == 0)
1998                 for (i = 0; i < uap->iovcnt; i++) {
1999                         PTROUT_CP(auio->uio_iov[i], iov32, iov_base);
2000                         CP(auio->uio_iov[i], iov32, iov_len);
2001                         error = copyout(&iov32, uap->iovp + i, sizeof(iov32));
2002                         if (error != 0)
2003                                 break;
2004                 }
2005         free(auio, M_IOV);
2006         return (error);
2007 }
2008
2009 int
2010 freebsd32_sigaction(struct thread *td, struct freebsd32_sigaction_args *uap)
2011 {
2012         struct sigaction32 s32;
2013         struct sigaction sa, osa, *sap;
2014         int error;
2015
2016         if (uap->act) {
2017                 error = copyin(uap->act, &s32, sizeof(s32));
2018                 if (error)
2019                         return (error);
2020                 sa.sa_handler = PTRIN(s32.sa_u);
2021                 CP(s32, sa, sa_flags);
2022                 CP(s32, sa, sa_mask);
2023                 sap = &sa;
2024         } else
2025                 sap = NULL;
2026         error = kern_sigaction(td, uap->sig, sap, &osa, 0);
2027         if (error == 0 && uap->oact != NULL) {
2028                 s32.sa_u = PTROUT(osa.sa_handler);
2029                 CP(osa, s32, sa_flags);
2030                 CP(osa, s32, sa_mask);
2031                 error = copyout(&s32, uap->oact, sizeof(s32));
2032         }
2033         return (error);
2034 }
2035
2036 #ifdef COMPAT_FREEBSD4
2037 int
2038 freebsd4_freebsd32_sigaction(struct thread *td,
2039                              struct freebsd4_freebsd32_sigaction_args *uap)
2040 {
2041         struct sigaction32 s32;
2042         struct sigaction sa, osa, *sap;
2043         int error;
2044
2045         if (uap->act) {
2046                 error = copyin(uap->act, &s32, sizeof(s32));
2047                 if (error)
2048                         return (error);
2049                 sa.sa_handler = PTRIN(s32.sa_u);
2050                 CP(s32, sa, sa_flags);
2051                 CP(s32, sa, sa_mask);
2052                 sap = &sa;
2053         } else
2054                 sap = NULL;
2055         error = kern_sigaction(td, uap->sig, sap, &osa, KSA_FREEBSD4);
2056         if (error == 0 && uap->oact != NULL) {
2057                 s32.sa_u = PTROUT(osa.sa_handler);
2058                 CP(osa, s32, sa_flags);
2059                 CP(osa, s32, sa_mask);
2060                 error = copyout(&s32, uap->oact, sizeof(s32));
2061         }
2062         return (error);
2063 }
2064 #endif
2065
2066 #ifdef COMPAT_43
2067 struct osigaction32 {
2068         u_int32_t       sa_u;
2069         osigset_t       sa_mask;
2070         int             sa_flags;
2071 };
2072
2073 #define ONSIG   32
2074
2075 int
2076 ofreebsd32_sigaction(struct thread *td,
2077                              struct ofreebsd32_sigaction_args *uap)
2078 {
2079         struct osigaction32 s32;
2080         struct sigaction sa, osa, *sap;
2081         int error;
2082
2083         if (uap->signum <= 0 || uap->signum >= ONSIG)
2084                 return (EINVAL);
2085
2086         if (uap->nsa) {
2087                 error = copyin(uap->nsa, &s32, sizeof(s32));
2088                 if (error)
2089                         return (error);
2090                 sa.sa_handler = PTRIN(s32.sa_u);
2091                 CP(s32, sa, sa_flags);
2092                 OSIG2SIG(s32.sa_mask, sa.sa_mask);
2093                 sap = &sa;
2094         } else
2095                 sap = NULL;
2096         error = kern_sigaction(td, uap->signum, sap, &osa, KSA_OSIGSET);
2097         if (error == 0 && uap->osa != NULL) {
2098                 s32.sa_u = PTROUT(osa.sa_handler);
2099                 CP(osa, s32, sa_flags);
2100                 SIG2OSIG(osa.sa_mask, s32.sa_mask);
2101                 error = copyout(&s32, uap->osa, sizeof(s32));
2102         }
2103         return (error);
2104 }
2105
2106 int
2107 ofreebsd32_sigprocmask(struct thread *td,
2108                                struct ofreebsd32_sigprocmask_args *uap)
2109 {
2110         sigset_t set, oset;
2111         int error;
2112
2113         OSIG2SIG(uap->mask, set);
2114         error = kern_sigprocmask(td, uap->how, &set, &oset, SIGPROCMASK_OLD);
2115         SIG2OSIG(oset, td->td_retval[0]);
2116         return (error);
2117 }
2118
2119 int
2120 ofreebsd32_sigpending(struct thread *td,
2121                               struct ofreebsd32_sigpending_args *uap)
2122 {
2123         struct proc *p = td->td_proc;
2124         sigset_t siglist;
2125
2126         PROC_LOCK(p);
2127         siglist = p->p_siglist;
2128         SIGSETOR(siglist, td->td_siglist);
2129         PROC_UNLOCK(p);
2130         SIG2OSIG(siglist, td->td_retval[0]);
2131         return (0);
2132 }
2133
2134 struct sigvec32 {
2135         u_int32_t       sv_handler;
2136         int             sv_mask;
2137         int             sv_flags;
2138 };
2139
2140 int
2141 ofreebsd32_sigvec(struct thread *td,
2142                           struct ofreebsd32_sigvec_args *uap)
2143 {
2144         struct sigvec32 vec;
2145         struct sigaction sa, osa, *sap;
2146         int error;
2147
2148         if (uap->signum <= 0 || uap->signum >= ONSIG)
2149                 return (EINVAL);
2150
2151         if (uap->nsv) {
2152                 error = copyin(uap->nsv, &vec, sizeof(vec));
2153                 if (error)
2154                         return (error);
2155                 sa.sa_handler = PTRIN(vec.sv_handler);
2156                 OSIG2SIG(vec.sv_mask, sa.sa_mask);
2157                 sa.sa_flags = vec.sv_flags;
2158                 sa.sa_flags ^= SA_RESTART;
2159                 sap = &sa;
2160         } else
2161                 sap = NULL;
2162         error = kern_sigaction(td, uap->signum, sap, &osa, KSA_OSIGSET);
2163         if (error == 0 && uap->osv != NULL) {
2164                 vec.sv_handler = PTROUT(osa.sa_handler);
2165                 SIG2OSIG(osa.sa_mask, vec.sv_mask);
2166                 vec.sv_flags = osa.sa_flags;
2167                 vec.sv_flags &= ~SA_NOCLDWAIT;
2168                 vec.sv_flags ^= SA_RESTART;
2169                 error = copyout(&vec, uap->osv, sizeof(vec));
2170         }
2171         return (error);
2172 }
2173
2174 int
2175 ofreebsd32_sigblock(struct thread *td,
2176                             struct ofreebsd32_sigblock_args *uap)
2177 {
2178         sigset_t set, oset;
2179
2180         OSIG2SIG(uap->mask, set);
2181         kern_sigprocmask(td, SIG_BLOCK, &set, &oset, 0);
2182         SIG2OSIG(oset, td->td_retval[0]);
2183         return (0);
2184 }
2185
2186 int
2187 ofreebsd32_sigsetmask(struct thread *td,
2188                               struct ofreebsd32_sigsetmask_args *uap)
2189 {
2190         sigset_t set, oset;
2191
2192         OSIG2SIG(uap->mask, set);
2193         kern_sigprocmask(td, SIG_SETMASK, &set, &oset, 0);
2194         SIG2OSIG(oset, td->td_retval[0]);
2195         return (0);
2196 }
2197
2198 int
2199 ofreebsd32_sigsuspend(struct thread *td,
2200                               struct ofreebsd32_sigsuspend_args *uap)
2201 {
2202         sigset_t mask;
2203
2204         OSIG2SIG(uap->mask, mask);
2205         return (kern_sigsuspend(td, mask));
2206 }
2207
2208 struct sigstack32 {
2209         u_int32_t       ss_sp;
2210         int             ss_onstack;
2211 };
2212
2213 int
2214 ofreebsd32_sigstack(struct thread *td,
2215                             struct ofreebsd32_sigstack_args *uap)
2216 {
2217         struct sigstack32 s32;
2218         struct sigstack nss, oss;
2219         int error = 0, unss;
2220
2221         if (uap->nss != NULL) {
2222                 error = copyin(uap->nss, &s32, sizeof(s32));
2223                 if (error)
2224                         return (error);
2225                 nss.ss_sp = PTRIN(s32.ss_sp);
2226                 CP(s32, nss, ss_onstack);
2227                 unss = 1;
2228         } else {
2229                 unss = 0;
2230         }
2231         oss.ss_sp = td->td_sigstk.ss_sp;
2232         oss.ss_onstack = sigonstack(cpu_getstack(td));
2233         if (unss) {
2234                 td->td_sigstk.ss_sp = nss.ss_sp;
2235                 td->td_sigstk.ss_size = 0;
2236                 td->td_sigstk.ss_flags |= (nss.ss_onstack & SS_ONSTACK);
2237                 td->td_pflags |= TDP_ALTSTACK;
2238         }
2239         if (uap->oss != NULL) {
2240                 s32.ss_sp = PTROUT(oss.ss_sp);
2241                 CP(oss, s32, ss_onstack);
2242                 error = copyout(&s32, uap->oss, sizeof(s32));
2243         }
2244         return (error);
2245 }
2246 #endif
2247
2248 int
2249 freebsd32_nanosleep(struct thread *td, struct freebsd32_nanosleep_args *uap)
2250 {
2251         struct timespec32 rmt32, rqt32;
2252         struct timespec rmt, rqt;
2253         int error;
2254
2255         error = copyin(uap->rqtp, &rqt32, sizeof(rqt32));
2256         if (error)
2257                 return (error);
2258
2259         CP(rqt32, rqt, tv_sec);
2260         CP(rqt32, rqt, tv_nsec);
2261
2262         if (uap->rmtp &&
2263             !useracc((caddr_t)uap->rmtp, sizeof(rmt), VM_PROT_WRITE))
2264                 return (EFAULT);
2265         error = kern_nanosleep(td, &rqt, &rmt);
2266         if (error && uap->rmtp) {
2267                 int error2;
2268
2269                 CP(rmt, rmt32, tv_sec);
2270                 CP(rmt, rmt32, tv_nsec);
2271
2272                 error2 = copyout(&rmt32, uap->rmtp, sizeof(rmt32));
2273                 if (error2)
2274                         error = error2;
2275         }
2276         return (error);
2277 }
2278
2279 int
2280 freebsd32_clock_gettime(struct thread *td,
2281                         struct freebsd32_clock_gettime_args *uap)
2282 {
2283         struct timespec ats;
2284         struct timespec32 ats32;
2285         int error;
2286
2287         error = kern_clock_gettime(td, uap->clock_id, &ats);
2288         if (error == 0) {
2289                 CP(ats, ats32, tv_sec);
2290                 CP(ats, ats32, tv_nsec);
2291                 error = copyout(&ats32, uap->tp, sizeof(ats32));
2292         }
2293         return (error);
2294 }
2295
2296 int
2297 freebsd32_clock_settime(struct thread *td,
2298                         struct freebsd32_clock_settime_args *uap)
2299 {
2300         struct timespec ats;
2301         struct timespec32 ats32;
2302         int error;
2303
2304         error = copyin(uap->tp, &ats32, sizeof(ats32));
2305         if (error)
2306                 return (error);
2307         CP(ats32, ats, tv_sec);
2308         CP(ats32, ats, tv_nsec);
2309
2310         return (kern_clock_settime(td, uap->clock_id, &ats));
2311 }
2312
2313 int
2314 freebsd32_clock_getres(struct thread *td,
2315                        struct freebsd32_clock_getres_args *uap)
2316 {
2317         struct timespec ts;
2318         struct timespec32 ts32;
2319         int error;
2320
2321         if (uap->tp == NULL)
2322                 return (0);
2323         error = kern_clock_getres(td, uap->clock_id, &ts);
2324         if (error == 0) {
2325                 CP(ts, ts32, tv_sec);
2326                 CP(ts, ts32, tv_nsec);
2327                 error = copyout(&ts32, uap->tp, sizeof(ts32));
2328         }
2329         return (error);
2330 }
2331
2332 int
2333 freebsd32_thr_new(struct thread *td,
2334                   struct freebsd32_thr_new_args *uap)
2335 {
2336         struct thr_param32 param32;
2337         struct thr_param param;
2338         int error;
2339
2340         if (uap->param_size < 0 ||
2341             uap->param_size > sizeof(struct thr_param32))
2342                 return (EINVAL);
2343         bzero(&param, sizeof(struct thr_param));
2344         bzero(&param32, sizeof(struct thr_param32));
2345         error = copyin(uap->param, &param32, uap->param_size);
2346         if (error != 0)
2347                 return (error);
2348         param.start_func = PTRIN(param32.start_func);
2349         param.arg = PTRIN(param32.arg);
2350         param.stack_base = PTRIN(param32.stack_base);
2351         param.stack_size = param32.stack_size;
2352         param.tls_base = PTRIN(param32.tls_base);
2353         param.tls_size = param32.tls_size;
2354         param.child_tid = PTRIN(param32.child_tid);
2355         param.parent_tid = PTRIN(param32.parent_tid);
2356         param.flags = param32.flags;
2357         param.rtp = PTRIN(param32.rtp);
2358         param.spare[0] = PTRIN(param32.spare[0]);
2359         param.spare[1] = PTRIN(param32.spare[1]);
2360         param.spare[2] = PTRIN(param32.spare[2]);
2361
2362         return (kern_thr_new(td, &param));
2363 }
2364
2365 int
2366 freebsd32_thr_suspend(struct thread *td, struct freebsd32_thr_suspend_args *uap)
2367 {
2368         struct timespec32 ts32;
2369         struct timespec ts, *tsp;
2370         int error;
2371
2372         error = 0;
2373         tsp = NULL;
2374         if (uap->timeout != NULL) {
2375                 error = copyin((const void *)uap->timeout, (void *)&ts32,
2376                     sizeof(struct timespec32));
2377                 if (error != 0)
2378                         return (error);
2379                 ts.tv_sec = ts32.tv_sec;
2380                 ts.tv_nsec = ts32.tv_nsec;
2381                 tsp = &ts;
2382         }
2383         return (kern_thr_suspend(td, tsp));
2384 }
2385
2386 void
2387 siginfo_to_siginfo32(const siginfo_t *src, struct siginfo32 *dst)
2388 {
2389         bzero(dst, sizeof(*dst));
2390         dst->si_signo = src->si_signo;
2391         dst->si_errno = src->si_errno;
2392         dst->si_code = src->si_code;
2393         dst->si_pid = src->si_pid;
2394         dst->si_uid = src->si_uid;
2395         dst->si_status = src->si_status;
2396         dst->si_addr = (uintptr_t)src->si_addr;
2397         dst->si_value.sigval_int = src->si_value.sival_int;
2398         dst->si_timerid = src->si_timerid;
2399         dst->si_overrun = src->si_overrun;
2400 }
2401
2402 int
2403 freebsd32_sigtimedwait(struct thread *td, struct freebsd32_sigtimedwait_args *uap)
2404 {
2405         struct timespec32 ts32;
2406         struct timespec ts;
2407         struct timespec *timeout;
2408         sigset_t set;
2409         ksiginfo_t ksi;
2410         struct siginfo32 si32;
2411         int error;
2412
2413         if (uap->timeout) {
2414                 error = copyin(uap->timeout, &ts32, sizeof(ts32));
2415                 if (error)
2416                         return (error);
2417                 ts.tv_sec = ts32.tv_sec;
2418                 ts.tv_nsec = ts32.tv_nsec;
2419                 timeout = &ts;
2420         } else
2421                 timeout = NULL;
2422
2423         error = copyin(uap->set, &set, sizeof(set));
2424         if (error)
2425                 return (error);
2426
2427         error = kern_sigtimedwait(td, set, &ksi, timeout);
2428         if (error)
2429                 return (error);
2430
2431         if (uap->info) {
2432                 siginfo_to_siginfo32(&ksi.ksi_info, &si32);
2433                 error = copyout(&si32, uap->info, sizeof(struct siginfo32));
2434         }
2435
2436         if (error == 0)
2437                 td->td_retval[0] = ksi.ksi_signo;
2438         return (error);
2439 }
2440
2441 /*
2442  * MPSAFE
2443  */
2444 int
2445 freebsd32_sigwaitinfo(struct thread *td, struct freebsd32_sigwaitinfo_args *uap)
2446 {
2447         ksiginfo_t ksi;
2448         struct siginfo32 si32;
2449         sigset_t set;
2450         int error;
2451
2452         error = copyin(uap->set, &set, sizeof(set));
2453         if (error)
2454                 return (error);
2455
2456         error = kern_sigtimedwait(td, set, &ksi, NULL);
2457         if (error)
2458                 return (error);
2459
2460         if (uap->info) {
2461                 siginfo_to_siginfo32(&ksi.ksi_info, &si32);
2462                 error = copyout(&si32, uap->info, sizeof(struct siginfo32));
2463         }       
2464         if (error == 0)
2465                 td->td_retval[0] = ksi.ksi_signo;
2466         return (error);
2467 }
2468
2469 int
2470 freebsd32_cpuset_setid(struct thread *td,
2471     struct freebsd32_cpuset_setid_args *uap)
2472 {
2473         struct cpuset_setid_args ap;
2474
2475         ap.which = uap->which;
2476         ap.id = PAIR32TO64(id_t,uap->id);
2477         ap.setid = uap->setid;
2478
2479         return (sys_cpuset_setid(td, &ap));
2480 }
2481
2482 int
2483 freebsd32_cpuset_getid(struct thread *td,
2484     struct freebsd32_cpuset_getid_args *uap)
2485 {
2486         struct cpuset_getid_args ap;
2487
2488         ap.level = uap->level;
2489         ap.which = uap->which;
2490         ap.id = PAIR32TO64(id_t,uap->id);
2491         ap.setid = uap->setid;
2492
2493         return (sys_cpuset_getid(td, &ap));
2494 }
2495
2496 int
2497 freebsd32_cpuset_getaffinity(struct thread *td,
2498     struct freebsd32_cpuset_getaffinity_args *uap)
2499 {
2500         struct cpuset_getaffinity_args ap;
2501
2502         ap.level = uap->level;
2503         ap.which = uap->which;
2504         ap.id = PAIR32TO64(id_t,uap->id);
2505         ap.cpusetsize = uap->cpusetsize;
2506         ap.mask = uap->mask;
2507
2508         return (sys_cpuset_getaffinity(td, &ap));
2509 }
2510
2511 int
2512 freebsd32_cpuset_setaffinity(struct thread *td,
2513     struct freebsd32_cpuset_setaffinity_args *uap)
2514 {
2515         struct cpuset_setaffinity_args ap;
2516
2517         ap.level = uap->level;
2518         ap.which = uap->which;
2519         ap.id = PAIR32TO64(id_t,uap->id);
2520         ap.cpusetsize = uap->cpusetsize;
2521         ap.mask = uap->mask;
2522
2523         return (sys_cpuset_setaffinity(td, &ap));
2524 }
2525
2526 int
2527 freebsd32_nmount(struct thread *td,
2528     struct freebsd32_nmount_args /* {
2529         struct iovec *iovp;
2530         unsigned int iovcnt;
2531         int flags;
2532     } */ *uap)
2533 {
2534         struct uio *auio;
2535         uint64_t flags;
2536         int error;
2537
2538         /*
2539          * Mount flags are now 64-bits. On 32-bit archtectures only
2540          * 32-bits are passed in, but from here on everything handles
2541          * 64-bit flags correctly.
2542          */
2543         flags = uap->flags;
2544
2545         AUDIT_ARG_FFLAGS(flags);
2546
2547         /*
2548          * Filter out MNT_ROOTFS.  We do not want clients of nmount() in
2549          * userspace to set this flag, but we must filter it out if we want
2550          * MNT_UPDATE on the root file system to work.
2551          * MNT_ROOTFS should only be set by the kernel when mounting its
2552          * root file system.
2553          */
2554         flags &= ~MNT_ROOTFS;
2555
2556         /*
2557          * check that we have an even number of iovec's
2558          * and that we have at least two options.
2559          */
2560         if ((uap->iovcnt & 1) || (uap->iovcnt < 4))
2561                 return (EINVAL);
2562
2563         error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
2564         if (error)
2565                 return (error);
2566         error = vfs_donmount(td, flags, auio);
2567
2568         free(auio, M_IOV);
2569         return error;
2570 }
2571
2572 #if 0
2573 int
2574 freebsd32_xxx(struct thread *td, struct freebsd32_xxx_args *uap)
2575 {
2576         struct yyy32 *p32, s32;
2577         struct yyy *p = NULL, s;
2578         struct xxx_arg ap;
2579         int error;
2580
2581         if (uap->zzz) {
2582                 error = copyin(uap->zzz, &s32, sizeof(s32));
2583                 if (error)
2584                         return (error);
2585                 /* translate in */
2586                 p = &s;
2587         }
2588         error = kern_xxx(td, p);
2589         if (error)
2590                 return (error);
2591         if (uap->zzz) {
2592                 /* translate out */
2593                 error = copyout(&s32, p32, sizeof(s32));
2594         }
2595         return (error);
2596 }
2597 #endif
2598
2599 int
2600 syscall32_register(int *offset, struct sysent *new_sysent,
2601     struct sysent *old_sysent)
2602 {
2603         if (*offset == NO_SYSCALL) {
2604                 int i;
2605
2606                 for (i = 1; i < SYS_MAXSYSCALL; ++i)
2607                         if (freebsd32_sysent[i].sy_call ==
2608                             (sy_call_t *)lkmnosys)
2609                                 break;
2610                 if (i == SYS_MAXSYSCALL)
2611                         return (ENFILE);
2612                 *offset = i;
2613         } else if (*offset < 0 || *offset >= SYS_MAXSYSCALL)
2614                 return (EINVAL);
2615         else if (freebsd32_sysent[*offset].sy_call != (sy_call_t *)lkmnosys &&
2616             freebsd32_sysent[*offset].sy_call != (sy_call_t *)lkmressys)
2617                 return (EEXIST);
2618
2619         *old_sysent = freebsd32_sysent[*offset];
2620         freebsd32_sysent[*offset] = *new_sysent;
2621         return 0;
2622 }
2623
2624 int
2625 syscall32_deregister(int *offset, struct sysent *old_sysent)
2626 {
2627
2628         if (*offset)
2629                 freebsd32_sysent[*offset] = *old_sysent;
2630         return 0;
2631 }
2632
2633 int
2634 syscall32_module_handler(struct module *mod, int what, void *arg)
2635 {
2636         struct syscall_module_data *data = (struct syscall_module_data*)arg;
2637         modspecific_t ms;
2638         int error;
2639
2640         switch (what) {
2641         case MOD_LOAD:
2642                 error = syscall32_register(data->offset, data->new_sysent,
2643                     &data->old_sysent);
2644                 if (error) {
2645                         /* Leave a mark so we know to safely unload below. */
2646                         data->offset = NULL;
2647                         return error;
2648                 }
2649                 ms.intval = *data->offset;
2650                 MOD_XLOCK;
2651                 module_setspecific(mod, &ms);
2652                 MOD_XUNLOCK;
2653                 if (data->chainevh)
2654                         error = data->chainevh(mod, what, data->chainarg);
2655                 return (error);
2656         case MOD_UNLOAD:
2657                 /*
2658                  * MOD_LOAD failed, so just return without calling the
2659                  * chained handler since we didn't pass along the MOD_LOAD
2660                  * event.
2661                  */
2662                 if (data->offset == NULL)
2663                         return (0);
2664                 if (data->chainevh) {
2665                         error = data->chainevh(mod, what, data->chainarg);
2666                         if (error)
2667                                 return (error);
2668                 }
2669                 error = syscall32_deregister(data->offset, &data->old_sysent);
2670                 return (error);
2671         default:
2672                 error = EOPNOTSUPP;
2673                 if (data->chainevh)
2674                         error = data->chainevh(mod, what, data->chainarg);
2675                 return (error);
2676         }
2677 }
2678
2679 int
2680 syscall32_helper_register(struct syscall_helper_data *sd)
2681 {
2682         struct syscall_helper_data *sd1;
2683         int error;
2684
2685         for (sd1 = sd; sd1->syscall_no != NO_SYSCALL; sd1++) {
2686                 error = syscall32_register(&sd1->syscall_no, &sd1->new_sysent,
2687                     &sd1->old_sysent);
2688                 if (error != 0) {
2689                         syscall32_helper_unregister(sd);
2690                         return (error);
2691                 }
2692                 sd1->registered = 1;
2693         }
2694         return (0);
2695 }
2696
2697 int
2698 syscall32_helper_unregister(struct syscall_helper_data *sd)
2699 {
2700         struct syscall_helper_data *sd1;
2701
2702         for (sd1 = sd; sd1->registered != 0; sd1++) {
2703                 syscall32_deregister(&sd1->syscall_no, &sd1->old_sysent);
2704                 sd1->registered = 0;
2705         }
2706         return (0);
2707 }
2708
2709 register_t *
2710 freebsd32_copyout_strings(struct image_params *imgp)
2711 {
2712         int argc, envc, i;
2713         u_int32_t *vectp;
2714         char *stringp, *destp;
2715         u_int32_t *stack_base;
2716         struct freebsd32_ps_strings *arginfo;
2717         char canary[sizeof(long) * 8];
2718         int32_t pagesizes32[MAXPAGESIZES];
2719         size_t execpath_len;
2720         int szsigcode;
2721
2722         /*
2723          * Calculate string base and vector table pointers.
2724          * Also deal with signal trampoline code for this exec type.
2725          */
2726         if (imgp->execpath != NULL && imgp->auxargs != NULL)
2727                 execpath_len = strlen(imgp->execpath) + 1;
2728         else
2729                 execpath_len = 0;
2730         arginfo = (struct freebsd32_ps_strings *)curproc->p_sysent->
2731             sv_psstrings;
2732         if (imgp->proc->p_sysent->sv_sigcode_base == 0)
2733                 szsigcode = *(imgp->proc->p_sysent->sv_szsigcode);
2734         else
2735                 szsigcode = 0;
2736         destp = (caddr_t)arginfo - szsigcode - SPARE_USRSPACE -
2737             roundup(execpath_len, sizeof(char *)) -
2738             roundup(sizeof(canary), sizeof(char *)) -
2739             roundup(sizeof(pagesizes32), sizeof(char *)) -
2740             roundup((ARG_MAX - imgp->args->stringspace), sizeof(char *));
2741
2742         /*
2743          * install sigcode
2744          */
2745         if (szsigcode != 0)
2746                 copyout(imgp->proc->p_sysent->sv_sigcode,
2747                         ((caddr_t)arginfo - szsigcode), szsigcode);
2748
2749         /*
2750          * Copy the image path for the rtld.
2751          */
2752         if (execpath_len != 0) {
2753                 imgp->execpathp = (uintptr_t)arginfo - szsigcode - execpath_len;
2754                 copyout(imgp->execpath, (void *)imgp->execpathp,
2755                     execpath_len);
2756         }
2757
2758         /*
2759          * Prepare the canary for SSP.
2760          */
2761         arc4rand(canary, sizeof(canary), 0);
2762         imgp->canary = (uintptr_t)arginfo - szsigcode - execpath_len -
2763             sizeof(canary);
2764         copyout(canary, (void *)imgp->canary, sizeof(canary));
2765         imgp->canarylen = sizeof(canary);
2766
2767         /*
2768          * Prepare the pagesizes array.
2769          */
2770         for (i = 0; i < MAXPAGESIZES; i++)
2771                 pagesizes32[i] = (uint32_t)pagesizes[i];
2772         imgp->pagesizes = (uintptr_t)arginfo - szsigcode - execpath_len -
2773             roundup(sizeof(canary), sizeof(char *)) - sizeof(pagesizes32);
2774         copyout(pagesizes32, (void *)imgp->pagesizes, sizeof(pagesizes32));
2775         imgp->pagesizeslen = sizeof(pagesizes32);
2776
2777         /*
2778          * If we have a valid auxargs ptr, prepare some room
2779          * on the stack.
2780          */
2781         if (imgp->auxargs) {
2782                 /*
2783                  * 'AT_COUNT*2' is size for the ELF Auxargs data. This is for
2784                  * lower compatibility.
2785                  */
2786                 imgp->auxarg_size = (imgp->auxarg_size) ? imgp->auxarg_size
2787                         : (AT_COUNT * 2);
2788                 /*
2789                  * The '+ 2' is for the null pointers at the end of each of
2790                  * the arg and env vector sets,and imgp->auxarg_size is room
2791                  * for argument of Runtime loader.
2792                  */
2793                 vectp = (u_int32_t *) (destp - (imgp->args->argc +
2794                     imgp->args->envc + 2 + imgp->auxarg_size + execpath_len) *
2795                     sizeof(u_int32_t));
2796         } else
2797                 /*
2798                  * The '+ 2' is for the null pointers at the end of each of
2799                  * the arg and env vector sets
2800                  */
2801                 vectp = (u_int32_t *)
2802                         (destp - (imgp->args->argc + imgp->args->envc + 2) * sizeof(u_int32_t));
2803
2804         /*
2805          * vectp also becomes our initial stack base
2806          */
2807         stack_base = vectp;
2808
2809         stringp = imgp->args->begin_argv;
2810         argc = imgp->args->argc;
2811         envc = imgp->args->envc;
2812         /*
2813          * Copy out strings - arguments and environment.
2814          */
2815         copyout(stringp, destp, ARG_MAX - imgp->args->stringspace);
2816
2817         /*
2818          * Fill in "ps_strings" struct for ps, w, etc.
2819          */
2820         suword32(&arginfo->ps_argvstr, (u_int32_t)(intptr_t)vectp);
2821         suword32(&arginfo->ps_nargvstr, argc);
2822
2823         /*
2824          * Fill in argument portion of vector table.
2825          */
2826         for (; argc > 0; --argc) {
2827                 suword32(vectp++, (u_int32_t)(intptr_t)destp);
2828                 while (*stringp++ != 0)
2829                         destp++;
2830                 destp++;
2831         }
2832
2833         /* a null vector table pointer separates the argp's from the envp's */
2834         suword32(vectp++, 0);
2835
2836         suword32(&arginfo->ps_envstr, (u_int32_t)(intptr_t)vectp);
2837         suword32(&arginfo->ps_nenvstr, envc);
2838
2839         /*
2840          * Fill in environment portion of vector table.
2841          */
2842         for (; envc > 0; --envc) {
2843                 suword32(vectp++, (u_int32_t)(intptr_t)destp);
2844                 while (*stringp++ != 0)
2845                         destp++;
2846                 destp++;
2847         }
2848
2849         /* end of vector table is a null pointer */
2850         suword32(vectp, 0);
2851
2852         return ((register_t *)stack_base);
2853 }
2854
2855 int
2856 freebsd32_kldstat(struct thread *td, struct freebsd32_kldstat_args *uap)
2857 {
2858         struct kld_file_stat stat;
2859         struct kld32_file_stat stat32;
2860         int error, version;
2861
2862         if ((error = copyin(&uap->stat->version, &version, sizeof(version)))
2863             != 0)
2864                 return (error);
2865         if (version != sizeof(struct kld32_file_stat_1) &&
2866             version != sizeof(struct kld32_file_stat))
2867                 return (EINVAL);
2868
2869         error = kern_kldstat(td, uap->fileid, &stat);
2870         if (error != 0)
2871                 return (error);
2872
2873         bcopy(&stat.name[0], &stat32.name[0], sizeof(stat.name));
2874         CP(stat, stat32, refs);
2875         CP(stat, stat32, id);
2876         PTROUT_CP(stat, stat32, address);
2877         CP(stat, stat32, size);
2878         bcopy(&stat.pathname[0], &stat32.pathname[0], sizeof(stat.pathname));
2879         return (copyout(&stat32, uap->stat, version));
2880 }
2881
2882 int
2883 freebsd32_posix_fallocate(struct thread *td,
2884     struct freebsd32_posix_fallocate_args *uap)
2885 {
2886
2887         return (kern_posix_fallocate(td, uap->fd,
2888             PAIR32TO64(off_t, uap->offset), PAIR32TO64(off_t, uap->len)));
2889 }
2890
2891 int
2892 freebsd32_posix_fadvise(struct thread *td,
2893     struct freebsd32_posix_fadvise_args *uap)
2894 {
2895
2896         return (kern_posix_fadvise(td, uap->fd, PAIR32TO64(off_t, uap->offset),
2897             PAIR32TO64(off_t, uap->len), uap->advice));
2898 }