freebsd32_misc.c revision 197049
1100384Speter/*- 2100384Speter * Copyright (c) 2002 Doug Rabson 3100384Speter * All rights reserved. 4100384Speter * 5100384Speter * Redistribution and use in source and binary forms, with or without 6100384Speter * modification, are permitted provided that the following conditions 7100384Speter * are met: 8100384Speter * 1. Redistributions of source code must retain the above copyright 9100384Speter * notice, this list of conditions and the following disclaimer. 10100384Speter * 2. Redistributions in binary form must reproduce the above copyright 11100384Speter * notice, this list of conditions and the following disclaimer in the 12100384Speter * documentation and/or other materials provided with the distribution. 13100384Speter * 14100384Speter * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15100384Speter * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16100384Speter * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17100384Speter * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18100384Speter * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19100384Speter * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20100384Speter * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21100384Speter * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22100384Speter * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23100384Speter * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24100384Speter * SUCH DAMAGE. 25100384Speter */ 26100384Speter 27118031Sobrien#include <sys/cdefs.h> 28118031Sobrien__FBSDID("$FreeBSD: head/sys/compat/freebsd32/freebsd32_misc.c 197049 2009-09-09 20:59:01Z kib $"); 29118031Sobrien 30104738Speter#include "opt_compat.h" 31191673Sjamie#include "opt_inet.h" 32191673Sjamie#include "opt_inet6.h" 33104738Speter 34100384Speter#include <sys/param.h> 35100384Speter#include <sys/bus.h> 36162954Sphk#include <sys/clock.h> 37100384Speter#include <sys/exec.h> 38100384Speter#include <sys/fcntl.h> 39100384Speter#include <sys/filedesc.h> 40100384Speter#include <sys/imgact.h> 41185435Sbz#include <sys/jail.h> 42100384Speter#include <sys/kernel.h> 43161343Sjkim#include <sys/limits.h> 44100384Speter#include <sys/lock.h> 45100384Speter#include <sys/malloc.h> 46100384Speter#include <sys/file.h> /* Must come after sys/malloc.h */ 47151909Sps#include <sys/mbuf.h> 48100384Speter#include <sys/mman.h> 49100384Speter#include <sys/module.h> 50100384Speter#include <sys/mount.h> 51100384Speter#include <sys/mutex.h> 52183044Sobrien#include <sys/namei.h> 53100384Speter#include <sys/proc.h> 54100384Speter#include <sys/reboot.h> 55100384Speter#include <sys/resource.h> 56100384Speter#include <sys/resourcevar.h> 57100384Speter#include <sys/selinfo.h> 58146950Sps#include <sys/eventvar.h> /* Must come after sys/selinfo.h */ 59100384Speter#include <sys/pipe.h> /* Must come after sys/selinfo.h */ 60100384Speter#include <sys/signal.h> 61100384Speter#include <sys/signalvar.h> 62100384Speter#include <sys/socket.h> 63100384Speter#include <sys/socketvar.h> 64100384Speter#include <sys/stat.h> 65150883Sjhb#include <sys/syscall.h> 66113859Sjhb#include <sys/syscallsubr.h> 67100384Speter#include <sys/sysctl.h> 68100384Speter#include <sys/sysent.h> 69100384Speter#include <sys/sysproto.h> 70183044Sobrien#include <sys/systm.h> 71162551Sdavidxu#include <sys/thr.h> 72100384Speter#include <sys/unistd.h> 73162551Sdavidxu#include <sys/ucontext.h> 74100384Speter#include <sys/vnode.h> 75127140Sjhb#include <sys/wait.h> 76157285Sps#include <sys/ipc.h> 77174381Sjhb#include <sys/msg.h> 78174381Sjhb#include <sys/sem.h> 79157285Sps#include <sys/shm.h> 80100384Speter 81191673Sjamie#ifdef INET 82191673Sjamie#include <netinet/in.h> 83191673Sjamie#endif 84191673Sjamie 85100384Speter#include <vm/vm.h> 86100384Speter#include <vm/vm_kern.h> 87100384Speter#include <vm/vm_param.h> 88100384Speter#include <vm/pmap.h> 89100384Speter#include <vm/vm_map.h> 90100384Speter#include <vm/vm_object.h> 91100384Speter#include <vm/vm_extern.h> 92100384Speter 93151582Sps#include <machine/cpu.h> 94151582Sps 95183188Sobrien#include <security/audit/audit.h> 96183188Sobrien 97119333Speter#include <compat/freebsd32/freebsd32_util.h> 98119333Speter#include <compat/freebsd32/freebsd32.h> 99174380Sjhb#include <compat/freebsd32/freebsd32_ipc.h> 100163018Sdavidxu#include <compat/freebsd32/freebsd32_signal.h> 101119333Speter#include <compat/freebsd32/freebsd32_proto.h> 102100384Speter 103121719SpeterCTASSERT(sizeof(struct timeval32) == 8); 104121719SpeterCTASSERT(sizeof(struct timespec32) == 8); 105174377SjhbCTASSERT(sizeof(struct itimerval32) == 16); 106121719SpeterCTASSERT(sizeof(struct statfs32) == 256); 107121719SpeterCTASSERT(sizeof(struct rusage32) == 72); 108174377SjhbCTASSERT(sizeof(struct sigaltstack32) == 12); 109174377SjhbCTASSERT(sizeof(struct kevent32) == 20); 110174377SjhbCTASSERT(sizeof(struct iovec32) == 8); 111174377SjhbCTASSERT(sizeof(struct msghdr32) == 28); 112174377SjhbCTASSERT(sizeof(struct stat32) == 96); 113174377SjhbCTASSERT(sizeof(struct sigaction32) == 24); 114121719Speter 115174377Sjhbstatic int freebsd32_kevent_copyout(void *arg, struct kevent *kevp, int count); 116174377Sjhbstatic int freebsd32_kevent_copyin(void *arg, struct kevent *kevp, int count); 117174377Sjhb 118100384Speterint 119119333Speterfreebsd32_wait4(struct thread *td, struct freebsd32_wait4_args *uap) 120100384Speter{ 121127140Sjhb int error, status; 122127140Sjhb struct rusage32 ru32; 123136152Sjhb struct rusage ru, *rup; 124100384Speter 125136152Sjhb if (uap->rusage != NULL) 126136152Sjhb rup = &ru; 127136152Sjhb else 128136152Sjhb rup = NULL; 129136152Sjhb error = kern_wait(td, uap->pid, &status, uap->options, rup); 130100384Speter if (error) 131100384Speter return (error); 132127140Sjhb if (uap->status != NULL) 133127140Sjhb error = copyout(&status, uap->status, sizeof(status)); 134127140Sjhb if (uap->rusage != NULL && error == 0) { 135100384Speter TV_CP(ru, ru32, ru_utime); 136100384Speter TV_CP(ru, ru32, ru_stime); 137100384Speter CP(ru, ru32, ru_maxrss); 138100384Speter CP(ru, ru32, ru_ixrss); 139100384Speter CP(ru, ru32, ru_idrss); 140100384Speter CP(ru, ru32, ru_isrss); 141100384Speter CP(ru, ru32, ru_minflt); 142100384Speter CP(ru, ru32, ru_majflt); 143100384Speter CP(ru, ru32, ru_nswap); 144100384Speter CP(ru, ru32, ru_inblock); 145100384Speter CP(ru, ru32, ru_oublock); 146100384Speter CP(ru, ru32, ru_msgsnd); 147100384Speter CP(ru, ru32, ru_msgrcv); 148100384Speter CP(ru, ru32, ru_nsignals); 149100384Speter CP(ru, ru32, ru_nvcsw); 150100384Speter CP(ru, ru32, ru_nivcsw); 151127140Sjhb error = copyout(&ru32, uap->rusage, sizeof(ru32)); 152100384Speter } 153100384Speter return (error); 154100384Speter} 155100384Speter 156128597Smarcel#ifdef COMPAT_FREEBSD4 157174526Sjhbstatic void 158100384Spetercopy_statfs(struct statfs *in, struct statfs32 *out) 159100384Speter{ 160172003Sjhb 161174424Sscottl statfs_scale_blocks(in, INT32_MAX); 162156266Sps bzero(out, sizeof(*out)); 163100384Speter CP(*in, *out, f_bsize); 164172003Sjhb out->f_iosize = MIN(in->f_iosize, INT32_MAX); 165100384Speter CP(*in, *out, f_blocks); 166100384Speter CP(*in, *out, f_bfree); 167100384Speter CP(*in, *out, f_bavail); 168172003Sjhb out->f_files = MIN(in->f_files, INT32_MAX); 169174526Sjhb out->f_ffree = MIN(in->f_ffree, INT32_MAX); 170100384Speter CP(*in, *out, f_fsid); 171100384Speter CP(*in, *out, f_owner); 172100384Speter CP(*in, *out, f_type); 173100384Speter CP(*in, *out, f_flags); 174174526Sjhb out->f_syncwrites = MIN(in->f_syncwrites, INT32_MAX); 175174526Sjhb out->f_asyncwrites = MIN(in->f_asyncwrites, INT32_MAX); 176156266Sps strlcpy(out->f_fstypename, 177156266Sps in->f_fstypename, MFSNAMELEN); 178156266Sps strlcpy(out->f_mntonname, 179156266Sps in->f_mntonname, min(MNAMELEN, FREEBSD4_MNAMELEN)); 180174526Sjhb out->f_syncreads = MIN(in->f_syncreads, INT32_MAX); 181174526Sjhb out->f_asyncreads = MIN(in->f_asyncreads, INT32_MAX); 182156266Sps strlcpy(out->f_mntfromname, 183156266Sps in->f_mntfromname, min(MNAMELEN, FREEBSD4_MNAMELEN)); 184100384Speter} 185128597Smarcel#endif 186100384Speter 187128597Smarcel#ifdef COMPAT_FREEBSD4 188100384Speterint 189128260Speterfreebsd4_freebsd32_getfsstat(struct thread *td, struct freebsd4_freebsd32_getfsstat_args *uap) 190100384Speter{ 191147178Spjd struct statfs *buf, *sp; 192147178Spjd struct statfs32 stat32; 193147178Spjd size_t count, size; 194100384Speter int error; 195100384Speter 196147178Spjd count = uap->bufsize / sizeof(struct statfs32); 197147178Spjd size = count * sizeof(struct statfs); 198147302Spjd error = kern_getfsstat(td, &buf, size, UIO_SYSSPACE, uap->flags); 199147302Spjd if (size > 0) { 200100384Speter count = td->td_retval[0]; 201147178Spjd sp = buf; 202147178Spjd while (count > 0 && error == 0) { 203174526Sjhb copy_statfs(sp, &stat32); 204147178Spjd error = copyout(&stat32, uap->buf, sizeof(stat32)); 205147178Spjd sp++; 206147178Spjd uap->buf++; 207147178Spjd count--; 208100384Speter } 209147178Spjd free(buf, M_TEMP); 210100384Speter } 211100384Speter return (error); 212100384Speter} 213128597Smarcel#endif 214100384Speter 215100384Speterint 216119333Speterfreebsd32_sigaltstack(struct thread *td, 217119333Speter struct freebsd32_sigaltstack_args *uap) 218100384Speter{ 219113859Sjhb struct sigaltstack32 s32; 220113859Sjhb struct sigaltstack ss, oss, *ssp; 221100384Speter int error; 222100384Speter 223113859Sjhb if (uap->ss != NULL) { 224113859Sjhb error = copyin(uap->ss, &s32, sizeof(s32)); 225100384Speter if (error) 226100384Speter return (error); 227113859Sjhb PTRIN_CP(s32, ss, ss_sp); 228113859Sjhb CP(s32, ss, ss_size); 229113859Sjhb CP(s32, ss, ss_flags); 230113859Sjhb ssp = &ss; 231113859Sjhb } else 232113859Sjhb ssp = NULL; 233113859Sjhb error = kern_sigaltstack(td, ssp, &oss); 234113859Sjhb if (error == 0 && uap->oss != NULL) { 235113859Sjhb PTROUT_CP(oss, s32, ss_sp); 236113859Sjhb CP(oss, s32, ss_size); 237113859Sjhb CP(oss, s32, ss_flags); 238113859Sjhb error = copyout(&s32, uap->oss, sizeof(s32)); 239100384Speter } 240100384Speter return (error); 241100384Speter} 242100384Speter 243142059Sjhb/* 244142059Sjhb * Custom version of exec_copyin_args() so that we can translate 245142059Sjhb * the pointers. 246142059Sjhb */ 247142059Sjhbstatic int 248142059Sjhbfreebsd32_exec_copyin_args(struct image_args *args, char *fname, 249142059Sjhb enum uio_seg segflg, u_int32_t *argv, u_int32_t *envv) 250100384Speter{ 251142059Sjhb char *argp, *envp; 252142059Sjhb u_int32_t *p32, arg; 253142059Sjhb size_t length; 254100384Speter int error; 255100384Speter 256142059Sjhb bzero(args, sizeof(*args)); 257142059Sjhb if (argv == NULL) 258142059Sjhb return (EFAULT); 259100384Speter 260142059Sjhb /* 261142059Sjhb * Allocate temporary demand zeroed space for argument and 262142059Sjhb * environment strings 263142059Sjhb */ 264147588Sjhb args->buf = (char *) kmem_alloc_wait(exec_map, 265147588Sjhb PATH_MAX + ARG_MAX + MAXSHELLCMDLEN); 266142059Sjhb if (args->buf == NULL) 267142059Sjhb return (ENOMEM); 268142059Sjhb args->begin_argv = args->buf; 269142059Sjhb args->endp = args->begin_argv; 270142059Sjhb args->stringspace = ARG_MAX; 271142059Sjhb 272142059Sjhb /* 273142059Sjhb * Copy the file name. 274142059Sjhb */ 275177789Skib if (fname != NULL) { 276177789Skib args->fname = args->buf + ARG_MAX; 277177789Skib error = (segflg == UIO_SYSSPACE) ? 278177789Skib copystr(fname, args->fname, PATH_MAX, &length) : 279177789Skib copyinstr(fname, args->fname, PATH_MAX, &length); 280177789Skib if (error != 0) 281177789Skib goto err_exit; 282177789Skib } else 283177789Skib args->fname = NULL; 284142059Sjhb 285142059Sjhb /* 286142059Sjhb * extract arguments first 287142059Sjhb */ 288142059Sjhb p32 = argv; 289142059Sjhb for (;;) { 290142059Sjhb error = copyin(p32++, &arg, sizeof(arg)); 291142059Sjhb if (error) 292156440Sups goto err_exit; 293142059Sjhb if (arg == 0) 294142059Sjhb break; 295142059Sjhb argp = PTRIN(arg); 296142059Sjhb error = copyinstr(argp, args->endp, args->stringspace, &length); 297142059Sjhb if (error) { 298142059Sjhb if (error == ENAMETOOLONG) 299156440Sups error = E2BIG; 300156440Sups goto err_exit; 301142059Sjhb } 302142059Sjhb args->stringspace -= length; 303142059Sjhb args->endp += length; 304142059Sjhb args->argc++; 305100384Speter } 306142059Sjhb 307142059Sjhb args->begin_envv = args->endp; 308142059Sjhb 309142059Sjhb /* 310142059Sjhb * extract environment strings 311142059Sjhb */ 312142059Sjhb if (envv) { 313142059Sjhb p32 = envv; 314142059Sjhb for (;;) { 315100384Speter error = copyin(p32++, &arg, sizeof(arg)); 316100384Speter if (error) 317156440Sups goto err_exit; 318142059Sjhb if (arg == 0) 319142059Sjhb break; 320142059Sjhb envp = PTRIN(arg); 321142059Sjhb error = copyinstr(envp, args->endp, args->stringspace, 322142059Sjhb &length); 323142059Sjhb if (error) { 324142059Sjhb if (error == ENAMETOOLONG) 325156440Sups error = E2BIG; 326156440Sups goto err_exit; 327142059Sjhb } 328142059Sjhb args->stringspace -= length; 329142059Sjhb args->endp += length; 330142059Sjhb args->envc++; 331142059Sjhb } 332100384Speter } 333100384Speter 334142059Sjhb return (0); 335156440Sups 336156440Supserr_exit: 337156440Sups kmem_free_wakeup(exec_map, (vm_offset_t)args->buf, 338156440Sups PATH_MAX + ARG_MAX + MAXSHELLCMDLEN); 339156440Sups args->buf = NULL; 340156440Sups return (error); 341100384Speter} 342100384Speter 343142059Sjhbint 344142059Sjhbfreebsd32_execve(struct thread *td, struct freebsd32_execve_args *uap) 345142059Sjhb{ 346142059Sjhb struct image_args eargs; 347142059Sjhb int error; 348142059Sjhb 349142059Sjhb error = freebsd32_exec_copyin_args(&eargs, uap->fname, UIO_USERSPACE, 350142059Sjhb uap->argv, uap->envv); 351142059Sjhb if (error == 0) 352142059Sjhb error = kern_execve(td, &eargs, NULL); 353142059Sjhb return (error); 354142059Sjhb} 355142059Sjhb 356177789Skibint 357177789Skibfreebsd32_fexecve(struct thread *td, struct freebsd32_fexecve_args *uap) 358177789Skib{ 359177789Skib struct image_args eargs; 360177789Skib int error; 361177789Skib 362177789Skib error = freebsd32_exec_copyin_args(&eargs, NULL, UIO_SYSSPACE, 363177789Skib uap->argv, uap->envv); 364177789Skib if (error == 0) { 365177789Skib eargs.fd = uap->fd; 366177789Skib error = kern_execve(td, &eargs, NULL); 367177789Skib } 368177789Skib return (error); 369177789Skib} 370177789Skib 371114987Speter#ifdef __ia64__ 372100384Speterstatic int 373119333Speterfreebsd32_mmap_partial(struct thread *td, vm_offset_t start, vm_offset_t end, 374119333Speter int prot, int fd, off_t pos) 375100384Speter{ 376100384Speter vm_map_t map; 377100384Speter vm_map_entry_t entry; 378100384Speter int rv; 379100384Speter 380100384Speter map = &td->td_proc->p_vmspace->vm_map; 381100384Speter if (fd != -1) 382100384Speter prot |= VM_PROT_WRITE; 383100384Speter 384100384Speter if (vm_map_lookup_entry(map, start, &entry)) { 385100384Speter if ((entry->protection & prot) != prot) { 386100384Speter rv = vm_map_protect(map, 387100384Speter trunc_page(start), 388100384Speter round_page(end), 389100384Speter entry->protection | prot, 390100384Speter FALSE); 391100384Speter if (rv != KERN_SUCCESS) 392100384Speter return (EINVAL); 393100384Speter } 394100384Speter } else { 395100384Speter vm_offset_t addr = trunc_page(start); 396100384Speter rv = vm_map_find(map, 0, 0, 397100384Speter &addr, PAGE_SIZE, FALSE, prot, 398100384Speter VM_PROT_ALL, 0); 399100384Speter if (rv != KERN_SUCCESS) 400100384Speter return (EINVAL); 401100384Speter } 402100384Speter 403100384Speter if (fd != -1) { 404100384Speter struct pread_args r; 405107849Salfred r.fd = fd; 406107849Salfred r.buf = (void *) start; 407107849Salfred r.nbyte = end - start; 408107849Salfred r.offset = pos; 409100384Speter return (pread(td, &r)); 410100384Speter } else { 411100384Speter while (start < end) { 412100384Speter subyte((void *) start, 0); 413100384Speter start++; 414100384Speter } 415100384Speter return (0); 416100384Speter } 417100384Speter} 418114987Speter#endif 419100384Speter 420100384Speterint 421119333Speterfreebsd32_mmap(struct thread *td, struct freebsd32_mmap_args *uap) 422100384Speter{ 423100384Speter struct mmap_args ap; 424107849Salfred vm_offset_t addr = (vm_offset_t) uap->addr; 425107849Salfred vm_size_t len = uap->len; 426107849Salfred int prot = uap->prot; 427107849Salfred int flags = uap->flags; 428107849Salfred int fd = uap->fd; 429107849Salfred off_t pos = (uap->poslo 430107849Salfred | ((off_t)uap->poshi << 32)); 431114987Speter#ifdef __ia64__ 432100384Speter vm_size_t pageoff; 433100384Speter int error; 434100384Speter 435100384Speter /* 436100384Speter * Attempt to handle page size hassles. 437100384Speter */ 438100384Speter pageoff = (pos & PAGE_MASK); 439100384Speter if (flags & MAP_FIXED) { 440100384Speter vm_offset_t start, end; 441100384Speter start = addr; 442100384Speter end = addr + len; 443100384Speter 444100384Speter if (start != trunc_page(start)) { 445119333Speter error = freebsd32_mmap_partial(td, start, 446119333Speter round_page(start), prot, 447119333Speter fd, pos); 448100384Speter if (fd != -1) 449100384Speter pos += round_page(start) - start; 450100384Speter start = round_page(start); 451100384Speter } 452100384Speter if (end != round_page(end)) { 453100384Speter vm_offset_t t = trunc_page(end); 454119333Speter error = freebsd32_mmap_partial(td, t, end, 455100384Speter prot, fd, 456100384Speter pos + t - start); 457100384Speter end = trunc_page(end); 458100384Speter } 459100384Speter if (end > start && fd != -1 && (pos & PAGE_MASK)) { 460100384Speter /* 461100384Speter * We can't map this region at all. The specified 462100384Speter * address doesn't have the same alignment as the file 463100384Speter * position. Fake the mapping by simply reading the 464100384Speter * entire region into memory. First we need to make 465100384Speter * sure the region exists. 466100384Speter */ 467100384Speter vm_map_t map; 468100384Speter struct pread_args r; 469100384Speter int rv; 470100384Speter 471100384Speter prot |= VM_PROT_WRITE; 472100384Speter map = &td->td_proc->p_vmspace->vm_map; 473100384Speter rv = vm_map_remove(map, start, end); 474169181Salc if (rv != KERN_SUCCESS) 475100384Speter return (EINVAL); 476100384Speter rv = vm_map_find(map, 0, 0, 477100384Speter &start, end - start, FALSE, 478100384Speter prot, VM_PROT_ALL, 0); 479100384Speter if (rv != KERN_SUCCESS) 480100384Speter return (EINVAL); 481107849Salfred r.fd = fd; 482107849Salfred r.buf = (void *) start; 483107849Salfred r.nbyte = end - start; 484107849Salfred r.offset = pos; 485100384Speter error = pread(td, &r); 486100384Speter if (error) 487100384Speter return (error); 488100384Speter 489100384Speter td->td_retval[0] = addr; 490100384Speter return (0); 491100384Speter } 492100384Speter if (end == start) { 493100384Speter /* 494100384Speter * After dealing with the ragged ends, there 495100384Speter * might be none left. 496100384Speter */ 497100384Speter td->td_retval[0] = addr; 498100384Speter return (0); 499100384Speter } 500100384Speter addr = start; 501100384Speter len = end - start; 502100384Speter } 503114987Speter#endif 504100384Speter 505107849Salfred ap.addr = (void *) addr; 506107849Salfred ap.len = len; 507107849Salfred ap.prot = prot; 508107849Salfred ap.flags = flags; 509107849Salfred ap.fd = fd; 510107849Salfred ap.pos = pos; 511100384Speter 512100384Speter return (mmap(td, &ap)); 513100384Speter} 514100384Speter 515171215Speter#ifdef COMPAT_FREEBSD6 516171215Speterint 517171215Speterfreebsd6_freebsd32_mmap(struct thread *td, struct freebsd6_freebsd32_mmap_args *uap) 518171215Speter{ 519171215Speter struct freebsd32_mmap_args ap; 520171215Speter 521171215Speter ap.addr = uap->addr; 522171215Speter ap.len = uap->len; 523171215Speter ap.prot = uap->prot; 524171215Speter ap.flags = uap->flags; 525171215Speter ap.fd = uap->fd; 526171215Speter ap.poslo = uap->poslo; 527171215Speter ap.poshi = uap->poshi; 528171215Speter 529171215Speter return (freebsd32_mmap(td, &ap)); 530171215Speter} 531171215Speter#endif 532171215Speter 533100384Speterint 534119333Speterfreebsd32_setitimer(struct thread *td, struct freebsd32_setitimer_args *uap) 535100384Speter{ 536142059Sjhb struct itimerval itv, oitv, *itvp; 537142059Sjhb struct itimerval32 i32; 538100384Speter int error; 539100384Speter 540142059Sjhb if (uap->itv != NULL) { 541142059Sjhb error = copyin(uap->itv, &i32, sizeof(i32)); 542100384Speter if (error) 543100384Speter return (error); 544142059Sjhb TV_CP(i32, itv, it_interval); 545142059Sjhb TV_CP(i32, itv, it_value); 546142059Sjhb itvp = &itv; 547142059Sjhb } else 548142059Sjhb itvp = NULL; 549142059Sjhb error = kern_setitimer(td, uap->which, itvp, &oitv); 550142059Sjhb if (error || uap->oitv == NULL) 551100384Speter return (error); 552142059Sjhb TV_CP(oitv, i32, it_interval); 553142059Sjhb TV_CP(oitv, i32, it_value); 554142059Sjhb return (copyout(&i32, uap->oitv, sizeof(i32))); 555100384Speter} 556100384Speter 557100384Speterint 558125171Speterfreebsd32_getitimer(struct thread *td, struct freebsd32_getitimer_args *uap) 559125171Speter{ 560142059Sjhb struct itimerval itv; 561142059Sjhb struct itimerval32 i32; 562125171Speter int error; 563125171Speter 564142059Sjhb error = kern_getitimer(td, uap->which, &itv); 565142059Sjhb if (error || uap->itv == NULL) 566125171Speter return (error); 567142059Sjhb TV_CP(itv, i32, it_interval); 568142059Sjhb TV_CP(itv, i32, it_value); 569142059Sjhb return (copyout(&i32, uap->itv, sizeof(i32))); 570125171Speter} 571125171Speter 572125171Speterint 573119333Speterfreebsd32_select(struct thread *td, struct freebsd32_select_args *uap) 574100384Speter{ 575142059Sjhb struct timeval32 tv32; 576142059Sjhb struct timeval tv, *tvp; 577100384Speter int error; 578100384Speter 579142059Sjhb if (uap->tv != NULL) { 580142059Sjhb error = copyin(uap->tv, &tv32, sizeof(tv32)); 581100384Speter if (error) 582100384Speter return (error); 583142059Sjhb CP(tv32, tv, tv_sec); 584142059Sjhb CP(tv32, tv, tv_usec); 585142059Sjhb tvp = &tv; 586142059Sjhb } else 587142059Sjhb tvp = NULL; 588100384Speter /* 589100384Speter * XXX big-endian needs to convert the fd_sets too. 590142059Sjhb * XXX Do pointers need PTRIN()? 591100384Speter */ 592197049Skib return (kern_select(td, uap->nd, uap->in, uap->ou, uap->ex, tvp, 593197049Skib sizeof(int32_t) * 8)); 594100384Speter} 595100384Speter 596146950Sps/* 597146950Sps * Copy 'count' items into the destination list pointed to by uap->eventlist. 598146950Sps */ 599146950Spsstatic int 600146950Spsfreebsd32_kevent_copyout(void *arg, struct kevent *kevp, int count) 601146950Sps{ 602146950Sps struct freebsd32_kevent_args *uap; 603146950Sps struct kevent32 ks32[KQ_NEVENTS]; 604146950Sps int i, error = 0; 605146950Sps 606146950Sps KASSERT(count <= KQ_NEVENTS, ("count (%d) > KQ_NEVENTS", count)); 607146950Sps uap = (struct freebsd32_kevent_args *)arg; 608146950Sps 609146950Sps for (i = 0; i < count; i++) { 610146950Sps CP(kevp[i], ks32[i], ident); 611146950Sps CP(kevp[i], ks32[i], filter); 612146950Sps CP(kevp[i], ks32[i], flags); 613146950Sps CP(kevp[i], ks32[i], fflags); 614146950Sps CP(kevp[i], ks32[i], data); 615146950Sps PTROUT_CP(kevp[i], ks32[i], udata); 616146950Sps } 617146950Sps error = copyout(ks32, uap->eventlist, count * sizeof *ks32); 618146950Sps if (error == 0) 619146950Sps uap->eventlist += count; 620146950Sps return (error); 621146950Sps} 622146950Sps 623146950Sps/* 624146950Sps * Copy 'count' items from the list pointed to by uap->changelist. 625146950Sps */ 626146950Spsstatic int 627146950Spsfreebsd32_kevent_copyin(void *arg, struct kevent *kevp, int count) 628146950Sps{ 629146950Sps struct freebsd32_kevent_args *uap; 630146950Sps struct kevent32 ks32[KQ_NEVENTS]; 631146950Sps int i, error = 0; 632146950Sps 633146950Sps KASSERT(count <= KQ_NEVENTS, ("count (%d) > KQ_NEVENTS", count)); 634146950Sps uap = (struct freebsd32_kevent_args *)arg; 635146950Sps 636146950Sps error = copyin(uap->changelist, ks32, count * sizeof *ks32); 637146950Sps if (error) 638146950Sps goto done; 639146950Sps uap->changelist += count; 640146950Sps 641146950Sps for (i = 0; i < count; i++) { 642146950Sps CP(ks32[i], kevp[i], ident); 643146950Sps CP(ks32[i], kevp[i], filter); 644146950Sps CP(ks32[i], kevp[i], flags); 645146950Sps CP(ks32[i], kevp[i], fflags); 646146950Sps CP(ks32[i], kevp[i], data); 647146950Sps PTRIN_CP(ks32[i], kevp[i], udata); 648146950Sps } 649146950Spsdone: 650146950Sps return (error); 651146950Sps} 652146950Sps 653100384Speterint 654119333Speterfreebsd32_kevent(struct thread *td, struct freebsd32_kevent_args *uap) 655114987Speter{ 656114987Speter struct timespec32 ts32; 657142934Sps struct timespec ts, *tsp; 658146950Sps struct kevent_copyops k_ops = { uap, 659146950Sps freebsd32_kevent_copyout, 660146950Sps freebsd32_kevent_copyin}; 661146950Sps int error; 662114987Speter 663114987Speter 664114987Speter if (uap->timeout) { 665114987Speter error = copyin(uap->timeout, &ts32, sizeof(ts32)); 666114987Speter if (error) 667114987Speter return (error); 668114987Speter CP(ts32, ts, tv_sec); 669114987Speter CP(ts32, ts, tv_nsec); 670142934Sps tsp = &ts; 671142934Sps } else 672142934Sps tsp = NULL; 673146950Sps error = kern_kevent(td, uap->fd, uap->nchanges, uap->nevents, 674146950Sps &k_ops, tsp); 675142934Sps return (error); 676114987Speter} 677114987Speter 678114987Speterint 679119333Speterfreebsd32_gettimeofday(struct thread *td, 680119333Speter struct freebsd32_gettimeofday_args *uap) 681100384Speter{ 682123425Speter struct timeval atv; 683123425Speter struct timeval32 atv32; 684123425Speter struct timezone rtz; 685123425Speter int error = 0; 686100384Speter 687123425Speter if (uap->tp) { 688123425Speter microtime(&atv); 689123425Speter CP(atv, atv32, tv_sec); 690123425Speter CP(atv, atv32, tv_usec); 691123425Speter error = copyout(&atv32, uap->tp, sizeof (atv32)); 692100384Speter } 693123425Speter if (error == 0 && uap->tzp != NULL) { 694123425Speter rtz.tz_minuteswest = tz_minuteswest; 695123425Speter rtz.tz_dsttime = tz_dsttime; 696123425Speter error = copyout(&rtz, uap->tzp, sizeof (rtz)); 697100384Speter } 698100384Speter return (error); 699100384Speter} 700100384Speter 701100384Speterint 702119333Speterfreebsd32_getrusage(struct thread *td, struct freebsd32_getrusage_args *uap) 703100384Speter{ 704136152Sjhb struct rusage32 s32; 705136152Sjhb struct rusage s; 706100384Speter int error; 707100384Speter 708136152Sjhb error = kern_getrusage(td, uap->who, &s); 709100384Speter if (error) 710100384Speter return (error); 711136152Sjhb if (uap->rusage != NULL) { 712100384Speter TV_CP(s, s32, ru_utime); 713100384Speter TV_CP(s, s32, ru_stime); 714100384Speter CP(s, s32, ru_maxrss); 715100384Speter CP(s, s32, ru_ixrss); 716100384Speter CP(s, s32, ru_idrss); 717100384Speter CP(s, s32, ru_isrss); 718100384Speter CP(s, s32, ru_minflt); 719100384Speter CP(s, s32, ru_majflt); 720100384Speter CP(s, s32, ru_nswap); 721100384Speter CP(s, s32, ru_inblock); 722100384Speter CP(s, s32, ru_oublock); 723100384Speter CP(s, s32, ru_msgsnd); 724100384Speter CP(s, s32, ru_msgrcv); 725100384Speter CP(s, s32, ru_nsignals); 726100384Speter CP(s, s32, ru_nvcsw); 727100384Speter CP(s, s32, ru_nivcsw); 728136152Sjhb error = copyout(&s32, uap->rusage, sizeof(s32)); 729100384Speter } 730100384Speter return (error); 731100384Speter} 732100384Speter 733144450Sjhbstatic int 734144450Sjhbfreebsd32_copyinuio(struct iovec32 *iovp, u_int iovcnt, struct uio **uiop) 735100384Speter{ 736144450Sjhb struct iovec32 iov32; 737144450Sjhb struct iovec *iov; 738144450Sjhb struct uio *uio; 739144450Sjhb u_int iovlen; 740144450Sjhb int error, i; 741100384Speter 742144450Sjhb *uiop = NULL; 743144450Sjhb if (iovcnt > UIO_MAXIOV) 744100384Speter return (EINVAL); 745144450Sjhb iovlen = iovcnt * sizeof(struct iovec); 746144450Sjhb uio = malloc(iovlen + sizeof *uio, M_IOV, M_WAITOK); 747144450Sjhb iov = (struct iovec *)(uio + 1); 748144450Sjhb for (i = 0; i < iovcnt; i++) { 749144450Sjhb error = copyin(&iovp[i], &iov32, sizeof(struct iovec32)); 750144450Sjhb if (error) { 751144450Sjhb free(uio, M_IOV); 752144450Sjhb return (error); 753144450Sjhb } 754144450Sjhb iov[i].iov_base = PTRIN(iov32.iov_base); 755144450Sjhb iov[i].iov_len = iov32.iov_len; 756100384Speter } 757144450Sjhb uio->uio_iov = iov; 758144450Sjhb uio->uio_iovcnt = iovcnt; 759144450Sjhb uio->uio_segflg = UIO_USERSPACE; 760144450Sjhb uio->uio_offset = -1; 761144450Sjhb uio->uio_resid = 0; 762144450Sjhb for (i = 0; i < iovcnt; i++) { 763144450Sjhb if (iov->iov_len > INT_MAX - uio->uio_resid) { 764144450Sjhb free(uio, M_IOV); 765144450Sjhb return (EINVAL); 766144450Sjhb } 767144450Sjhb uio->uio_resid += iov->iov_len; 768144450Sjhb iov++; 769144450Sjhb } 770144450Sjhb *uiop = uio; 771144450Sjhb return (0); 772144450Sjhb} 773100384Speter 774144450Sjhbint 775144450Sjhbfreebsd32_readv(struct thread *td, struct freebsd32_readv_args *uap) 776144450Sjhb{ 777144450Sjhb struct uio *auio; 778144450Sjhb int error; 779100384Speter 780144450Sjhb error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio); 781144450Sjhb if (error) 782144450Sjhb return (error); 783144450Sjhb error = kern_readv(td, uap->fd, auio); 784144450Sjhb free(auio, M_IOV); 785100384Speter return (error); 786100384Speter} 787100384Speter 788100384Speterint 789119333Speterfreebsd32_writev(struct thread *td, struct freebsd32_writev_args *uap) 790100384Speter{ 791144450Sjhb struct uio *auio; 792144450Sjhb int error; 793100384Speter 794144450Sjhb error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio); 795144450Sjhb if (error) 796144450Sjhb return (error); 797144450Sjhb error = kern_writev(td, uap->fd, auio); 798144450Sjhb free(auio, M_IOV); 799100384Speter return (error); 800100384Speter} 801100384Speter 802100384Speterint 803147813Sjhbfreebsd32_preadv(struct thread *td, struct freebsd32_preadv_args *uap) 804147813Sjhb{ 805147813Sjhb struct uio *auio; 806147813Sjhb int error; 807147813Sjhb 808147813Sjhb error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio); 809147813Sjhb if (error) 810147813Sjhb return (error); 811147813Sjhb error = kern_preadv(td, uap->fd, auio, uap->offset); 812147813Sjhb free(auio, M_IOV); 813147813Sjhb return (error); 814147813Sjhb} 815147813Sjhb 816147813Sjhbint 817147813Sjhbfreebsd32_pwritev(struct thread *td, struct freebsd32_pwritev_args *uap) 818147813Sjhb{ 819147813Sjhb struct uio *auio; 820147813Sjhb int error; 821147813Sjhb 822147813Sjhb error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio); 823147813Sjhb if (error) 824147813Sjhb return (error); 825147813Sjhb error = kern_pwritev(td, uap->fd, auio, uap->offset); 826147813Sjhb free(auio, M_IOV); 827147813Sjhb return (error); 828147813Sjhb} 829147813Sjhb 830151359Spsstatic int 831151909Spsfreebsd32_copyiniov(struct iovec32 *iovp32, u_int iovcnt, struct iovec **iovp, 832151359Sps int error) 833151359Sps{ 834151359Sps struct iovec32 iov32; 835151909Sps struct iovec *iov; 836151909Sps u_int iovlen; 837151359Sps int i; 838151359Sps 839151909Sps *iovp = NULL; 840151359Sps if (iovcnt > UIO_MAXIOV) 841151359Sps return (error); 842151359Sps iovlen = iovcnt * sizeof(struct iovec); 843151909Sps iov = malloc(iovlen, M_IOV, M_WAITOK); 844151359Sps for (i = 0; i < iovcnt; i++) { 845151909Sps error = copyin(&iovp32[i], &iov32, sizeof(struct iovec32)); 846151359Sps if (error) { 847151909Sps free(iov, M_IOV); 848151359Sps return (error); 849151359Sps } 850151909Sps iov[i].iov_base = PTRIN(iov32.iov_base); 851151909Sps iov[i].iov_len = iov32.iov_len; 852151359Sps } 853151909Sps *iovp = iov; 854151359Sps return (0); 855151359Sps} 856151359Sps 857151359Spsstatic int 858151359Spsfreebsd32_copyinmsghdr(struct msghdr32 *msg32, struct msghdr *msg) 859151359Sps{ 860151359Sps struct msghdr32 m32; 861151359Sps int error; 862151359Sps 863151359Sps error = copyin(msg32, &m32, sizeof(m32)); 864151359Sps if (error) 865151359Sps return (error); 866151359Sps msg->msg_name = PTRIN(m32.msg_name); 867151359Sps msg->msg_namelen = m32.msg_namelen; 868151359Sps msg->msg_iov = PTRIN(m32.msg_iov); 869151359Sps msg->msg_iovlen = m32.msg_iovlen; 870151359Sps msg->msg_control = PTRIN(m32.msg_control); 871151359Sps msg->msg_controllen = m32.msg_controllen; 872151359Sps msg->msg_flags = m32.msg_flags; 873151909Sps return (0); 874151359Sps} 875151359Sps 876151359Spsstatic int 877151359Spsfreebsd32_copyoutmsghdr(struct msghdr *msg, struct msghdr32 *msg32) 878151359Sps{ 879151359Sps struct msghdr32 m32; 880151359Sps int error; 881151359Sps 882151359Sps m32.msg_name = PTROUT(msg->msg_name); 883151359Sps m32.msg_namelen = msg->msg_namelen; 884151359Sps m32.msg_iov = PTROUT(msg->msg_iov); 885151359Sps m32.msg_iovlen = msg->msg_iovlen; 886151359Sps m32.msg_control = PTROUT(msg->msg_control); 887151359Sps m32.msg_controllen = msg->msg_controllen; 888151359Sps m32.msg_flags = msg->msg_flags; 889151359Sps error = copyout(&m32, msg32, sizeof(m32)); 890151359Sps return (error); 891151359Sps} 892151359Sps 893151909Sps#define FREEBSD32_ALIGNBYTES (sizeof(int) - 1) 894151909Sps#define FREEBSD32_ALIGN(p) \ 895151909Sps (((u_long)(p) + FREEBSD32_ALIGNBYTES) & ~FREEBSD32_ALIGNBYTES) 896151909Sps#define FREEBSD32_CMSG_SPACE(l) \ 897151909Sps (FREEBSD32_ALIGN(sizeof(struct cmsghdr)) + FREEBSD32_ALIGN(l)) 898151909Sps 899151909Sps#define FREEBSD32_CMSG_DATA(cmsg) ((unsigned char *)(cmsg) + \ 900151909Sps FREEBSD32_ALIGN(sizeof(struct cmsghdr))) 901151909Spsstatic int 902151909Spsfreebsd32_copy_msg_out(struct msghdr *msg, struct mbuf *control) 903151909Sps{ 904151909Sps struct cmsghdr *cm; 905151909Sps void *data; 906151909Sps socklen_t clen, datalen; 907151909Sps int error; 908151909Sps caddr_t ctlbuf; 909151909Sps int len, maxlen, copylen; 910151909Sps struct mbuf *m; 911151909Sps error = 0; 912151909Sps 913151909Sps len = msg->msg_controllen; 914151909Sps maxlen = msg->msg_controllen; 915151909Sps msg->msg_controllen = 0; 916151909Sps 917151909Sps m = control; 918151909Sps ctlbuf = msg->msg_control; 919151909Sps 920151909Sps while (m && len > 0) { 921151909Sps cm = mtod(m, struct cmsghdr *); 922151909Sps clen = m->m_len; 923151909Sps 924151909Sps while (cm != NULL) { 925151909Sps 926151909Sps if (sizeof(struct cmsghdr) > clen || 927151909Sps cm->cmsg_len > clen) { 928151909Sps error = EINVAL; 929151909Sps break; 930151909Sps } 931151909Sps 932151909Sps data = CMSG_DATA(cm); 933151909Sps datalen = (caddr_t)cm + cm->cmsg_len - (caddr_t)data; 934151909Sps 935151909Sps /* Adjust message length */ 936151909Sps cm->cmsg_len = FREEBSD32_ALIGN(sizeof(struct cmsghdr)) + 937151909Sps datalen; 938151909Sps 939151909Sps 940151909Sps /* Copy cmsghdr */ 941151909Sps copylen = sizeof(struct cmsghdr); 942151909Sps if (len < copylen) { 943151909Sps msg->msg_flags |= MSG_CTRUNC; 944151909Sps copylen = len; 945151909Sps } 946151909Sps 947151909Sps error = copyout(cm,ctlbuf,copylen); 948151909Sps if (error) 949151909Sps goto exit; 950151909Sps 951151909Sps ctlbuf += FREEBSD32_ALIGN(copylen); 952151909Sps len -= FREEBSD32_ALIGN(copylen); 953151909Sps 954151909Sps if (len <= 0) 955151909Sps break; 956151909Sps 957151909Sps /* Copy data */ 958151909Sps copylen = datalen; 959151909Sps if (len < copylen) { 960151909Sps msg->msg_flags |= MSG_CTRUNC; 961151909Sps copylen = len; 962151909Sps } 963151909Sps 964151909Sps error = copyout(data,ctlbuf,copylen); 965151909Sps if (error) 966151909Sps goto exit; 967151909Sps 968151909Sps ctlbuf += FREEBSD32_ALIGN(copylen); 969151909Sps len -= FREEBSD32_ALIGN(copylen); 970151909Sps 971151909Sps if (CMSG_SPACE(datalen) < clen) { 972151909Sps clen -= CMSG_SPACE(datalen); 973151909Sps cm = (struct cmsghdr *) 974151909Sps ((caddr_t)cm + CMSG_SPACE(datalen)); 975151909Sps } else { 976151909Sps clen = 0; 977151909Sps cm = NULL; 978151909Sps } 979151909Sps } 980151909Sps m = m->m_next; 981151909Sps } 982151909Sps 983151909Sps msg->msg_controllen = (len <= 0) ? maxlen : ctlbuf - (caddr_t)msg->msg_control; 984151909Sps 985151909Spsexit: 986151909Sps return (error); 987151909Sps 988151909Sps} 989151909Sps 990147813Sjhbint 991151359Spsfreebsd32_recvmsg(td, uap) 992151359Sps struct thread *td; 993151359Sps struct freebsd32_recvmsg_args /* { 994151359Sps int s; 995151359Sps struct msghdr32 *msg; 996151359Sps int flags; 997151359Sps } */ *uap; 998151359Sps{ 999151359Sps struct msghdr msg; 1000151359Sps struct msghdr32 m32; 1001151359Sps struct iovec *uiov, *iov; 1002151909Sps struct mbuf *control = NULL; 1003151909Sps struct mbuf **controlp; 1004151909Sps 1005151359Sps int error; 1006151359Sps error = copyin(uap->msg, &m32, sizeof(m32)); 1007151359Sps if (error) 1008151359Sps return (error); 1009151359Sps error = freebsd32_copyinmsghdr(uap->msg, &msg); 1010151359Sps if (error) 1011151359Sps return (error); 1012160246Sjhb error = freebsd32_copyiniov(PTRIN(m32.msg_iov), m32.msg_iovlen, &iov, 1013160246Sjhb EMSGSIZE); 1014151359Sps if (error) 1015151359Sps return (error); 1016151359Sps msg.msg_flags = uap->flags; 1017151359Sps uiov = msg.msg_iov; 1018151359Sps msg.msg_iov = iov; 1019151909Sps 1020151909Sps controlp = (msg.msg_control != NULL) ? &control : NULL; 1021160249Sjhb error = kern_recvit(td, uap->s, &msg, UIO_USERSPACE, controlp); 1022151359Sps if (error == 0) { 1023151359Sps msg.msg_iov = uiov; 1024151909Sps 1025151909Sps if (control != NULL) 1026151909Sps error = freebsd32_copy_msg_out(&msg, control); 1027151909Sps 1028151909Sps if (error == 0) 1029151909Sps error = freebsd32_copyoutmsghdr(&msg, uap->msg); 1030151359Sps } 1031151359Sps free(iov, M_IOV); 1032151909Sps 1033151909Sps if (control != NULL) 1034151909Sps m_freem(control); 1035151909Sps 1036151359Sps return (error); 1037151359Sps} 1038151359Sps 1039151909Sps 1040151909Spsstatic int 1041151909Spsfreebsd32_convert_msg_in(struct mbuf **controlp) 1042151909Sps{ 1043151909Sps struct mbuf *control = *controlp; 1044151909Sps struct cmsghdr *cm = mtod(control, struct cmsghdr *); 1045151909Sps void *data; 1046151909Sps socklen_t clen = control->m_len, datalen; 1047151909Sps int error; 1048151909Sps 1049151909Sps error = 0; 1050151909Sps *controlp = NULL; 1051151909Sps 1052151909Sps while (cm != NULL) { 1053151909Sps if (sizeof(struct cmsghdr) > clen || cm->cmsg_len > clen) { 1054151909Sps error = EINVAL; 1055151909Sps break; 1056151909Sps } 1057151909Sps 1058151909Sps data = FREEBSD32_CMSG_DATA(cm); 1059151909Sps datalen = (caddr_t)cm + cm->cmsg_len - (caddr_t)data; 1060151909Sps 1061151909Sps *controlp = sbcreatecontrol(data, datalen, cm->cmsg_type, 1062151909Sps cm->cmsg_level); 1063151909Sps controlp = &(*controlp)->m_next; 1064151909Sps 1065151909Sps if (FREEBSD32_CMSG_SPACE(datalen) < clen) { 1066151909Sps clen -= FREEBSD32_CMSG_SPACE(datalen); 1067151909Sps cm = (struct cmsghdr *) 1068151909Sps ((caddr_t)cm + FREEBSD32_CMSG_SPACE(datalen)); 1069151909Sps } else { 1070151909Sps clen = 0; 1071151909Sps cm = NULL; 1072151909Sps } 1073151909Sps } 1074151909Sps 1075151909Sps m_freem(control); 1076151909Sps return (error); 1077151909Sps} 1078151909Sps 1079151909Sps 1080151359Spsint 1081151359Spsfreebsd32_sendmsg(struct thread *td, 1082151359Sps struct freebsd32_sendmsg_args *uap) 1083151359Sps{ 1084151359Sps struct msghdr msg; 1085151359Sps struct msghdr32 m32; 1086151359Sps struct iovec *iov; 1087151909Sps struct mbuf *control = NULL; 1088151909Sps struct sockaddr *to = NULL; 1089151359Sps int error; 1090151359Sps 1091151359Sps error = copyin(uap->msg, &m32, sizeof(m32)); 1092151359Sps if (error) 1093151359Sps return (error); 1094151359Sps error = freebsd32_copyinmsghdr(uap->msg, &msg); 1095151359Sps if (error) 1096151359Sps return (error); 1097160246Sjhb error = freebsd32_copyiniov(PTRIN(m32.msg_iov), m32.msg_iovlen, &iov, 1098160246Sjhb EMSGSIZE); 1099151359Sps if (error) 1100151359Sps return (error); 1101151359Sps msg.msg_iov = iov; 1102151909Sps if (msg.msg_name != NULL) { 1103151909Sps error = getsockaddr(&to, msg.msg_name, msg.msg_namelen); 1104151909Sps if (error) { 1105151909Sps to = NULL; 1106151909Sps goto out; 1107151909Sps } 1108151909Sps msg.msg_name = to; 1109151909Sps } 1110151909Sps 1111151909Sps if (msg.msg_control) { 1112151909Sps if (msg.msg_controllen < sizeof(struct cmsghdr)) { 1113151909Sps error = EINVAL; 1114151909Sps goto out; 1115151909Sps } 1116151909Sps 1117151909Sps error = sockargs(&control, msg.msg_control, 1118151909Sps msg.msg_controllen, MT_CONTROL); 1119151909Sps if (error) 1120151909Sps goto out; 1121151909Sps 1122151909Sps error = freebsd32_convert_msg_in(&control); 1123151909Sps if (error) 1124151909Sps goto out; 1125151909Sps } 1126151909Sps 1127151909Sps error = kern_sendit(td, uap->s, &msg, uap->flags, control, 1128151909Sps UIO_USERSPACE); 1129151909Sps 1130151909Spsout: 1131151359Sps free(iov, M_IOV); 1132151909Sps if (to) 1133151909Sps free(to, M_SONAME); 1134151359Sps return (error); 1135151359Sps} 1136151359Sps 1137151359Spsint 1138151359Spsfreebsd32_recvfrom(struct thread *td, 1139151359Sps struct freebsd32_recvfrom_args *uap) 1140151359Sps{ 1141151359Sps struct msghdr msg; 1142151359Sps struct iovec aiov; 1143151359Sps int error; 1144151359Sps 1145151359Sps if (uap->fromlenaddr) { 1146160246Sjhb error = copyin(PTRIN(uap->fromlenaddr), &msg.msg_namelen, 1147160246Sjhb sizeof(msg.msg_namelen)); 1148151359Sps if (error) 1149151359Sps return (error); 1150151359Sps } else { 1151151359Sps msg.msg_namelen = 0; 1152151359Sps } 1153151359Sps 1154160246Sjhb msg.msg_name = PTRIN(uap->from); 1155151359Sps msg.msg_iov = &aiov; 1156151359Sps msg.msg_iovlen = 1; 1157160246Sjhb aiov.iov_base = PTRIN(uap->buf); 1158151359Sps aiov.iov_len = uap->len; 1159160246Sjhb msg.msg_control = NULL; 1160151359Sps msg.msg_flags = uap->flags; 1161160249Sjhb error = kern_recvit(td, uap->s, &msg, UIO_USERSPACE, NULL); 1162160249Sjhb if (error == 0 && uap->fromlenaddr) 1163160249Sjhb error = copyout(&msg.msg_namelen, PTRIN(uap->fromlenaddr), 1164160249Sjhb sizeof (msg.msg_namelen)); 1165151359Sps return (error); 1166151359Sps} 1167151359Sps 1168151359Spsint 1169119333Speterfreebsd32_settimeofday(struct thread *td, 1170119333Speter struct freebsd32_settimeofday_args *uap) 1171100384Speter{ 1172144450Sjhb struct timeval32 tv32; 1173144450Sjhb struct timeval tv, *tvp; 1174144450Sjhb struct timezone tz, *tzp; 1175100384Speter int error; 1176100384Speter 1177144450Sjhb if (uap->tv) { 1178144450Sjhb error = copyin(uap->tv, &tv32, sizeof(tv32)); 1179100384Speter if (error) 1180100384Speter return (error); 1181144450Sjhb CP(tv32, tv, tv_sec); 1182144450Sjhb CP(tv32, tv, tv_usec); 1183144450Sjhb tvp = &tv; 1184144450Sjhb } else 1185144450Sjhb tvp = NULL; 1186144450Sjhb if (uap->tzp) { 1187144450Sjhb error = copyin(uap->tzp, &tz, sizeof(tz)); 1188100384Speter if (error) 1189100384Speter return (error); 1190144450Sjhb tzp = &tz; 1191144450Sjhb } else 1192144450Sjhb tzp = NULL; 1193144450Sjhb return (kern_settimeofday(td, tvp, tzp)); 1194100384Speter} 1195100384Speter 1196100384Speterint 1197119333Speterfreebsd32_utimes(struct thread *td, struct freebsd32_utimes_args *uap) 1198100384Speter{ 1199142059Sjhb struct timeval32 s32[2]; 1200142059Sjhb struct timeval s[2], *sp; 1201100384Speter int error; 1202100384Speter 1203142059Sjhb if (uap->tptr != NULL) { 1204142059Sjhb error = copyin(uap->tptr, s32, sizeof(s32)); 1205100384Speter if (error) 1206100384Speter return (error); 1207100384Speter CP(s32[0], s[0], tv_sec); 1208100384Speter CP(s32[0], s[0], tv_usec); 1209100384Speter CP(s32[1], s[1], tv_sec); 1210100384Speter CP(s32[1], s[1], tv_usec); 1211142059Sjhb sp = s; 1212142059Sjhb } else 1213142059Sjhb sp = NULL; 1214142059Sjhb return (kern_utimes(td, uap->path, UIO_USERSPACE, sp, UIO_SYSSPACE)); 1215100384Speter} 1216100384Speter 1217100384Speterint 1218154586Sambriskofreebsd32_lutimes(struct thread *td, struct freebsd32_lutimes_args *uap) 1219154586Sambrisko{ 1220154586Sambrisko struct timeval32 s32[2]; 1221154586Sambrisko struct timeval s[2], *sp; 1222154586Sambrisko int error; 1223154586Sambrisko 1224154586Sambrisko if (uap->tptr != NULL) { 1225154586Sambrisko error = copyin(uap->tptr, s32, sizeof(s32)); 1226154586Sambrisko if (error) 1227154586Sambrisko return (error); 1228154586Sambrisko CP(s32[0], s[0], tv_sec); 1229154586Sambrisko CP(s32[0], s[0], tv_usec); 1230154586Sambrisko CP(s32[1], s[1], tv_sec); 1231154586Sambrisko CP(s32[1], s[1], tv_usec); 1232154586Sambrisko sp = s; 1233154586Sambrisko } else 1234154586Sambrisko sp = NULL; 1235154586Sambrisko return (kern_lutimes(td, uap->path, UIO_USERSPACE, sp, UIO_SYSSPACE)); 1236154586Sambrisko} 1237154586Sambrisko 1238154586Sambriskoint 1239153247Sambriskofreebsd32_futimes(struct thread *td, struct freebsd32_futimes_args *uap) 1240153247Sambrisko{ 1241153247Sambrisko struct timeval32 s32[2]; 1242153247Sambrisko struct timeval s[2], *sp; 1243153247Sambrisko int error; 1244153247Sambrisko 1245153247Sambrisko if (uap->tptr != NULL) { 1246153247Sambrisko error = copyin(uap->tptr, s32, sizeof(s32)); 1247153247Sambrisko if (error) 1248153247Sambrisko return (error); 1249153247Sambrisko CP(s32[0], s[0], tv_sec); 1250153247Sambrisko CP(s32[0], s[0], tv_usec); 1251153247Sambrisko CP(s32[1], s[1], tv_sec); 1252153247Sambrisko CP(s32[1], s[1], tv_usec); 1253153247Sambrisko sp = s; 1254153247Sambrisko } else 1255153247Sambrisko sp = NULL; 1256153247Sambrisko return (kern_futimes(td, uap->fd, sp, UIO_SYSSPACE)); 1257153247Sambrisko} 1258153247Sambrisko 1259177789Skibint 1260177789Skibfreebsd32_futimesat(struct thread *td, struct freebsd32_futimesat_args *uap) 1261177789Skib{ 1262177789Skib struct timeval32 s32[2]; 1263177789Skib struct timeval s[2], *sp; 1264177789Skib int error; 1265153247Sambrisko 1266177789Skib if (uap->times != NULL) { 1267177789Skib error = copyin(uap->times, s32, sizeof(s32)); 1268177789Skib if (error) 1269177789Skib return (error); 1270177789Skib CP(s32[0], s[0], tv_sec); 1271177789Skib CP(s32[0], s[0], tv_usec); 1272177789Skib CP(s32[1], s[1], tv_sec); 1273177789Skib CP(s32[1], s[1], tv_usec); 1274177789Skib sp = s; 1275177789Skib } else 1276177789Skib sp = NULL; 1277177789Skib return (kern_utimesat(td, uap->fd, uap->path, UIO_USERSPACE, 1278177789Skib sp, UIO_SYSSPACE)); 1279177789Skib} 1280177789Skib 1281153247Sambriskoint 1282119333Speterfreebsd32_adjtime(struct thread *td, struct freebsd32_adjtime_args *uap) 1283100384Speter{ 1284144450Sjhb struct timeval32 tv32; 1285144450Sjhb struct timeval delta, olddelta, *deltap; 1286100384Speter int error; 1287100384Speter 1288144450Sjhb if (uap->delta) { 1289144450Sjhb error = copyin(uap->delta, &tv32, sizeof(tv32)); 1290100384Speter if (error) 1291100384Speter return (error); 1292144450Sjhb CP(tv32, delta, tv_sec); 1293144450Sjhb CP(tv32, delta, tv_usec); 1294144450Sjhb deltap = δ 1295144450Sjhb } else 1296144450Sjhb deltap = NULL; 1297144450Sjhb error = kern_adjtime(td, deltap, &olddelta); 1298144450Sjhb if (uap->olddelta && error == 0) { 1299144450Sjhb CP(olddelta, tv32, tv_sec); 1300144450Sjhb CP(olddelta, tv32, tv_usec); 1301144450Sjhb error = copyout(&tv32, uap->olddelta, sizeof(tv32)); 1302100384Speter } 1303100384Speter return (error); 1304100384Speter} 1305100384Speter 1306128597Smarcel#ifdef COMPAT_FREEBSD4 1307100384Speterint 1308128260Speterfreebsd4_freebsd32_statfs(struct thread *td, struct freebsd4_freebsd32_statfs_args *uap) 1309100384Speter{ 1310142059Sjhb struct statfs32 s32; 1311142059Sjhb struct statfs s; 1312100384Speter int error; 1313100384Speter 1314142059Sjhb error = kern_statfs(td, uap->path, UIO_USERSPACE, &s); 1315100384Speter if (error) 1316100384Speter return (error); 1317174526Sjhb copy_statfs(&s, &s32); 1318142059Sjhb return (copyout(&s32, uap->buf, sizeof(s32))); 1319100384Speter} 1320128597Smarcel#endif 1321100384Speter 1322128597Smarcel#ifdef COMPAT_FREEBSD4 1323100384Speterint 1324128260Speterfreebsd4_freebsd32_fstatfs(struct thread *td, struct freebsd4_freebsd32_fstatfs_args *uap) 1325100384Speter{ 1326142059Sjhb struct statfs32 s32; 1327142059Sjhb struct statfs s; 1328100384Speter int error; 1329100384Speter 1330142059Sjhb error = kern_fstatfs(td, uap->fd, &s); 1331100384Speter if (error) 1332100384Speter return (error); 1333174526Sjhb copy_statfs(&s, &s32); 1334142059Sjhb return (copyout(&s32, uap->buf, sizeof(s32))); 1335100384Speter} 1336128597Smarcel#endif 1337100384Speter 1338128597Smarcel#ifdef COMPAT_FREEBSD4 1339100384Speterint 1340128260Speterfreebsd4_freebsd32_fhstatfs(struct thread *td, struct freebsd4_freebsd32_fhstatfs_args *uap) 1341128260Speter{ 1342142059Sjhb struct statfs32 s32; 1343142059Sjhb struct statfs s; 1344142059Sjhb fhandle_t fh; 1345128260Speter int error; 1346128260Speter 1347142059Sjhb if ((error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t))) != 0) 1348142059Sjhb return (error); 1349142059Sjhb error = kern_fhstatfs(td, fh, &s); 1350128260Speter if (error) 1351128260Speter return (error); 1352174526Sjhb copy_statfs(&s, &s32); 1353142059Sjhb return (copyout(&s32, uap->buf, sizeof(s32))); 1354128260Speter} 1355128597Smarcel#endif 1356128260Speter 1357194910Sjhb#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \ 1358194910Sjhb defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7) 1359174381Sjhbstatic void 1360194910Sjhbfreebsd32_ipcperm_old_in(struct ipc_perm32_old *ip32, struct ipc_perm *ip) 1361194910Sjhb{ 1362194910Sjhb 1363194910Sjhb CP(*ip32, *ip, cuid); 1364194910Sjhb CP(*ip32, *ip, cgid); 1365194910Sjhb CP(*ip32, *ip, uid); 1366194910Sjhb CP(*ip32, *ip, gid); 1367194910Sjhb CP(*ip32, *ip, mode); 1368194910Sjhb CP(*ip32, *ip, seq); 1369194910Sjhb CP(*ip32, *ip, key); 1370194910Sjhb} 1371194910Sjhb 1372194910Sjhbstatic void 1373194910Sjhbfreebsd32_ipcperm_old_out(struct ipc_perm *ip, struct ipc_perm32_old *ip32) 1374194910Sjhb{ 1375194910Sjhb 1376194910Sjhb CP(*ip, *ip32, cuid); 1377194910Sjhb CP(*ip, *ip32, cgid); 1378194910Sjhb CP(*ip, *ip32, uid); 1379194910Sjhb CP(*ip, *ip32, gid); 1380194910Sjhb CP(*ip, *ip32, mode); 1381194910Sjhb CP(*ip, *ip32, seq); 1382194910Sjhb CP(*ip, *ip32, key); 1383194910Sjhb} 1384194910Sjhb#endif 1385194910Sjhb 1386194910Sjhbstatic void 1387174381Sjhbfreebsd32_ipcperm_in(struct ipc_perm32 *ip32, struct ipc_perm *ip) 1388174381Sjhb{ 1389174381Sjhb 1390174381Sjhb CP(*ip32, *ip, cuid); 1391174381Sjhb CP(*ip32, *ip, cgid); 1392174381Sjhb CP(*ip32, *ip, uid); 1393174381Sjhb CP(*ip32, *ip, gid); 1394174381Sjhb CP(*ip32, *ip, mode); 1395174381Sjhb CP(*ip32, *ip, seq); 1396174381Sjhb CP(*ip32, *ip, key); 1397174381Sjhb} 1398174381Sjhb 1399174381Sjhbstatic void 1400174381Sjhbfreebsd32_ipcperm_out(struct ipc_perm *ip, struct ipc_perm32 *ip32) 1401174381Sjhb{ 1402174381Sjhb 1403174381Sjhb CP(*ip, *ip32, cuid); 1404174381Sjhb CP(*ip, *ip32, cgid); 1405174381Sjhb CP(*ip, *ip32, uid); 1406174381Sjhb CP(*ip, *ip32, gid); 1407174381Sjhb CP(*ip, *ip32, mode); 1408174381Sjhb CP(*ip, *ip32, seq); 1409174381Sjhb CP(*ip, *ip32, key); 1410174381Sjhb} 1411174381Sjhb 1412128260Speterint 1413119333Speterfreebsd32_semsys(struct thread *td, struct freebsd32_semsys_args *uap) 1414100384Speter{ 1415174381Sjhb 1416194910Sjhb#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \ 1417194910Sjhb defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7) 1418174381Sjhb switch (uap->which) { 1419174381Sjhb case 0: 1420195911Sjhb return (freebsd7_freebsd32_semctl(td, 1421195911Sjhb (struct freebsd7_freebsd32_semctl_args *)&uap->a2)); 1422174381Sjhb default: 1423174381Sjhb return (semsys(td, (struct semsys_args *)uap)); 1424174381Sjhb } 1425194910Sjhb#else 1426194910Sjhb return (nosys(td, NULL)); 1427194910Sjhb#endif 1428100384Speter} 1429100384Speter 1430194910Sjhb#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \ 1431194910Sjhb defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7) 1432100384Speterint 1433194910Sjhbfreebsd7_freebsd32_semctl(struct thread *td, 1434194910Sjhb struct freebsd7_freebsd32_semctl_args *uap) 1435194910Sjhb{ 1436194910Sjhb struct semid_ds32_old dsbuf32; 1437194910Sjhb struct semid_ds dsbuf; 1438194910Sjhb union semun semun; 1439194910Sjhb union semun32 arg; 1440194910Sjhb register_t rval; 1441194910Sjhb int error; 1442194910Sjhb 1443194910Sjhb switch (uap->cmd) { 1444194910Sjhb case SEM_STAT: 1445194910Sjhb case IPC_SET: 1446194910Sjhb case IPC_STAT: 1447194910Sjhb case GETALL: 1448194910Sjhb case SETVAL: 1449194910Sjhb case SETALL: 1450194910Sjhb error = copyin(uap->arg, &arg, sizeof(arg)); 1451194910Sjhb if (error) 1452194910Sjhb return (error); 1453194910Sjhb break; 1454194910Sjhb } 1455194910Sjhb 1456194910Sjhb switch (uap->cmd) { 1457194910Sjhb case SEM_STAT: 1458194910Sjhb case IPC_STAT: 1459194910Sjhb semun.buf = &dsbuf; 1460194910Sjhb break; 1461194910Sjhb case IPC_SET: 1462194910Sjhb error = copyin(PTRIN(arg.buf), &dsbuf32, sizeof(dsbuf32)); 1463194910Sjhb if (error) 1464194910Sjhb return (error); 1465194910Sjhb freebsd32_ipcperm_old_in(&dsbuf32.sem_perm, &dsbuf.sem_perm); 1466194910Sjhb PTRIN_CP(dsbuf32, dsbuf, sem_base); 1467194910Sjhb CP(dsbuf32, dsbuf, sem_nsems); 1468194910Sjhb CP(dsbuf32, dsbuf, sem_otime); 1469194910Sjhb CP(dsbuf32, dsbuf, sem_ctime); 1470194910Sjhb semun.buf = &dsbuf; 1471194910Sjhb break; 1472194910Sjhb case GETALL: 1473194910Sjhb case SETALL: 1474194910Sjhb semun.array = PTRIN(arg.array); 1475194910Sjhb break; 1476194910Sjhb case SETVAL: 1477194910Sjhb semun.val = arg.val; 1478194910Sjhb break; 1479194910Sjhb } 1480194910Sjhb 1481194910Sjhb error = kern_semctl(td, uap->semid, uap->semnum, uap->cmd, &semun, 1482194910Sjhb &rval); 1483194910Sjhb if (error) 1484194910Sjhb return (error); 1485194910Sjhb 1486194910Sjhb switch (uap->cmd) { 1487194910Sjhb case SEM_STAT: 1488194910Sjhb case IPC_STAT: 1489194910Sjhb bzero(&dsbuf32, sizeof(dsbuf32)); 1490194910Sjhb freebsd32_ipcperm_old_out(&dsbuf.sem_perm, &dsbuf32.sem_perm); 1491194910Sjhb PTROUT_CP(dsbuf, dsbuf32, sem_base); 1492194910Sjhb CP(dsbuf, dsbuf32, sem_nsems); 1493194910Sjhb CP(dsbuf, dsbuf32, sem_otime); 1494194910Sjhb CP(dsbuf, dsbuf32, sem_ctime); 1495194910Sjhb error = copyout(&dsbuf32, PTRIN(arg.buf), sizeof(dsbuf32)); 1496194910Sjhb break; 1497194910Sjhb } 1498194910Sjhb 1499194910Sjhb if (error == 0) 1500194910Sjhb td->td_retval[0] = rval; 1501194910Sjhb return (error); 1502194910Sjhb} 1503194910Sjhb#endif 1504194910Sjhb 1505194910Sjhbint 1506174381Sjhbfreebsd32_semctl(struct thread *td, struct freebsd32_semctl_args *uap) 1507174381Sjhb{ 1508174381Sjhb struct semid_ds32 dsbuf32; 1509174381Sjhb struct semid_ds dsbuf; 1510174381Sjhb union semun semun; 1511174381Sjhb union semun32 arg; 1512174381Sjhb register_t rval; 1513174381Sjhb int error; 1514174381Sjhb 1515174381Sjhb switch (uap->cmd) { 1516174381Sjhb case SEM_STAT: 1517174381Sjhb case IPC_SET: 1518174381Sjhb case IPC_STAT: 1519174381Sjhb case GETALL: 1520174381Sjhb case SETVAL: 1521174381Sjhb case SETALL: 1522174381Sjhb error = copyin(uap->arg, &arg, sizeof(arg)); 1523174381Sjhb if (error) 1524174381Sjhb return (error); 1525174381Sjhb break; 1526174381Sjhb } 1527174381Sjhb 1528174381Sjhb switch (uap->cmd) { 1529174381Sjhb case SEM_STAT: 1530174381Sjhb case IPC_STAT: 1531174381Sjhb semun.buf = &dsbuf; 1532174381Sjhb break; 1533174381Sjhb case IPC_SET: 1534174381Sjhb error = copyin(PTRIN(arg.buf), &dsbuf32, sizeof(dsbuf32)); 1535174381Sjhb if (error) 1536174381Sjhb return (error); 1537174381Sjhb freebsd32_ipcperm_in(&dsbuf32.sem_perm, &dsbuf.sem_perm); 1538174381Sjhb PTRIN_CP(dsbuf32, dsbuf, sem_base); 1539174381Sjhb CP(dsbuf32, dsbuf, sem_nsems); 1540174381Sjhb CP(dsbuf32, dsbuf, sem_otime); 1541174381Sjhb CP(dsbuf32, dsbuf, sem_ctime); 1542174381Sjhb semun.buf = &dsbuf; 1543174381Sjhb break; 1544174381Sjhb case GETALL: 1545174381Sjhb case SETALL: 1546174381Sjhb semun.array = PTRIN(arg.array); 1547174381Sjhb break; 1548174381Sjhb case SETVAL: 1549174381Sjhb semun.val = arg.val; 1550174381Sjhb break; 1551174381Sjhb } 1552174381Sjhb 1553174381Sjhb error = kern_semctl(td, uap->semid, uap->semnum, uap->cmd, &semun, 1554174381Sjhb &rval); 1555174381Sjhb if (error) 1556174381Sjhb return (error); 1557174381Sjhb 1558174381Sjhb switch (uap->cmd) { 1559174381Sjhb case SEM_STAT: 1560174381Sjhb case IPC_STAT: 1561194910Sjhb bzero(&dsbuf32, sizeof(dsbuf32)); 1562174381Sjhb freebsd32_ipcperm_out(&dsbuf.sem_perm, &dsbuf32.sem_perm); 1563174381Sjhb PTROUT_CP(dsbuf, dsbuf32, sem_base); 1564174381Sjhb CP(dsbuf, dsbuf32, sem_nsems); 1565174381Sjhb CP(dsbuf, dsbuf32, sem_otime); 1566174381Sjhb CP(dsbuf, dsbuf32, sem_ctime); 1567174381Sjhb error = copyout(&dsbuf32, PTRIN(arg.buf), sizeof(dsbuf32)); 1568174381Sjhb break; 1569174381Sjhb } 1570174381Sjhb 1571174381Sjhb if (error == 0) 1572174381Sjhb td->td_retval[0] = rval; 1573174381Sjhb return (error); 1574174381Sjhb} 1575174381Sjhb 1576174381Sjhbint 1577119333Speterfreebsd32_msgsys(struct thread *td, struct freebsd32_msgsys_args *uap) 1578100384Speter{ 1579174381Sjhb 1580194910Sjhb#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \ 1581194910Sjhb defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7) 1582165405Sjkim switch (uap->which) { 1583174381Sjhb case 0: 1584195911Sjhb return (freebsd7_freebsd32_msgctl(td, 1585195911Sjhb (struct freebsd7_freebsd32_msgctl_args *)&uap->a2)); 1586165405Sjkim case 2: 1587165405Sjkim return (freebsd32_msgsnd(td, 1588165405Sjkim (struct freebsd32_msgsnd_args *)&uap->a2)); 1589165405Sjkim case 3: 1590165405Sjkim return (freebsd32_msgrcv(td, 1591165405Sjkim (struct freebsd32_msgrcv_args *)&uap->a2)); 1592165405Sjkim default: 1593174381Sjhb return (msgsys(td, (struct msgsys_args *)uap)); 1594165405Sjkim } 1595194910Sjhb#else 1596194910Sjhb return (nosys(td, NULL)); 1597194910Sjhb#endif 1598100384Speter} 1599100384Speter 1600194910Sjhb#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \ 1601194910Sjhb defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7) 1602100384Speterint 1603194910Sjhbfreebsd7_freebsd32_msgctl(struct thread *td, 1604194910Sjhb struct freebsd7_freebsd32_msgctl_args *uap) 1605194910Sjhb{ 1606194910Sjhb struct msqid_ds msqbuf; 1607194910Sjhb struct msqid_ds32_old msqbuf32; 1608194910Sjhb int error; 1609194910Sjhb 1610194910Sjhb if (uap->cmd == IPC_SET) { 1611194910Sjhb error = copyin(uap->buf, &msqbuf32, sizeof(msqbuf32)); 1612194910Sjhb if (error) 1613194910Sjhb return (error); 1614194910Sjhb freebsd32_ipcperm_old_in(&msqbuf32.msg_perm, &msqbuf.msg_perm); 1615194910Sjhb PTRIN_CP(msqbuf32, msqbuf, msg_first); 1616194910Sjhb PTRIN_CP(msqbuf32, msqbuf, msg_last); 1617194910Sjhb CP(msqbuf32, msqbuf, msg_cbytes); 1618194910Sjhb CP(msqbuf32, msqbuf, msg_qnum); 1619194910Sjhb CP(msqbuf32, msqbuf, msg_qbytes); 1620194910Sjhb CP(msqbuf32, msqbuf, msg_lspid); 1621194910Sjhb CP(msqbuf32, msqbuf, msg_lrpid); 1622194910Sjhb CP(msqbuf32, msqbuf, msg_stime); 1623194910Sjhb CP(msqbuf32, msqbuf, msg_rtime); 1624194910Sjhb CP(msqbuf32, msqbuf, msg_ctime); 1625194910Sjhb } 1626194910Sjhb error = kern_msgctl(td, uap->msqid, uap->cmd, &msqbuf); 1627194910Sjhb if (error) 1628194910Sjhb return (error); 1629194910Sjhb if (uap->cmd == IPC_STAT) { 1630194910Sjhb bzero(&msqbuf32, sizeof(msqbuf32)); 1631194910Sjhb freebsd32_ipcperm_old_out(&msqbuf.msg_perm, &msqbuf32.msg_perm); 1632194910Sjhb PTROUT_CP(msqbuf, msqbuf32, msg_first); 1633194910Sjhb PTROUT_CP(msqbuf, msqbuf32, msg_last); 1634194910Sjhb CP(msqbuf, msqbuf32, msg_cbytes); 1635194910Sjhb CP(msqbuf, msqbuf32, msg_qnum); 1636194910Sjhb CP(msqbuf, msqbuf32, msg_qbytes); 1637194910Sjhb CP(msqbuf, msqbuf32, msg_lspid); 1638194910Sjhb CP(msqbuf, msqbuf32, msg_lrpid); 1639194910Sjhb CP(msqbuf, msqbuf32, msg_stime); 1640194910Sjhb CP(msqbuf, msqbuf32, msg_rtime); 1641194910Sjhb CP(msqbuf, msqbuf32, msg_ctime); 1642194910Sjhb error = copyout(&msqbuf32, uap->buf, sizeof(struct msqid_ds32)); 1643194910Sjhb } 1644194910Sjhb return (error); 1645194910Sjhb} 1646194910Sjhb#endif 1647194910Sjhb 1648194910Sjhbint 1649174381Sjhbfreebsd32_msgctl(struct thread *td, struct freebsd32_msgctl_args *uap) 1650174381Sjhb{ 1651174381Sjhb struct msqid_ds msqbuf; 1652174381Sjhb struct msqid_ds32 msqbuf32; 1653174381Sjhb int error; 1654174381Sjhb 1655174381Sjhb if (uap->cmd == IPC_SET) { 1656174381Sjhb error = copyin(uap->buf, &msqbuf32, sizeof(msqbuf32)); 1657174381Sjhb if (error) 1658174381Sjhb return (error); 1659174381Sjhb freebsd32_ipcperm_in(&msqbuf32.msg_perm, &msqbuf.msg_perm); 1660174381Sjhb PTRIN_CP(msqbuf32, msqbuf, msg_first); 1661174381Sjhb PTRIN_CP(msqbuf32, msqbuf, msg_last); 1662174381Sjhb CP(msqbuf32, msqbuf, msg_cbytes); 1663174381Sjhb CP(msqbuf32, msqbuf, msg_qnum); 1664174381Sjhb CP(msqbuf32, msqbuf, msg_qbytes); 1665174381Sjhb CP(msqbuf32, msqbuf, msg_lspid); 1666174381Sjhb CP(msqbuf32, msqbuf, msg_lrpid); 1667174381Sjhb CP(msqbuf32, msqbuf, msg_stime); 1668174381Sjhb CP(msqbuf32, msqbuf, msg_rtime); 1669174381Sjhb CP(msqbuf32, msqbuf, msg_ctime); 1670174381Sjhb } 1671174381Sjhb error = kern_msgctl(td, uap->msqid, uap->cmd, &msqbuf); 1672174381Sjhb if (error) 1673174381Sjhb return (error); 1674174381Sjhb if (uap->cmd == IPC_STAT) { 1675174381Sjhb freebsd32_ipcperm_out(&msqbuf.msg_perm, &msqbuf32.msg_perm); 1676174381Sjhb PTROUT_CP(msqbuf, msqbuf32, msg_first); 1677174381Sjhb PTROUT_CP(msqbuf, msqbuf32, msg_last); 1678174381Sjhb CP(msqbuf, msqbuf32, msg_cbytes); 1679174381Sjhb CP(msqbuf, msqbuf32, msg_qnum); 1680174381Sjhb CP(msqbuf, msqbuf32, msg_qbytes); 1681174381Sjhb CP(msqbuf, msqbuf32, msg_lspid); 1682174381Sjhb CP(msqbuf, msqbuf32, msg_lrpid); 1683174381Sjhb CP(msqbuf, msqbuf32, msg_stime); 1684174381Sjhb CP(msqbuf, msqbuf32, msg_rtime); 1685174381Sjhb CP(msqbuf, msqbuf32, msg_ctime); 1686174381Sjhb error = copyout(&msqbuf32, uap->buf, sizeof(struct msqid_ds32)); 1687174381Sjhb } 1688174381Sjhb return (error); 1689174381Sjhb} 1690174381Sjhb 1691174381Sjhbint 1692165405Sjkimfreebsd32_msgsnd(struct thread *td, struct freebsd32_msgsnd_args *uap) 1693165405Sjkim{ 1694165405Sjkim const void *msgp; 1695165405Sjkim long mtype; 1696165405Sjkim int32_t mtype32; 1697165405Sjkim int error; 1698165405Sjkim 1699165405Sjkim msgp = PTRIN(uap->msgp); 1700165405Sjkim if ((error = copyin(msgp, &mtype32, sizeof(mtype32))) != 0) 1701165405Sjkim return (error); 1702165405Sjkim mtype = mtype32; 1703165405Sjkim return (kern_msgsnd(td, uap->msqid, 1704165405Sjkim (const char *)msgp + sizeof(mtype32), 1705165405Sjkim uap->msgsz, uap->msgflg, mtype)); 1706165405Sjkim} 1707165405Sjkim 1708165405Sjkimint 1709165405Sjkimfreebsd32_msgrcv(struct thread *td, struct freebsd32_msgrcv_args *uap) 1710165405Sjkim{ 1711165405Sjkim void *msgp; 1712165405Sjkim long mtype; 1713165405Sjkim int32_t mtype32; 1714165405Sjkim int error; 1715165405Sjkim 1716165405Sjkim msgp = PTRIN(uap->msgp); 1717165405Sjkim if ((error = kern_msgrcv(td, uap->msqid, 1718165405Sjkim (char *)msgp + sizeof(mtype32), uap->msgsz, 1719165405Sjkim uap->msgtyp, uap->msgflg, &mtype)) != 0) 1720165405Sjkim return (error); 1721165405Sjkim mtype32 = (int32_t)mtype; 1722165405Sjkim return (copyout(&mtype32, msgp, sizeof(mtype32))); 1723165405Sjkim} 1724165405Sjkim 1725165405Sjkimint 1726119333Speterfreebsd32_shmsys(struct thread *td, struct freebsd32_shmsys_args *uap) 1727100384Speter{ 1728157285Sps 1729194910Sjhb#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \ 1730194910Sjhb defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7) 1731157285Sps switch (uap->which) { 1732157285Sps case 0: { /* shmat */ 1733157285Sps struct shmat_args ap; 1734157285Sps 1735157285Sps ap.shmid = uap->a2; 1736157285Sps ap.shmaddr = PTRIN(uap->a3); 1737157285Sps ap.shmflg = uap->a4; 1738157285Sps return (sysent[SYS_shmat].sy_call(td, &ap)); 1739157285Sps } 1740157285Sps case 2: { /* shmdt */ 1741157285Sps struct shmdt_args ap; 1742157285Sps 1743157285Sps ap.shmaddr = PTRIN(uap->a2); 1744157285Sps return (sysent[SYS_shmdt].sy_call(td, &ap)); 1745157285Sps } 1746157285Sps case 3: { /* shmget */ 1747157285Sps struct shmget_args ap; 1748157285Sps 1749157285Sps ap.key = uap->a2; 1750157285Sps ap.size = uap->a3; 1751157285Sps ap.shmflg = uap->a4; 1752157285Sps return (sysent[SYS_shmget].sy_call(td, &ap)); 1753157285Sps } 1754157285Sps case 4: { /* shmctl */ 1755195911Sjhb struct freebsd7_freebsd32_shmctl_args ap; 1756157285Sps 1757157285Sps ap.shmid = uap->a2; 1758157285Sps ap.cmd = uap->a3; 1759157285Sps ap.buf = PTRIN(uap->a4); 1760195911Sjhb return (freebsd7_freebsd32_shmctl(td, &ap)); 1761157285Sps } 1762157285Sps case 1: /* oshmctl */ 1763157285Sps default: 1764157285Sps return (EINVAL); 1765157285Sps } 1766194910Sjhb#else 1767194910Sjhb return (nosys(td, NULL)); 1768194910Sjhb#endif 1769100384Speter} 1770100384Speter 1771194910Sjhb#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \ 1772194910Sjhb defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7) 1773100384Speterint 1774194910Sjhbfreebsd7_freebsd32_shmctl(struct thread *td, 1775194910Sjhb struct freebsd7_freebsd32_shmctl_args *uap) 1776194910Sjhb{ 1777194910Sjhb int error = 0; 1778194910Sjhb union { 1779194910Sjhb struct shmid_ds shmid_ds; 1780194910Sjhb struct shm_info shm_info; 1781194910Sjhb struct shminfo shminfo; 1782194910Sjhb } u; 1783194910Sjhb union { 1784194910Sjhb struct shmid_ds32_old shmid_ds32; 1785194910Sjhb struct shm_info32 shm_info32; 1786194910Sjhb struct shminfo32 shminfo32; 1787194910Sjhb } u32; 1788194910Sjhb size_t sz; 1789194910Sjhb 1790194910Sjhb if (uap->cmd == IPC_SET) { 1791194910Sjhb if ((error = copyin(uap->buf, &u32.shmid_ds32, 1792194910Sjhb sizeof(u32.shmid_ds32)))) 1793194910Sjhb goto done; 1794194910Sjhb freebsd32_ipcperm_old_in(&u32.shmid_ds32.shm_perm, 1795194910Sjhb &u.shmid_ds.shm_perm); 1796194910Sjhb CP(u32.shmid_ds32, u.shmid_ds, shm_segsz); 1797194910Sjhb CP(u32.shmid_ds32, u.shmid_ds, shm_lpid); 1798194910Sjhb CP(u32.shmid_ds32, u.shmid_ds, shm_cpid); 1799194910Sjhb CP(u32.shmid_ds32, u.shmid_ds, shm_nattch); 1800194910Sjhb CP(u32.shmid_ds32, u.shmid_ds, shm_atime); 1801194910Sjhb CP(u32.shmid_ds32, u.shmid_ds, shm_dtime); 1802194910Sjhb CP(u32.shmid_ds32, u.shmid_ds, shm_ctime); 1803194910Sjhb } 1804194910Sjhb 1805194910Sjhb error = kern_shmctl(td, uap->shmid, uap->cmd, (void *)&u, &sz); 1806194910Sjhb if (error) 1807194910Sjhb goto done; 1808194910Sjhb 1809194910Sjhb /* Cases in which we need to copyout */ 1810194910Sjhb switch (uap->cmd) { 1811194910Sjhb case IPC_INFO: 1812194910Sjhb CP(u.shminfo, u32.shminfo32, shmmax); 1813194910Sjhb CP(u.shminfo, u32.shminfo32, shmmin); 1814194910Sjhb CP(u.shminfo, u32.shminfo32, shmmni); 1815194910Sjhb CP(u.shminfo, u32.shminfo32, shmseg); 1816194910Sjhb CP(u.shminfo, u32.shminfo32, shmall); 1817194910Sjhb error = copyout(&u32.shminfo32, uap->buf, 1818194910Sjhb sizeof(u32.shminfo32)); 1819194910Sjhb break; 1820194910Sjhb case SHM_INFO: 1821194910Sjhb CP(u.shm_info, u32.shm_info32, used_ids); 1822194910Sjhb CP(u.shm_info, u32.shm_info32, shm_rss); 1823194910Sjhb CP(u.shm_info, u32.shm_info32, shm_tot); 1824194910Sjhb CP(u.shm_info, u32.shm_info32, shm_swp); 1825194910Sjhb CP(u.shm_info, u32.shm_info32, swap_attempts); 1826194910Sjhb CP(u.shm_info, u32.shm_info32, swap_successes); 1827194910Sjhb error = copyout(&u32.shm_info32, uap->buf, 1828194910Sjhb sizeof(u32.shm_info32)); 1829194910Sjhb break; 1830194910Sjhb case SHM_STAT: 1831194910Sjhb case IPC_STAT: 1832194910Sjhb freebsd32_ipcperm_old_out(&u.shmid_ds.shm_perm, 1833194910Sjhb &u32.shmid_ds32.shm_perm); 1834194910Sjhb if (u.shmid_ds.shm_segsz > INT32_MAX) 1835194910Sjhb u32.shmid_ds32.shm_segsz = INT32_MAX; 1836194910Sjhb else 1837194910Sjhb CP(u.shmid_ds, u32.shmid_ds32, shm_segsz); 1838194910Sjhb CP(u.shmid_ds, u32.shmid_ds32, shm_lpid); 1839194910Sjhb CP(u.shmid_ds, u32.shmid_ds32, shm_cpid); 1840194910Sjhb CP(u.shmid_ds, u32.shmid_ds32, shm_nattch); 1841194910Sjhb CP(u.shmid_ds, u32.shmid_ds32, shm_atime); 1842194910Sjhb CP(u.shmid_ds, u32.shmid_ds32, shm_dtime); 1843194910Sjhb CP(u.shmid_ds, u32.shmid_ds32, shm_ctime); 1844194910Sjhb u32.shmid_ds32.shm_internal = 0; 1845194910Sjhb error = copyout(&u32.shmid_ds32, uap->buf, 1846194910Sjhb sizeof(u32.shmid_ds32)); 1847194910Sjhb break; 1848194910Sjhb } 1849194910Sjhb 1850194910Sjhbdone: 1851194910Sjhb if (error) { 1852194910Sjhb /* Invalidate the return value */ 1853194910Sjhb td->td_retval[0] = -1; 1854194910Sjhb } 1855194910Sjhb return (error); 1856194910Sjhb} 1857194910Sjhb#endif 1858194910Sjhb 1859194910Sjhbint 1860157285Spsfreebsd32_shmctl(struct thread *td, struct freebsd32_shmctl_args *uap) 1861157285Sps{ 1862157285Sps int error = 0; 1863157285Sps union { 1864157285Sps struct shmid_ds shmid_ds; 1865157285Sps struct shm_info shm_info; 1866157285Sps struct shminfo shminfo; 1867157285Sps } u; 1868157285Sps union { 1869157285Sps struct shmid_ds32 shmid_ds32; 1870157285Sps struct shm_info32 shm_info32; 1871157285Sps struct shminfo32 shminfo32; 1872157285Sps } u32; 1873157285Sps size_t sz; 1874157285Sps 1875157285Sps if (uap->cmd == IPC_SET) { 1876157285Sps if ((error = copyin(uap->buf, &u32.shmid_ds32, 1877157285Sps sizeof(u32.shmid_ds32)))) 1878157285Sps goto done; 1879174381Sjhb freebsd32_ipcperm_in(&u32.shmid_ds32.shm_perm, 1880174381Sjhb &u.shmid_ds.shm_perm); 1881157285Sps CP(u32.shmid_ds32, u.shmid_ds, shm_segsz); 1882157285Sps CP(u32.shmid_ds32, u.shmid_ds, shm_lpid); 1883157285Sps CP(u32.shmid_ds32, u.shmid_ds, shm_cpid); 1884157285Sps CP(u32.shmid_ds32, u.shmid_ds, shm_nattch); 1885157285Sps CP(u32.shmid_ds32, u.shmid_ds, shm_atime); 1886157285Sps CP(u32.shmid_ds32, u.shmid_ds, shm_dtime); 1887157285Sps CP(u32.shmid_ds32, u.shmid_ds, shm_ctime); 1888157285Sps } 1889157285Sps 1890157285Sps error = kern_shmctl(td, uap->shmid, uap->cmd, (void *)&u, &sz); 1891157285Sps if (error) 1892157285Sps goto done; 1893157285Sps 1894157285Sps /* Cases in which we need to copyout */ 1895157285Sps switch (uap->cmd) { 1896157285Sps case IPC_INFO: 1897157285Sps CP(u.shminfo, u32.shminfo32, shmmax); 1898157285Sps CP(u.shminfo, u32.shminfo32, shmmin); 1899157285Sps CP(u.shminfo, u32.shminfo32, shmmni); 1900157285Sps CP(u.shminfo, u32.shminfo32, shmseg); 1901157285Sps CP(u.shminfo, u32.shminfo32, shmall); 1902157285Sps error = copyout(&u32.shminfo32, uap->buf, 1903157285Sps sizeof(u32.shminfo32)); 1904157285Sps break; 1905157285Sps case SHM_INFO: 1906157285Sps CP(u.shm_info, u32.shm_info32, used_ids); 1907157285Sps CP(u.shm_info, u32.shm_info32, shm_rss); 1908157285Sps CP(u.shm_info, u32.shm_info32, shm_tot); 1909157285Sps CP(u.shm_info, u32.shm_info32, shm_swp); 1910157285Sps CP(u.shm_info, u32.shm_info32, swap_attempts); 1911157285Sps CP(u.shm_info, u32.shm_info32, swap_successes); 1912157285Sps error = copyout(&u32.shm_info32, uap->buf, 1913157285Sps sizeof(u32.shm_info32)); 1914157285Sps break; 1915157285Sps case SHM_STAT: 1916157285Sps case IPC_STAT: 1917174381Sjhb freebsd32_ipcperm_out(&u.shmid_ds.shm_perm, 1918174381Sjhb &u32.shmid_ds32.shm_perm); 1919194910Sjhb if (u.shmid_ds.shm_segsz > INT32_MAX) 1920194910Sjhb u32.shmid_ds32.shm_segsz = INT32_MAX; 1921194910Sjhb else 1922194910Sjhb CP(u.shmid_ds, u32.shmid_ds32, shm_segsz); 1923157285Sps CP(u.shmid_ds, u32.shmid_ds32, shm_lpid); 1924157285Sps CP(u.shmid_ds, u32.shmid_ds32, shm_cpid); 1925157285Sps CP(u.shmid_ds, u32.shmid_ds32, shm_nattch); 1926157285Sps CP(u.shmid_ds, u32.shmid_ds32, shm_atime); 1927157285Sps CP(u.shmid_ds, u32.shmid_ds32, shm_dtime); 1928157285Sps CP(u.shmid_ds, u32.shmid_ds32, shm_ctime); 1929157285Sps error = copyout(&u32.shmid_ds32, uap->buf, 1930157285Sps sizeof(u32.shmid_ds32)); 1931157285Sps break; 1932157285Sps } 1933157285Sps 1934157285Spsdone: 1935157285Sps if (error) { 1936157285Sps /* Invalidate the return value */ 1937157285Sps td->td_retval[0] = -1; 1938157285Sps } 1939157285Sps return (error); 1940157285Sps} 1941157285Sps 1942157285Spsint 1943119333Speterfreebsd32_pread(struct thread *td, struct freebsd32_pread_args *uap) 1944100384Speter{ 1945100384Speter struct pread_args ap; 1946100384Speter 1947107849Salfred ap.fd = uap->fd; 1948107849Salfred ap.buf = uap->buf; 1949107849Salfred ap.nbyte = uap->nbyte; 1950119333Speter ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 1951100384Speter return (pread(td, &ap)); 1952100384Speter} 1953100384Speter 1954100384Speterint 1955119333Speterfreebsd32_pwrite(struct thread *td, struct freebsd32_pwrite_args *uap) 1956100384Speter{ 1957100384Speter struct pwrite_args ap; 1958100384Speter 1959107849Salfred ap.fd = uap->fd; 1960107849Salfred ap.buf = uap->buf; 1961107849Salfred ap.nbyte = uap->nbyte; 1962119333Speter ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 1963100384Speter return (pwrite(td, &ap)); 1964100384Speter} 1965100384Speter 1966100384Speterint 1967119333Speterfreebsd32_lseek(struct thread *td, struct freebsd32_lseek_args *uap) 1968100384Speter{ 1969100384Speter int error; 1970100384Speter struct lseek_args ap; 1971100384Speter off_t pos; 1972100384Speter 1973107849Salfred ap.fd = uap->fd; 1974119333Speter ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 1975107849Salfred ap.whence = uap->whence; 1976100384Speter error = lseek(td, &ap); 1977100384Speter /* Expand the quad return into two parts for eax and edx */ 1978100384Speter pos = *(off_t *)(td->td_retval); 1979100384Speter td->td_retval[0] = pos & 0xffffffff; /* %eax */ 1980100384Speter td->td_retval[1] = pos >> 32; /* %edx */ 1981100384Speter return error; 1982100384Speter} 1983100384Speter 1984100384Speterint 1985119333Speterfreebsd32_truncate(struct thread *td, struct freebsd32_truncate_args *uap) 1986100384Speter{ 1987100384Speter struct truncate_args ap; 1988100384Speter 1989107849Salfred ap.path = uap->path; 1990119333Speter ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32)); 1991100384Speter return (truncate(td, &ap)); 1992100384Speter} 1993100384Speter 1994100384Speterint 1995119333Speterfreebsd32_ftruncate(struct thread *td, struct freebsd32_ftruncate_args *uap) 1996100384Speter{ 1997100384Speter struct ftruncate_args ap; 1998100384Speter 1999107849Salfred ap.fd = uap->fd; 2000119333Speter ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32)); 2001100384Speter return (ftruncate(td, &ap)); 2002100384Speter} 2003100384Speter 2004184183Sjhbint 2005184183Sjhbfreebsd32_getdirentries(struct thread *td, 2006184183Sjhb struct freebsd32_getdirentries_args *uap) 2007184183Sjhb{ 2008184183Sjhb long base; 2009184183Sjhb int32_t base32; 2010184183Sjhb int error; 2011184183Sjhb 2012184183Sjhb error = kern_getdirentries(td, uap->fd, uap->buf, uap->count, &base); 2013184183Sjhb if (error) 2014184183Sjhb return (error); 2015184183Sjhb if (uap->basep != NULL) { 2016184183Sjhb base32 = base; 2017184183Sjhb error = copyout(&base32, uap->basep, sizeof(int32_t)); 2018184183Sjhb } 2019184183Sjhb return (error); 2020184183Sjhb} 2021184183Sjhb 2022171215Speter#ifdef COMPAT_FREEBSD6 2023171215Speter/* versions with the 'int pad' argument */ 2024171215Speterint 2025171215Speterfreebsd6_freebsd32_pread(struct thread *td, struct freebsd6_freebsd32_pread_args *uap) 2026171215Speter{ 2027171215Speter struct pread_args ap; 2028171215Speter 2029171215Speter ap.fd = uap->fd; 2030171215Speter ap.buf = uap->buf; 2031171215Speter ap.nbyte = uap->nbyte; 2032171215Speter ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 2033171215Speter return (pread(td, &ap)); 2034171215Speter} 2035171215Speter 2036171215Speterint 2037171215Speterfreebsd6_freebsd32_pwrite(struct thread *td, struct freebsd6_freebsd32_pwrite_args *uap) 2038171215Speter{ 2039171215Speter struct pwrite_args ap; 2040171215Speter 2041171215Speter ap.fd = uap->fd; 2042171215Speter ap.buf = uap->buf; 2043171215Speter ap.nbyte = uap->nbyte; 2044171215Speter ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 2045171215Speter return (pwrite(td, &ap)); 2046171215Speter} 2047171215Speter 2048171215Speterint 2049171215Speterfreebsd6_freebsd32_lseek(struct thread *td, struct freebsd6_freebsd32_lseek_args *uap) 2050171215Speter{ 2051171215Speter int error; 2052171215Speter struct lseek_args ap; 2053171215Speter off_t pos; 2054171215Speter 2055171215Speter ap.fd = uap->fd; 2056171215Speter ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 2057171215Speter ap.whence = uap->whence; 2058171215Speter error = lseek(td, &ap); 2059171215Speter /* Expand the quad return into two parts for eax and edx */ 2060171215Speter pos = *(off_t *)(td->td_retval); 2061171215Speter td->td_retval[0] = pos & 0xffffffff; /* %eax */ 2062171215Speter td->td_retval[1] = pos >> 32; /* %edx */ 2063171215Speter return error; 2064171215Speter} 2065171215Speter 2066171215Speterint 2067171215Speterfreebsd6_freebsd32_truncate(struct thread *td, struct freebsd6_freebsd32_truncate_args *uap) 2068171215Speter{ 2069171215Speter struct truncate_args ap; 2070171215Speter 2071171215Speter ap.path = uap->path; 2072171215Speter ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32)); 2073171215Speter return (truncate(td, &ap)); 2074171215Speter} 2075171215Speter 2076171215Speterint 2077171215Speterfreebsd6_freebsd32_ftruncate(struct thread *td, struct freebsd6_freebsd32_ftruncate_args *uap) 2078171215Speter{ 2079171215Speter struct ftruncate_args ap; 2080171215Speter 2081171215Speter ap.fd = uap->fd; 2082171215Speter ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32)); 2083171215Speter return (ftruncate(td, &ap)); 2084171215Speter} 2085171215Speter#endif /* COMPAT_FREEBSD6 */ 2086171215Speter 2087156114Spsstruct sf_hdtr32 { 2088156114Sps uint32_t headers; 2089156114Sps int hdr_cnt; 2090156114Sps uint32_t trailers; 2091156114Sps int trl_cnt; 2092156114Sps}; 2093156114Sps 2094156114Spsstatic int 2095156114Spsfreebsd32_do_sendfile(struct thread *td, 2096156114Sps struct freebsd32_sendfile_args *uap, int compat) 2097104738Speter{ 2098156114Sps struct sendfile_args ap; 2099156114Sps struct sf_hdtr32 hdtr32; 2100156114Sps struct sf_hdtr hdtr; 2101156114Sps struct uio *hdr_uio, *trl_uio; 2102156114Sps struct iovec32 *iov32; 2103156114Sps int error; 2104104738Speter 2105156114Sps hdr_uio = trl_uio = NULL; 2106156114Sps 2107107849Salfred ap.fd = uap->fd; 2108107849Salfred ap.s = uap->s; 2109119333Speter ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 2110156114Sps ap.nbytes = uap->nbytes; 2111156114Sps ap.hdtr = (struct sf_hdtr *)uap->hdtr; /* XXX not used */ 2112156114Sps ap.sbytes = uap->sbytes; 2113107849Salfred ap.flags = uap->flags; 2114156114Sps 2115156114Sps if (uap->hdtr != NULL) { 2116156114Sps error = copyin(uap->hdtr, &hdtr32, sizeof(hdtr32)); 2117156114Sps if (error) 2118156114Sps goto out; 2119156114Sps PTRIN_CP(hdtr32, hdtr, headers); 2120156114Sps CP(hdtr32, hdtr, hdr_cnt); 2121156114Sps PTRIN_CP(hdtr32, hdtr, trailers); 2122156114Sps CP(hdtr32, hdtr, trl_cnt); 2123156114Sps 2124156114Sps if (hdtr.headers != NULL) { 2125160246Sjhb iov32 = PTRIN(hdtr32.headers); 2126156114Sps error = freebsd32_copyinuio(iov32, 2127156114Sps hdtr32.hdr_cnt, &hdr_uio); 2128156114Sps if (error) 2129156114Sps goto out; 2130156114Sps } 2131156114Sps if (hdtr.trailers != NULL) { 2132160246Sjhb iov32 = PTRIN(hdtr32.trailers); 2133156114Sps error = freebsd32_copyinuio(iov32, 2134156114Sps hdtr32.trl_cnt, &trl_uio); 2135156114Sps if (error) 2136156114Sps goto out; 2137156114Sps } 2138156114Sps } 2139156114Sps 2140156114Sps error = kern_sendfile(td, &ap, hdr_uio, trl_uio, compat); 2141156114Spsout: 2142156114Sps if (hdr_uio) 2143156114Sps free(hdr_uio, M_IOV); 2144156114Sps if (trl_uio) 2145156114Sps free(trl_uio, M_IOV); 2146156114Sps return (error); 2147104738Speter} 2148156114Sps 2149156114Sps#ifdef COMPAT_FREEBSD4 2150156114Spsint 2151156114Spsfreebsd4_freebsd32_sendfile(struct thread *td, 2152156114Sps struct freebsd4_freebsd32_sendfile_args *uap) 2153156114Sps{ 2154156114Sps return (freebsd32_do_sendfile(td, 2155156114Sps (struct freebsd32_sendfile_args *)uap, 1)); 2156156114Sps} 2157104738Speter#endif 2158104738Speter 2159104738Speterint 2160119333Speterfreebsd32_sendfile(struct thread *td, struct freebsd32_sendfile_args *uap) 2161100384Speter{ 2162100384Speter 2163156114Sps return (freebsd32_do_sendfile(td, uap, 0)); 2164100384Speter} 2165100384Speter 2166100384Speterstatic void 2167100384Spetercopy_stat( struct stat *in, struct stat32 *out) 2168100384Speter{ 2169100384Speter CP(*in, *out, st_dev); 2170100384Speter CP(*in, *out, st_ino); 2171100384Speter CP(*in, *out, st_mode); 2172100384Speter CP(*in, *out, st_nlink); 2173100384Speter CP(*in, *out, st_uid); 2174100384Speter CP(*in, *out, st_gid); 2175100384Speter CP(*in, *out, st_rdev); 2176100384Speter TS_CP(*in, *out, st_atimespec); 2177100384Speter TS_CP(*in, *out, st_mtimespec); 2178100384Speter TS_CP(*in, *out, st_ctimespec); 2179100384Speter CP(*in, *out, st_size); 2180100384Speter CP(*in, *out, st_blocks); 2181100384Speter CP(*in, *out, st_blksize); 2182100384Speter CP(*in, *out, st_flags); 2183100384Speter CP(*in, *out, st_gen); 2184100384Speter} 2185100384Speter 2186100384Speterint 2187119333Speterfreebsd32_stat(struct thread *td, struct freebsd32_stat_args *uap) 2188100384Speter{ 2189123746Speter struct stat sb; 2190123746Speter struct stat32 sb32; 2191100384Speter int error; 2192100384Speter 2193142059Sjhb error = kern_stat(td, uap->path, UIO_USERSPACE, &sb); 2194100384Speter if (error) 2195100384Speter return (error); 2196123746Speter copy_stat(&sb, &sb32); 2197123746Speter error = copyout(&sb32, uap->ub, sizeof (sb32)); 2198100384Speter return (error); 2199100384Speter} 2200100384Speter 2201100384Speterint 2202119333Speterfreebsd32_fstat(struct thread *td, struct freebsd32_fstat_args *uap) 2203100384Speter{ 2204123746Speter struct stat ub; 2205123746Speter struct stat32 ub32; 2206100384Speter int error; 2207100384Speter 2208142059Sjhb error = kern_fstat(td, uap->fd, &ub); 2209100384Speter if (error) 2210100384Speter return (error); 2211123746Speter copy_stat(&ub, &ub32); 2212123746Speter error = copyout(&ub32, uap->ub, sizeof(ub32)); 2213100384Speter return (error); 2214100384Speter} 2215100384Speter 2216100384Speterint 2217177789Skibfreebsd32_fstatat(struct thread *td, struct freebsd32_fstatat_args *uap) 2218177789Skib{ 2219177789Skib struct stat ub; 2220177789Skib struct stat32 ub32; 2221177789Skib int error; 2222177789Skib 2223177789Skib error = kern_statat(td, uap->flag, uap->fd, uap->path, UIO_USERSPACE, &ub); 2224177789Skib if (error) 2225177789Skib return (error); 2226177789Skib copy_stat(&ub, &ub32); 2227177789Skib error = copyout(&ub32, uap->buf, sizeof(ub32)); 2228177789Skib return (error); 2229177789Skib} 2230177789Skib 2231177789Skibint 2232119333Speterfreebsd32_lstat(struct thread *td, struct freebsd32_lstat_args *uap) 2233100384Speter{ 2234123746Speter struct stat sb; 2235123746Speter struct stat32 sb32; 2236142059Sjhb int error; 2237100384Speter 2238142059Sjhb error = kern_lstat(td, uap->path, UIO_USERSPACE, &sb); 2239100384Speter if (error) 2240100384Speter return (error); 2241123746Speter copy_stat(&sb, &sb32); 2242123746Speter error = copyout(&sb32, uap->ub, sizeof (sb32)); 2243100384Speter return (error); 2244100384Speter} 2245100384Speter 2246100384Speter/* 2247100384Speter * MPSAFE 2248100384Speter */ 2249100384Speterint 2250119333Speterfreebsd32_sysctl(struct thread *td, struct freebsd32_sysctl_args *uap) 2251100384Speter{ 2252100384Speter int error, name[CTL_MAXNAME]; 2253100384Speter size_t j, oldlen; 2254100384Speter 2255100384Speter if (uap->namelen > CTL_MAXNAME || uap->namelen < 2) 2256100384Speter return (EINVAL); 2257136404Speter error = copyin(uap->name, name, uap->namelen * sizeof(int)); 2258100384Speter if (error) 2259100384Speter return (error); 2260100384Speter if (uap->oldlenp) 2261100384Speter oldlen = fuword32(uap->oldlenp); 2262100384Speter else 2263100384Speter oldlen = 0; 2264100384Speter error = userland_sysctl(td, name, uap->namelen, 2265100384Speter uap->old, &oldlen, 1, 2266136404Speter uap->new, uap->newlen, &j, SCTL_MASK32); 2267100384Speter if (error && error != ENOMEM) 2268186564Sed return (error); 2269136404Speter if (uap->oldlenp) 2270100384Speter suword32(uap->oldlenp, j); 2271186564Sed return (0); 2272100384Speter} 2273100384Speter 2274100384Speterint 2275185435Sbzfreebsd32_jail(struct thread *td, struct freebsd32_jail_args *uap) 2276185435Sbz{ 2277185435Sbz uint32_t version; 2278185435Sbz int error; 2279192895Sjamie struct jail j; 2280185435Sbz 2281185435Sbz error = copyin(uap->jail, &version, sizeof(uint32_t)); 2282185435Sbz if (error) 2283185435Sbz return (error); 2284190466Sjamie 2285185435Sbz switch (version) { 2286190466Sjamie case 0: 2287185435Sbz { 2288185435Sbz /* FreeBSD single IPv4 jails. */ 2289185435Sbz struct jail32_v0 j32_v0; 2290185435Sbz 2291192895Sjamie bzero(&j, sizeof(struct jail)); 2292185435Sbz error = copyin(uap->jail, &j32_v0, sizeof(struct jail32_v0)); 2293185435Sbz if (error) 2294185435Sbz return (error); 2295192895Sjamie CP(j32_v0, j, version); 2296192895Sjamie PTRIN_CP(j32_v0, j, path); 2297192895Sjamie PTRIN_CP(j32_v0, j, hostname); 2298192895Sjamie j.ip4s = j32_v0.ip_number; 2299185435Sbz break; 2300185435Sbz } 2301185435Sbz 2302185435Sbz case 1: 2303185435Sbz /* 2304185435Sbz * Version 1 was used by multi-IPv4 jail implementations 2305185435Sbz * that never made it into the official kernel. 2306185435Sbz */ 2307185435Sbz return (EINVAL); 2308185435Sbz 2309185435Sbz case 2: /* JAIL_API_VERSION */ 2310185435Sbz { 2311185435Sbz /* FreeBSD multi-IPv4/IPv6,noIP jails. */ 2312185435Sbz struct jail32 j32; 2313185435Sbz 2314185435Sbz error = copyin(uap->jail, &j32, sizeof(struct jail32)); 2315185435Sbz if (error) 2316185435Sbz return (error); 2317192895Sjamie CP(j32, j, version); 2318192895Sjamie PTRIN_CP(j32, j, path); 2319192895Sjamie PTRIN_CP(j32, j, hostname); 2320192895Sjamie PTRIN_CP(j32, j, jailname); 2321192895Sjamie CP(j32, j, ip4s); 2322192895Sjamie CP(j32, j, ip6s); 2323192895Sjamie PTRIN_CP(j32, j, ip4); 2324192895Sjamie PTRIN_CP(j32, j, ip6); 2325185435Sbz break; 2326185435Sbz } 2327185435Sbz 2328185435Sbz default: 2329185435Sbz /* Sci-Fi jails are not supported, sorry. */ 2330185435Sbz return (EINVAL); 2331185435Sbz } 2332192895Sjamie return (kern_jail(td, &j)); 2333185435Sbz} 2334185435Sbz 2335185435Sbzint 2336191673Sjamiefreebsd32_jail_set(struct thread *td, struct freebsd32_jail_set_args *uap) 2337191673Sjamie{ 2338191673Sjamie struct uio *auio; 2339191673Sjamie int error; 2340191673Sjamie 2341191673Sjamie /* Check that we have an even number of iovecs. */ 2342191673Sjamie if (uap->iovcnt & 1) 2343191673Sjamie return (EINVAL); 2344191673Sjamie 2345191673Sjamie error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio); 2346191673Sjamie if (error) 2347191673Sjamie return (error); 2348191673Sjamie error = kern_jail_set(td, auio, uap->flags); 2349191673Sjamie free(auio, M_IOV); 2350191673Sjamie return (error); 2351191673Sjamie} 2352191673Sjamie 2353191673Sjamieint 2354191673Sjamiefreebsd32_jail_get(struct thread *td, struct freebsd32_jail_get_args *uap) 2355191673Sjamie{ 2356191673Sjamie struct iovec32 iov32; 2357191673Sjamie struct uio *auio; 2358191673Sjamie int error, i; 2359191673Sjamie 2360191673Sjamie /* Check that we have an even number of iovecs. */ 2361191673Sjamie if (uap->iovcnt & 1) 2362191673Sjamie return (EINVAL); 2363191673Sjamie 2364191673Sjamie error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio); 2365191673Sjamie if (error) 2366191673Sjamie return (error); 2367191673Sjamie error = kern_jail_get(td, auio, uap->flags); 2368191673Sjamie if (error == 0) 2369191673Sjamie for (i = 0; i < uap->iovcnt; i++) { 2370191673Sjamie PTROUT_CP(auio->uio_iov[i], iov32, iov_base); 2371191673Sjamie CP(auio->uio_iov[i], iov32, iov_len); 2372191673Sjamie error = copyout(&iov32, uap->iovp + i, sizeof(iov32)); 2373191673Sjamie if (error != 0) 2374191673Sjamie break; 2375191673Sjamie } 2376191673Sjamie free(auio, M_IOV); 2377191673Sjamie return (error); 2378191673Sjamie} 2379191673Sjamie 2380191673Sjamieint 2381119333Speterfreebsd32_sigaction(struct thread *td, struct freebsd32_sigaction_args *uap) 2382100384Speter{ 2383113859Sjhb struct sigaction32 s32; 2384113859Sjhb struct sigaction sa, osa, *sap; 2385100384Speter int error; 2386100384Speter 2387113859Sjhb if (uap->act) { 2388113859Sjhb error = copyin(uap->act, &s32, sizeof(s32)); 2389100384Speter if (error) 2390100384Speter return (error); 2391113859Sjhb sa.sa_handler = PTRIN(s32.sa_u); 2392113859Sjhb CP(s32, sa, sa_flags); 2393113859Sjhb CP(s32, sa, sa_mask); 2394113859Sjhb sap = &sa; 2395113859Sjhb } else 2396113859Sjhb sap = NULL; 2397113859Sjhb error = kern_sigaction(td, uap->sig, sap, &osa, 0); 2398146583Sps if (error == 0 && uap->oact != NULL) { 2399113859Sjhb s32.sa_u = PTROUT(osa.sa_handler); 2400113859Sjhb CP(osa, s32, sa_flags); 2401113859Sjhb CP(osa, s32, sa_mask); 2402113859Sjhb error = copyout(&s32, uap->oact, sizeof(s32)); 2403100384Speter } 2404100384Speter return (error); 2405100384Speter} 2406100384Speter 2407114987Speter#ifdef COMPAT_FREEBSD4 2408114987Speterint 2409119333Speterfreebsd4_freebsd32_sigaction(struct thread *td, 2410119333Speter struct freebsd4_freebsd32_sigaction_args *uap) 2411114987Speter{ 2412114987Speter struct sigaction32 s32; 2413114987Speter struct sigaction sa, osa, *sap; 2414114987Speter int error; 2415114987Speter 2416114987Speter if (uap->act) { 2417114987Speter error = copyin(uap->act, &s32, sizeof(s32)); 2418114987Speter if (error) 2419114987Speter return (error); 2420114987Speter sa.sa_handler = PTRIN(s32.sa_u); 2421114987Speter CP(s32, sa, sa_flags); 2422114987Speter CP(s32, sa, sa_mask); 2423114987Speter sap = &sa; 2424114987Speter } else 2425114987Speter sap = NULL; 2426114987Speter error = kern_sigaction(td, uap->sig, sap, &osa, KSA_FREEBSD4); 2427146583Sps if (error == 0 && uap->oact != NULL) { 2428114987Speter s32.sa_u = PTROUT(osa.sa_handler); 2429114987Speter CP(osa, s32, sa_flags); 2430114987Speter CP(osa, s32, sa_mask); 2431114987Speter error = copyout(&s32, uap->oact, sizeof(s32)); 2432114987Speter } 2433114987Speter return (error); 2434114987Speter} 2435114987Speter#endif 2436114987Speter 2437151582Sps#ifdef COMPAT_43 2438151720Speterstruct osigaction32 { 2439151582Sps u_int32_t sa_u; 2440151582Sps osigset_t sa_mask; 2441151582Sps int sa_flags; 2442151582Sps}; 2443151582Sps 2444151582Sps#define ONSIG 32 2445151582Sps 2446140481Spsint 2447151720Speterofreebsd32_sigaction(struct thread *td, 2448151720Speter struct ofreebsd32_sigaction_args *uap) 2449151582Sps{ 2450151720Speter struct osigaction32 s32; 2451151582Sps struct sigaction sa, osa, *sap; 2452151582Sps int error; 2453151582Sps 2454151582Sps if (uap->signum <= 0 || uap->signum >= ONSIG) 2455151582Sps return (EINVAL); 2456151582Sps 2457151582Sps if (uap->nsa) { 2458151582Sps error = copyin(uap->nsa, &s32, sizeof(s32)); 2459151582Sps if (error) 2460151582Sps return (error); 2461151582Sps sa.sa_handler = PTRIN(s32.sa_u); 2462151582Sps CP(s32, sa, sa_flags); 2463151582Sps OSIG2SIG(s32.sa_mask, sa.sa_mask); 2464151582Sps sap = &sa; 2465151582Sps } else 2466151582Sps sap = NULL; 2467151582Sps error = kern_sigaction(td, uap->signum, sap, &osa, KSA_OSIGSET); 2468151582Sps if (error == 0 && uap->osa != NULL) { 2469151582Sps s32.sa_u = PTROUT(osa.sa_handler); 2470151582Sps CP(osa, s32, sa_flags); 2471151582Sps SIG2OSIG(osa.sa_mask, s32.sa_mask); 2472151582Sps error = copyout(&s32, uap->osa, sizeof(s32)); 2473151582Sps } 2474151582Sps return (error); 2475151582Sps} 2476151582Sps 2477151582Spsint 2478151720Speterofreebsd32_sigprocmask(struct thread *td, 2479151720Speter struct ofreebsd32_sigprocmask_args *uap) 2480151582Sps{ 2481151582Sps sigset_t set, oset; 2482151582Sps int error; 2483151582Sps 2484151582Sps OSIG2SIG(uap->mask, set); 2485151582Sps error = kern_sigprocmask(td, uap->how, &set, &oset, 1); 2486151582Sps SIG2OSIG(oset, td->td_retval[0]); 2487151582Sps return (error); 2488151582Sps} 2489151582Sps 2490151582Spsint 2491151720Speterofreebsd32_sigpending(struct thread *td, 2492151720Speter struct ofreebsd32_sigpending_args *uap) 2493151582Sps{ 2494151582Sps struct proc *p = td->td_proc; 2495151582Sps sigset_t siglist; 2496151582Sps 2497151582Sps PROC_LOCK(p); 2498151582Sps siglist = p->p_siglist; 2499151582Sps SIGSETOR(siglist, td->td_siglist); 2500151582Sps PROC_UNLOCK(p); 2501151582Sps SIG2OSIG(siglist, td->td_retval[0]); 2502151582Sps return (0); 2503151582Sps} 2504151582Sps 2505151582Spsstruct sigvec32 { 2506151582Sps u_int32_t sv_handler; 2507151582Sps int sv_mask; 2508151582Sps int sv_flags; 2509151582Sps}; 2510151582Sps 2511151582Spsint 2512151720Speterofreebsd32_sigvec(struct thread *td, 2513151720Speter struct ofreebsd32_sigvec_args *uap) 2514151582Sps{ 2515151582Sps struct sigvec32 vec; 2516151582Sps struct sigaction sa, osa, *sap; 2517151582Sps int error; 2518151582Sps 2519151582Sps if (uap->signum <= 0 || uap->signum >= ONSIG) 2520151582Sps return (EINVAL); 2521151582Sps 2522151582Sps if (uap->nsv) { 2523151582Sps error = copyin(uap->nsv, &vec, sizeof(vec)); 2524151582Sps if (error) 2525151582Sps return (error); 2526151582Sps sa.sa_handler = PTRIN(vec.sv_handler); 2527151582Sps OSIG2SIG(vec.sv_mask, sa.sa_mask); 2528151582Sps sa.sa_flags = vec.sv_flags; 2529151582Sps sa.sa_flags ^= SA_RESTART; 2530151582Sps sap = &sa; 2531151582Sps } else 2532151582Sps sap = NULL; 2533151582Sps error = kern_sigaction(td, uap->signum, sap, &osa, KSA_OSIGSET); 2534151582Sps if (error == 0 && uap->osv != NULL) { 2535151582Sps vec.sv_handler = PTROUT(osa.sa_handler); 2536151582Sps SIG2OSIG(osa.sa_mask, vec.sv_mask); 2537151582Sps vec.sv_flags = osa.sa_flags; 2538151582Sps vec.sv_flags &= ~SA_NOCLDWAIT; 2539151582Sps vec.sv_flags ^= SA_RESTART; 2540151582Sps error = copyout(&vec, uap->osv, sizeof(vec)); 2541151582Sps } 2542151582Sps return (error); 2543151582Sps} 2544151582Sps 2545151582Spsint 2546151720Speterofreebsd32_sigblock(struct thread *td, 2547151720Speter struct ofreebsd32_sigblock_args *uap) 2548151582Sps{ 2549151582Sps struct proc *p = td->td_proc; 2550151582Sps sigset_t set; 2551151582Sps 2552151582Sps OSIG2SIG(uap->mask, set); 2553151582Sps SIG_CANTMASK(set); 2554151582Sps PROC_LOCK(p); 2555151582Sps SIG2OSIG(td->td_sigmask, td->td_retval[0]); 2556151582Sps SIGSETOR(td->td_sigmask, set); 2557151582Sps PROC_UNLOCK(p); 2558151582Sps return (0); 2559151582Sps} 2560151582Sps 2561151582Spsint 2562151720Speterofreebsd32_sigsetmask(struct thread *td, 2563151720Speter struct ofreebsd32_sigsetmask_args *uap) 2564151582Sps{ 2565151582Sps struct proc *p = td->td_proc; 2566151582Sps sigset_t set; 2567151582Sps 2568151582Sps OSIG2SIG(uap->mask, set); 2569151582Sps SIG_CANTMASK(set); 2570151582Sps PROC_LOCK(p); 2571151582Sps SIG2OSIG(td->td_sigmask, td->td_retval[0]); 2572151582Sps SIGSETLO(td->td_sigmask, set); 2573151582Sps signotify(td); 2574151582Sps PROC_UNLOCK(p); 2575151582Sps return (0); 2576151582Sps} 2577151582Sps 2578151582Spsint 2579151720Speterofreebsd32_sigsuspend(struct thread *td, 2580151720Speter struct ofreebsd32_sigsuspend_args *uap) 2581151582Sps{ 2582151582Sps struct proc *p = td->td_proc; 2583151582Sps sigset_t mask; 2584151582Sps 2585151582Sps PROC_LOCK(p); 2586151582Sps td->td_oldsigmask = td->td_sigmask; 2587151582Sps td->td_pflags |= TDP_OLDMASK; 2588151582Sps OSIG2SIG(uap->mask, mask); 2589151582Sps SIG_CANTMASK(mask); 2590151582Sps SIGSETLO(td->td_sigmask, mask); 2591151582Sps signotify(td); 2592151582Sps while (msleep(&p->p_sigacts, &p->p_mtx, PPAUSE|PCATCH, "opause", 0) == 0) 2593151582Sps /* void */; 2594151582Sps PROC_UNLOCK(p); 2595151582Sps /* always return EINTR rather than ERESTART... */ 2596151582Sps return (EINTR); 2597151582Sps} 2598151582Sps 2599151582Spsstruct sigstack32 { 2600151582Sps u_int32_t ss_sp; 2601151582Sps int ss_onstack; 2602151582Sps}; 2603151582Sps 2604151582Spsint 2605151720Speterofreebsd32_sigstack(struct thread *td, 2606151720Speter struct ofreebsd32_sigstack_args *uap) 2607151582Sps{ 2608151582Sps struct sigstack32 s32; 2609151582Sps struct sigstack nss, oss; 2610170870Smjacob int error = 0, unss; 2611151582Sps 2612151582Sps if (uap->nss != NULL) { 2613151582Sps error = copyin(uap->nss, &s32, sizeof(s32)); 2614151582Sps if (error) 2615151582Sps return (error); 2616151582Sps nss.ss_sp = PTRIN(s32.ss_sp); 2617151582Sps CP(s32, nss, ss_onstack); 2618170870Smjacob unss = 1; 2619170870Smjacob } else { 2620170870Smjacob unss = 0; 2621151582Sps } 2622151582Sps oss.ss_sp = td->td_sigstk.ss_sp; 2623151582Sps oss.ss_onstack = sigonstack(cpu_getstack(td)); 2624170870Smjacob if (unss) { 2625151582Sps td->td_sigstk.ss_sp = nss.ss_sp; 2626151582Sps td->td_sigstk.ss_size = 0; 2627170870Smjacob td->td_sigstk.ss_flags |= (nss.ss_onstack & SS_ONSTACK); 2628151582Sps td->td_pflags |= TDP_ALTSTACK; 2629151582Sps } 2630151582Sps if (uap->oss != NULL) { 2631151582Sps s32.ss_sp = PTROUT(oss.ss_sp); 2632151582Sps CP(oss, s32, ss_onstack); 2633151582Sps error = copyout(&s32, uap->oss, sizeof(s32)); 2634151582Sps } 2635151582Sps return (error); 2636151582Sps} 2637151582Sps#endif 2638151582Sps 2639151582Spsint 2640140481Spsfreebsd32_nanosleep(struct thread *td, struct freebsd32_nanosleep_args *uap) 2641140481Sps{ 2642140481Sps struct timespec32 rmt32, rqt32; 2643140481Sps struct timespec rmt, rqt; 2644140481Sps int error; 2645140481Sps 2646151355Sps error = copyin(uap->rqtp, &rqt32, sizeof(rqt32)); 2647140481Sps if (error) 2648140481Sps return (error); 2649140481Sps 2650140481Sps CP(rqt32, rqt, tv_sec); 2651140481Sps CP(rqt32, rqt, tv_nsec); 2652140481Sps 2653140481Sps if (uap->rmtp && 2654140481Sps !useracc((caddr_t)uap->rmtp, sizeof(rmt), VM_PROT_WRITE)) 2655140481Sps return (EFAULT); 2656140481Sps error = kern_nanosleep(td, &rqt, &rmt); 2657140481Sps if (error && uap->rmtp) { 2658140481Sps int error2; 2659140481Sps 2660140481Sps CP(rmt, rmt32, tv_sec); 2661140481Sps CP(rmt, rmt32, tv_nsec); 2662140481Sps 2663151355Sps error2 = copyout(&rmt32, uap->rmtp, sizeof(rmt32)); 2664140481Sps if (error2) 2665140481Sps error = error2; 2666140481Sps } 2667140481Sps return (error); 2668140481Sps} 2669140481Sps 2670151357Spsint 2671151357Spsfreebsd32_clock_gettime(struct thread *td, 2672151357Sps struct freebsd32_clock_gettime_args *uap) 2673151357Sps{ 2674151357Sps struct timespec ats; 2675151357Sps struct timespec32 ats32; 2676151357Sps int error; 2677151357Sps 2678151357Sps error = kern_clock_gettime(td, uap->clock_id, &ats); 2679151357Sps if (error == 0) { 2680151357Sps CP(ats, ats32, tv_sec); 2681151357Sps CP(ats, ats32, tv_nsec); 2682151357Sps error = copyout(&ats32, uap->tp, sizeof(ats32)); 2683151357Sps } 2684151357Sps return (error); 2685151357Sps} 2686151357Sps 2687151357Spsint 2688151357Spsfreebsd32_clock_settime(struct thread *td, 2689151357Sps struct freebsd32_clock_settime_args *uap) 2690151357Sps{ 2691151357Sps struct timespec ats; 2692151357Sps struct timespec32 ats32; 2693151357Sps int error; 2694151357Sps 2695151357Sps error = copyin(uap->tp, &ats32, sizeof(ats32)); 2696151357Sps if (error) 2697151357Sps return (error); 2698151357Sps CP(ats32, ats, tv_sec); 2699151357Sps CP(ats32, ats, tv_nsec); 2700151357Sps 2701151357Sps return (kern_clock_settime(td, uap->clock_id, &ats)); 2702151357Sps} 2703151357Sps 2704151357Spsint 2705151357Spsfreebsd32_clock_getres(struct thread *td, 2706151357Sps struct freebsd32_clock_getres_args *uap) 2707151357Sps{ 2708151357Sps struct timespec ts; 2709151357Sps struct timespec32 ts32; 2710151357Sps int error; 2711151357Sps 2712151357Sps if (uap->tp == NULL) 2713151357Sps return (0); 2714151357Sps error = kern_clock_getres(td, uap->clock_id, &ts); 2715151357Sps if (error == 0) { 2716151357Sps CP(ts, ts32, tv_sec); 2717151357Sps CP(ts, ts32, tv_nsec); 2718151357Sps error = copyout(&ts32, uap->tp, sizeof(ts32)); 2719151357Sps } 2720151357Sps return (error); 2721151357Sps} 2722151357Sps 2723162551Sdavidxuint 2724162551Sdavidxufreebsd32_thr_new(struct thread *td, 2725162551Sdavidxu struct freebsd32_thr_new_args *uap) 2726162551Sdavidxu{ 2727162551Sdavidxu struct thr_param32 param32; 2728162551Sdavidxu struct thr_param param; 2729162551Sdavidxu int error; 2730162551Sdavidxu 2731162551Sdavidxu if (uap->param_size < 0 || 2732162551Sdavidxu uap->param_size > sizeof(struct thr_param32)) 2733162551Sdavidxu return (EINVAL); 2734162551Sdavidxu bzero(¶m, sizeof(struct thr_param)); 2735162551Sdavidxu bzero(¶m32, sizeof(struct thr_param32)); 2736162551Sdavidxu error = copyin(uap->param, ¶m32, uap->param_size); 2737162551Sdavidxu if (error != 0) 2738162551Sdavidxu return (error); 2739162551Sdavidxu param.start_func = PTRIN(param32.start_func); 2740162551Sdavidxu param.arg = PTRIN(param32.arg); 2741162551Sdavidxu param.stack_base = PTRIN(param32.stack_base); 2742162551Sdavidxu param.stack_size = param32.stack_size; 2743162551Sdavidxu param.tls_base = PTRIN(param32.tls_base); 2744162551Sdavidxu param.tls_size = param32.tls_size; 2745162551Sdavidxu param.child_tid = PTRIN(param32.child_tid); 2746162551Sdavidxu param.parent_tid = PTRIN(param32.parent_tid); 2747162551Sdavidxu param.flags = param32.flags; 2748162551Sdavidxu param.rtp = PTRIN(param32.rtp); 2749162551Sdavidxu param.spare[0] = PTRIN(param32.spare[0]); 2750162551Sdavidxu param.spare[1] = PTRIN(param32.spare[1]); 2751162551Sdavidxu param.spare[2] = PTRIN(param32.spare[2]); 2752162551Sdavidxu 2753162551Sdavidxu return (kern_thr_new(td, ¶m)); 2754162551Sdavidxu} 2755162551Sdavidxu 2756162551Sdavidxuint 2757162551Sdavidxufreebsd32_thr_suspend(struct thread *td, struct freebsd32_thr_suspend_args *uap) 2758162551Sdavidxu{ 2759162551Sdavidxu struct timespec32 ts32; 2760162551Sdavidxu struct timespec ts, *tsp; 2761162551Sdavidxu int error; 2762162551Sdavidxu 2763162551Sdavidxu error = 0; 2764162551Sdavidxu tsp = NULL; 2765162551Sdavidxu if (uap->timeout != NULL) { 2766162551Sdavidxu error = copyin((const void *)uap->timeout, (void *)&ts32, 2767162551Sdavidxu sizeof(struct timespec32)); 2768162551Sdavidxu if (error != 0) 2769162551Sdavidxu return (error); 2770162551Sdavidxu ts.tv_sec = ts32.tv_sec; 2771162551Sdavidxu ts.tv_nsec = ts32.tv_nsec; 2772162551Sdavidxu tsp = &ts; 2773162551Sdavidxu } 2774162551Sdavidxu return (kern_thr_suspend(td, tsp)); 2775162551Sdavidxu} 2776162551Sdavidxu 2777163018Sdavidxuvoid 2778163018Sdavidxusiginfo_to_siginfo32(siginfo_t *src, struct siginfo32 *dst) 2779163018Sdavidxu{ 2780163018Sdavidxu bzero(dst, sizeof(*dst)); 2781163018Sdavidxu dst->si_signo = src->si_signo; 2782163018Sdavidxu dst->si_errno = src->si_errno; 2783163018Sdavidxu dst->si_code = src->si_code; 2784163018Sdavidxu dst->si_pid = src->si_pid; 2785163018Sdavidxu dst->si_uid = src->si_uid; 2786163018Sdavidxu dst->si_status = src->si_status; 2787184829Speter dst->si_addr = (uintptr_t)src->si_addr; 2788163018Sdavidxu dst->si_value.sigval_int = src->si_value.sival_int; 2789163018Sdavidxu dst->si_timerid = src->si_timerid; 2790163018Sdavidxu dst->si_overrun = src->si_overrun; 2791163018Sdavidxu} 2792163018Sdavidxu 2793163018Sdavidxuint 2794163018Sdavidxufreebsd32_sigtimedwait(struct thread *td, struct freebsd32_sigtimedwait_args *uap) 2795163018Sdavidxu{ 2796163018Sdavidxu struct timespec32 ts32; 2797163018Sdavidxu struct timespec ts; 2798163018Sdavidxu struct timespec *timeout; 2799163018Sdavidxu sigset_t set; 2800163018Sdavidxu ksiginfo_t ksi; 2801163018Sdavidxu struct siginfo32 si32; 2802163018Sdavidxu int error; 2803163018Sdavidxu 2804163018Sdavidxu if (uap->timeout) { 2805163018Sdavidxu error = copyin(uap->timeout, &ts32, sizeof(ts32)); 2806163018Sdavidxu if (error) 2807163018Sdavidxu return (error); 2808163018Sdavidxu ts.tv_sec = ts32.tv_sec; 2809163018Sdavidxu ts.tv_nsec = ts32.tv_nsec; 2810163018Sdavidxu timeout = &ts; 2811163018Sdavidxu } else 2812163018Sdavidxu timeout = NULL; 2813163018Sdavidxu 2814163018Sdavidxu error = copyin(uap->set, &set, sizeof(set)); 2815163018Sdavidxu if (error) 2816163018Sdavidxu return (error); 2817163018Sdavidxu 2818163018Sdavidxu error = kern_sigtimedwait(td, set, &ksi, timeout); 2819163018Sdavidxu if (error) 2820163018Sdavidxu return (error); 2821163018Sdavidxu 2822163018Sdavidxu if (uap->info) { 2823163018Sdavidxu siginfo_to_siginfo32(&ksi.ksi_info, &si32); 2824163018Sdavidxu error = copyout(&si32, uap->info, sizeof(struct siginfo32)); 2825163018Sdavidxu } 2826163018Sdavidxu 2827163018Sdavidxu if (error == 0) 2828163018Sdavidxu td->td_retval[0] = ksi.ksi_signo; 2829163018Sdavidxu return (error); 2830163018Sdavidxu} 2831163018Sdavidxu 2832163018Sdavidxu/* 2833163018Sdavidxu * MPSAFE 2834163018Sdavidxu */ 2835163018Sdavidxuint 2836163018Sdavidxufreebsd32_sigwaitinfo(struct thread *td, struct freebsd32_sigwaitinfo_args *uap) 2837163018Sdavidxu{ 2838163018Sdavidxu ksiginfo_t ksi; 2839163018Sdavidxu struct siginfo32 si32; 2840163018Sdavidxu sigset_t set; 2841163018Sdavidxu int error; 2842163018Sdavidxu 2843163018Sdavidxu error = copyin(uap->set, &set, sizeof(set)); 2844163018Sdavidxu if (error) 2845163018Sdavidxu return (error); 2846163018Sdavidxu 2847163018Sdavidxu error = kern_sigtimedwait(td, set, &ksi, NULL); 2848163018Sdavidxu if (error) 2849163018Sdavidxu return (error); 2850163018Sdavidxu 2851163018Sdavidxu if (uap->info) { 2852163018Sdavidxu siginfo_to_siginfo32(&ksi.ksi_info, &si32); 2853163018Sdavidxu error = copyout(&si32, uap->info, sizeof(struct siginfo32)); 2854163018Sdavidxu } 2855163018Sdavidxu if (error == 0) 2856163018Sdavidxu td->td_retval[0] = ksi.ksi_signo; 2857163018Sdavidxu return (error); 2858163018Sdavidxu} 2859163018Sdavidxu 2860180433Sbrooksint 2861180433Sbrooksfreebsd32_cpuset_setid(struct thread *td, 2862180433Sbrooks struct freebsd32_cpuset_setid_args *uap) 2863180433Sbrooks{ 2864180433Sbrooks struct cpuset_setid_args ap; 2865180433Sbrooks 2866180433Sbrooks ap.which = uap->which; 2867180433Sbrooks ap.id = (uap->idlo | ((id_t)uap->idhi << 32)); 2868180433Sbrooks ap.setid = uap->setid; 2869180433Sbrooks 2870180436Sbrooks return (cpuset_setid(td, &ap)); 2871180433Sbrooks} 2872180433Sbrooks 2873180433Sbrooksint 2874180433Sbrooksfreebsd32_cpuset_getid(struct thread *td, 2875180433Sbrooks struct freebsd32_cpuset_getid_args *uap) 2876180433Sbrooks{ 2877180433Sbrooks struct cpuset_getid_args ap; 2878180433Sbrooks 2879180433Sbrooks ap.level = uap->level; 2880180433Sbrooks ap.which = uap->which; 2881180433Sbrooks ap.id = (uap->idlo | ((id_t)uap->idhi << 32)); 2882180433Sbrooks ap.setid = uap->setid; 2883180433Sbrooks 2884180436Sbrooks return (cpuset_getid(td, &ap)); 2885180433Sbrooks} 2886180433Sbrooks 2887180433Sbrooksint 2888180433Sbrooksfreebsd32_cpuset_getaffinity(struct thread *td, 2889180433Sbrooks struct freebsd32_cpuset_getaffinity_args *uap) 2890180433Sbrooks{ 2891180433Sbrooks struct cpuset_getaffinity_args ap; 2892180433Sbrooks 2893180433Sbrooks ap.level = uap->level; 2894180433Sbrooks ap.which = uap->which; 2895180433Sbrooks ap.id = (uap->idlo | ((id_t)uap->idhi << 32)); 2896180433Sbrooks ap.cpusetsize = uap->cpusetsize; 2897180433Sbrooks ap.mask = uap->mask; 2898180433Sbrooks 2899180436Sbrooks return (cpuset_getaffinity(td, &ap)); 2900180433Sbrooks} 2901180433Sbrooks 2902180433Sbrooksint 2903180433Sbrooksfreebsd32_cpuset_setaffinity(struct thread *td, 2904180433Sbrooks struct freebsd32_cpuset_setaffinity_args *uap) 2905180433Sbrooks{ 2906180433Sbrooks struct cpuset_setaffinity_args ap; 2907180433Sbrooks 2908180433Sbrooks ap.level = uap->level; 2909180433Sbrooks ap.which = uap->which; 2910180433Sbrooks ap.id = (uap->idlo | ((id_t)uap->idhi << 32)); 2911180433Sbrooks ap.cpusetsize = uap->cpusetsize; 2912180433Sbrooks ap.mask = uap->mask; 2913180433Sbrooks 2914180436Sbrooks return (cpuset_setaffinity(td, &ap)); 2915180433Sbrooks} 2916180433Sbrooks 2917183188Sobrienint 2918183188Sobrienfreebsd32_nmount(struct thread *td, 2919183188Sobrien struct freebsd32_nmount_args /* { 2920183188Sobrien struct iovec *iovp; 2921183188Sobrien unsigned int iovcnt; 2922183188Sobrien int flags; 2923183188Sobrien } */ *uap) 2924183188Sobrien{ 2925183188Sobrien struct uio *auio; 2926189290Sjamie int error; 2927183188Sobrien 2928195104Srwatson AUDIT_ARG_FFLAGS(uap->flags); 2929183188Sobrien 2930183188Sobrien /* 2931183188Sobrien * Filter out MNT_ROOTFS. We do not want clients of nmount() in 2932183188Sobrien * userspace to set this flag, but we must filter it out if we want 2933183188Sobrien * MNT_UPDATE on the root file system to work. 2934183188Sobrien * MNT_ROOTFS should only be set in the kernel in vfs_mountroot_try(). 2935183188Sobrien */ 2936183188Sobrien uap->flags &= ~MNT_ROOTFS; 2937183188Sobrien 2938183188Sobrien /* 2939183188Sobrien * check that we have an even number of iovec's 2940183188Sobrien * and that we have at least two options. 2941183188Sobrien */ 2942183188Sobrien if ((uap->iovcnt & 1) || (uap->iovcnt < 4)) 2943183188Sobrien return (EINVAL); 2944183188Sobrien 2945183188Sobrien error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio); 2946183188Sobrien if (error) 2947183188Sobrien return (error); 2948189290Sjamie error = vfs_donmount(td, uap->flags, auio); 2949183188Sobrien 2950183188Sobrien free(auio, M_IOV); 2951183188Sobrien return error; 2952183188Sobrien} 2953183188Sobrien 2954100384Speter#if 0 2955100384Speterint 2956119333Speterfreebsd32_xxx(struct thread *td, struct freebsd32_xxx_args *uap) 2957100384Speter{ 2958100384Speter struct yyy32 *p32, s32; 2959100384Speter struct yyy *p = NULL, s; 2960183044Sobrien struct xxx_arg ap; 2961183044Sobrien int error; 2962100384Speter 2963147654Sjhb if (uap->zzz) { 2964147654Sjhb error = copyin(uap->zzz, &s32, sizeof(s32)); 2965100384Speter if (error) 2966100384Speter return (error); 2967100384Speter /* translate in */ 2968147654Sjhb p = &s; 2969100384Speter } 2970147654Sjhb error = kern_xxx(td, p); 2971100384Speter if (error) 2972100384Speter return (error); 2973147654Sjhb if (uap->zzz) { 2974100384Speter /* translate out */ 2975100384Speter error = copyout(&s32, p32, sizeof(s32)); 2976100384Speter } 2977100384Speter return (error); 2978100384Speter} 2979100384Speter#endif 2980183365Sjhb 2981183365Sjhbint 2982183365Sjhbsyscall32_register(int *offset, struct sysent *new_sysent, 2983183365Sjhb struct sysent *old_sysent) 2984183365Sjhb{ 2985183365Sjhb if (*offset == NO_SYSCALL) { 2986183365Sjhb int i; 2987183365Sjhb 2988183365Sjhb for (i = 1; i < SYS_MAXSYSCALL; ++i) 2989183365Sjhb if (freebsd32_sysent[i].sy_call == 2990183365Sjhb (sy_call_t *)lkmnosys) 2991183365Sjhb break; 2992183365Sjhb if (i == SYS_MAXSYSCALL) 2993183365Sjhb return (ENFILE); 2994183365Sjhb *offset = i; 2995183365Sjhb } else if (*offset < 0 || *offset >= SYS_MAXSYSCALL) 2996183365Sjhb return (EINVAL); 2997183365Sjhb else if (freebsd32_sysent[*offset].sy_call != (sy_call_t *)lkmnosys && 2998183365Sjhb freebsd32_sysent[*offset].sy_call != (sy_call_t *)lkmressys) 2999183365Sjhb return (EEXIST); 3000183365Sjhb 3001183365Sjhb *old_sysent = freebsd32_sysent[*offset]; 3002183365Sjhb freebsd32_sysent[*offset] = *new_sysent; 3003183365Sjhb return 0; 3004183365Sjhb} 3005183365Sjhb 3006183365Sjhbint 3007183365Sjhbsyscall32_deregister(int *offset, struct sysent *old_sysent) 3008183365Sjhb{ 3009183365Sjhb 3010183365Sjhb if (*offset) 3011183365Sjhb freebsd32_sysent[*offset] = *old_sysent; 3012183365Sjhb return 0; 3013183365Sjhb} 3014183365Sjhb 3015183365Sjhbint 3016183365Sjhbsyscall32_module_handler(struct module *mod, int what, void *arg) 3017183365Sjhb{ 3018183365Sjhb struct syscall_module_data *data = (struct syscall_module_data*)arg; 3019183365Sjhb modspecific_t ms; 3020183365Sjhb int error; 3021183365Sjhb 3022183365Sjhb switch (what) { 3023183365Sjhb case MOD_LOAD: 3024183365Sjhb error = syscall32_register(data->offset, data->new_sysent, 3025183365Sjhb &data->old_sysent); 3026183365Sjhb if (error) { 3027183365Sjhb /* Leave a mark so we know to safely unload below. */ 3028183365Sjhb data->offset = NULL; 3029183365Sjhb return error; 3030183365Sjhb } 3031183365Sjhb ms.intval = *data->offset; 3032183365Sjhb MOD_XLOCK; 3033183365Sjhb module_setspecific(mod, &ms); 3034183365Sjhb MOD_XUNLOCK; 3035183365Sjhb if (data->chainevh) 3036183365Sjhb error = data->chainevh(mod, what, data->chainarg); 3037183365Sjhb return (error); 3038183365Sjhb case MOD_UNLOAD: 3039183365Sjhb /* 3040183365Sjhb * MOD_LOAD failed, so just return without calling the 3041183365Sjhb * chained handler since we didn't pass along the MOD_LOAD 3042183365Sjhb * event. 3043183365Sjhb */ 3044183365Sjhb if (data->offset == NULL) 3045183365Sjhb return (0); 3046183365Sjhb if (data->chainevh) { 3047183365Sjhb error = data->chainevh(mod, what, data->chainarg); 3048183365Sjhb if (error) 3049183365Sjhb return (error); 3050183365Sjhb } 3051185589Sjhb error = syscall32_deregister(data->offset, &data->old_sysent); 3052183365Sjhb return (error); 3053183365Sjhb default: 3054183365Sjhb error = EOPNOTSUPP; 3055183365Sjhb if (data->chainevh) 3056183365Sjhb error = data->chainevh(mod, what, data->chainarg); 3057183365Sjhb return (error); 3058183365Sjhb } 3059183365Sjhb} 3060