freebsd32_misc.c revision 146583
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 146583 2005-05-24 17:52:14Z ps $"); 29118031Sobrien 30104738Speter#include "opt_compat.h" 31104738Speter 32100384Speter#include <sys/param.h> 33100384Speter#include <sys/systm.h> 34100384Speter#include <sys/bus.h> 35100384Speter#include <sys/exec.h> 36100384Speter#include <sys/fcntl.h> 37100384Speter#include <sys/filedesc.h> 38123746Speter#include <sys/namei.h> 39100384Speter#include <sys/imgact.h> 40100384Speter#include <sys/kernel.h> 41100384Speter#include <sys/lock.h> 42100384Speter#include <sys/malloc.h> 43100384Speter#include <sys/file.h> /* Must come after sys/malloc.h */ 44100384Speter#include <sys/mman.h> 45100384Speter#include <sys/module.h> 46100384Speter#include <sys/mount.h> 47100384Speter#include <sys/mutex.h> 48100384Speter#include <sys/namei.h> 49100384Speter#include <sys/param.h> 50100384Speter#include <sys/proc.h> 51100384Speter#include <sys/reboot.h> 52100384Speter#include <sys/resource.h> 53100384Speter#include <sys/resourcevar.h> 54100384Speter#include <sys/selinfo.h> 55100384Speter#include <sys/pipe.h> /* Must come after sys/selinfo.h */ 56100384Speter#include <sys/signal.h> 57100384Speter#include <sys/signalvar.h> 58100384Speter#include <sys/socket.h> 59100384Speter#include <sys/socketvar.h> 60100384Speter#include <sys/stat.h> 61113859Sjhb#include <sys/syscallsubr.h> 62100384Speter#include <sys/sysctl.h> 63100384Speter#include <sys/sysent.h> 64100384Speter#include <sys/sysproto.h> 65100384Speter#include <sys/systm.h> 66100384Speter#include <sys/unistd.h> 67100384Speter#include <sys/vnode.h> 68127140Sjhb#include <sys/wait.h> 69100384Speter 70100384Speter#include <vm/vm.h> 71100384Speter#include <vm/vm_kern.h> 72100384Speter#include <vm/vm_param.h> 73100384Speter#include <vm/pmap.h> 74100384Speter#include <vm/vm_map.h> 75100384Speter#include <vm/vm_object.h> 76100384Speter#include <vm/vm_extern.h> 77100384Speter 78119333Speter#include <compat/freebsd32/freebsd32_util.h> 79119333Speter#include <compat/freebsd32/freebsd32.h> 80119333Speter#include <compat/freebsd32/freebsd32_proto.h> 81100384Speter 82121719SpeterCTASSERT(sizeof(struct timeval32) == 8); 83121719SpeterCTASSERT(sizeof(struct timespec32) == 8); 84121719SpeterCTASSERT(sizeof(struct statfs32) == 256); 85121719SpeterCTASSERT(sizeof(struct rusage32) == 72); 86121719Speter 87100384Speterint 88119333Speterfreebsd32_wait4(struct thread *td, struct freebsd32_wait4_args *uap) 89100384Speter{ 90127140Sjhb int error, status; 91127140Sjhb struct rusage32 ru32; 92136152Sjhb struct rusage ru, *rup; 93100384Speter 94136152Sjhb if (uap->rusage != NULL) 95136152Sjhb rup = &ru; 96136152Sjhb else 97136152Sjhb rup = NULL; 98136152Sjhb error = kern_wait(td, uap->pid, &status, uap->options, rup); 99100384Speter if (error) 100100384Speter return (error); 101127140Sjhb if (uap->status != NULL) 102127140Sjhb error = copyout(&status, uap->status, sizeof(status)); 103127140Sjhb if (uap->rusage != NULL && error == 0) { 104100384Speter TV_CP(ru, ru32, ru_utime); 105100384Speter TV_CP(ru, ru32, ru_stime); 106100384Speter CP(ru, ru32, ru_maxrss); 107100384Speter CP(ru, ru32, ru_ixrss); 108100384Speter CP(ru, ru32, ru_idrss); 109100384Speter CP(ru, ru32, ru_isrss); 110100384Speter CP(ru, ru32, ru_minflt); 111100384Speter CP(ru, ru32, ru_majflt); 112100384Speter CP(ru, ru32, ru_nswap); 113100384Speter CP(ru, ru32, ru_inblock); 114100384Speter CP(ru, ru32, ru_oublock); 115100384Speter CP(ru, ru32, ru_msgsnd); 116100384Speter CP(ru, ru32, ru_msgrcv); 117100384Speter CP(ru, ru32, ru_nsignals); 118100384Speter CP(ru, ru32, ru_nvcsw); 119100384Speter CP(ru, ru32, ru_nivcsw); 120127140Sjhb error = copyout(&ru32, uap->rusage, sizeof(ru32)); 121100384Speter } 122100384Speter return (error); 123100384Speter} 124100384Speter 125128597Smarcel#ifdef COMPAT_FREEBSD4 126100384Speterstatic void 127100384Spetercopy_statfs(struct statfs *in, struct statfs32 *out) 128100384Speter{ 129100384Speter CP(*in, *out, f_bsize); 130100384Speter CP(*in, *out, f_iosize); 131100384Speter CP(*in, *out, f_blocks); 132100384Speter CP(*in, *out, f_bfree); 133100384Speter CP(*in, *out, f_bavail); 134100384Speter CP(*in, *out, f_files); 135100384Speter CP(*in, *out, f_ffree); 136100384Speter CP(*in, *out, f_fsid); 137100384Speter CP(*in, *out, f_owner); 138100384Speter CP(*in, *out, f_type); 139100384Speter CP(*in, *out, f_flags); 140100384Speter CP(*in, *out, f_flags); 141100384Speter CP(*in, *out, f_syncwrites); 142100384Speter CP(*in, *out, f_asyncwrites); 143100384Speter bcopy(in->f_fstypename, 144100384Speter out->f_fstypename, MFSNAMELEN); 145100384Speter bcopy(in->f_mntonname, 146128260Speter out->f_mntonname, min(MNAMELEN, FREEBSD4_MNAMELEN)); 147100384Speter CP(*in, *out, f_syncreads); 148100384Speter CP(*in, *out, f_asyncreads); 149100384Speter bcopy(in->f_mntfromname, 150128260Speter out->f_mntfromname, min(MNAMELEN, FREEBSD4_MNAMELEN)); 151100384Speter} 152128597Smarcel#endif 153100384Speter 154128597Smarcel#ifdef COMPAT_FREEBSD4 155100384Speterint 156128260Speterfreebsd4_freebsd32_getfsstat(struct thread *td, struct freebsd4_freebsd32_getfsstat_args *uap) 157100384Speter{ 158100384Speter int error; 159100384Speter caddr_t sg; 160100384Speter struct statfs32 *sp32, stat32; 161100384Speter struct statfs *sp = NULL, stat; 162100384Speter int maxcount, count, i; 163100384Speter 164107849Salfred sp32 = uap->buf; 165107849Salfred maxcount = uap->bufsize / sizeof(struct statfs32); 166100384Speter 167100384Speter if (sp32) { 168100384Speter sg = stackgap_init(); 169100384Speter sp = stackgap_alloc(&sg, sizeof(struct statfs) * maxcount); 170107849Salfred uap->buf = (struct statfs32 *)sp; 171100384Speter } 172100384Speter error = getfsstat(td, (struct getfsstat_args *) uap); 173100384Speter if (sp32 && !error) { 174100384Speter count = td->td_retval[0]; 175100384Speter for (i = 0; i < count; i++) { 176100384Speter error = copyin(&sp[i], &stat, sizeof(stat)); 177100384Speter if (error) 178100384Speter return (error); 179100384Speter copy_statfs(&stat, &stat32); 180100384Speter error = copyout(&stat32, &sp32[i], sizeof(stat32)); 181100384Speter if (error) 182100384Speter return (error); 183100384Speter } 184100384Speter } 185100384Speter return (error); 186100384Speter} 187128597Smarcel#endif 188100384Speter 189100384Speterstruct sigaltstack32 { 190100384Speter u_int32_t ss_sp; 191100384Speter u_int32_t ss_size; 192100384Speter int ss_flags; 193100384Speter}; 194100384Speter 195121719SpeterCTASSERT(sizeof(struct sigaltstack32) == 12); 196121719Speter 197100384Speterint 198119333Speterfreebsd32_sigaltstack(struct thread *td, 199119333Speter struct freebsd32_sigaltstack_args *uap) 200100384Speter{ 201113859Sjhb struct sigaltstack32 s32; 202113859Sjhb struct sigaltstack ss, oss, *ssp; 203100384Speter int error; 204100384Speter 205113859Sjhb if (uap->ss != NULL) { 206113859Sjhb error = copyin(uap->ss, &s32, sizeof(s32)); 207100384Speter if (error) 208100384Speter return (error); 209113859Sjhb PTRIN_CP(s32, ss, ss_sp); 210113859Sjhb CP(s32, ss, ss_size); 211113859Sjhb CP(s32, ss, ss_flags); 212113859Sjhb ssp = &ss; 213113859Sjhb } else 214113859Sjhb ssp = NULL; 215113859Sjhb error = kern_sigaltstack(td, ssp, &oss); 216113859Sjhb if (error == 0 && uap->oss != NULL) { 217113859Sjhb PTROUT_CP(oss, s32, ss_sp); 218113859Sjhb CP(oss, s32, ss_size); 219113859Sjhb CP(oss, s32, ss_flags); 220113859Sjhb error = copyout(&s32, uap->oss, sizeof(s32)); 221100384Speter } 222100384Speter return (error); 223100384Speter} 224100384Speter 225142059Sjhb/* 226142059Sjhb * Custom version of exec_copyin_args() so that we can translate 227142059Sjhb * the pointers. 228142059Sjhb */ 229142059Sjhbstatic int 230142059Sjhbfreebsd32_exec_copyin_args(struct image_args *args, char *fname, 231142059Sjhb enum uio_seg segflg, u_int32_t *argv, u_int32_t *envv) 232100384Speter{ 233142059Sjhb char *argp, *envp; 234142059Sjhb u_int32_t *p32, arg; 235142059Sjhb size_t length; 236100384Speter int error; 237100384Speter 238142059Sjhb bzero(args, sizeof(*args)); 239142059Sjhb if (argv == NULL) 240142059Sjhb return (EFAULT); 241100384Speter 242142059Sjhb /* 243142059Sjhb * Allocate temporary demand zeroed space for argument and 244142059Sjhb * environment strings 245142059Sjhb */ 246142059Sjhb args->buf = (char *) kmem_alloc_wait(exec_map, PATH_MAX + ARG_MAX); 247142059Sjhb if (args->buf == NULL) 248142059Sjhb return (ENOMEM); 249142059Sjhb args->begin_argv = args->buf; 250142059Sjhb args->endp = args->begin_argv; 251142059Sjhb args->stringspace = ARG_MAX; 252142059Sjhb 253142059Sjhb args->fname = args->buf + ARG_MAX; 254142059Sjhb 255142059Sjhb /* 256142059Sjhb * Copy the file name. 257142059Sjhb */ 258142059Sjhb error = (segflg == UIO_SYSSPACE) ? 259142059Sjhb copystr(fname, args->fname, PATH_MAX, &length) : 260142059Sjhb copyinstr(fname, args->fname, PATH_MAX, &length); 261142059Sjhb if (error != 0) 262142059Sjhb return (error); 263142059Sjhb 264142059Sjhb /* 265142059Sjhb * extract arguments first 266142059Sjhb */ 267142059Sjhb p32 = argv; 268142059Sjhb for (;;) { 269142059Sjhb error = copyin(p32++, &arg, sizeof(arg)); 270142059Sjhb if (error) 271142059Sjhb return (error); 272142059Sjhb if (arg == 0) 273142059Sjhb break; 274142059Sjhb argp = PTRIN(arg); 275142059Sjhb error = copyinstr(argp, args->endp, args->stringspace, &length); 276142059Sjhb if (error) { 277142059Sjhb if (error == ENAMETOOLONG) 278142059Sjhb return (E2BIG); 279142059Sjhb else 280142059Sjhb return (error); 281142059Sjhb } 282142059Sjhb args->stringspace -= length; 283142059Sjhb args->endp += length; 284142059Sjhb args->argc++; 285100384Speter } 286142059Sjhb 287142059Sjhb args->begin_envv = args->endp; 288142059Sjhb 289142059Sjhb /* 290142059Sjhb * extract environment strings 291142059Sjhb */ 292142059Sjhb if (envv) { 293142059Sjhb p32 = envv; 294142059Sjhb for (;;) { 295100384Speter error = copyin(p32++, &arg, sizeof(arg)); 296100384Speter if (error) 297142059Sjhb return (error); 298142059Sjhb if (arg == 0) 299142059Sjhb break; 300142059Sjhb envp = PTRIN(arg); 301142059Sjhb error = copyinstr(envp, args->endp, args->stringspace, 302142059Sjhb &length); 303142059Sjhb if (error) { 304142059Sjhb if (error == ENAMETOOLONG) 305142059Sjhb return (E2BIG); 306142059Sjhb else 307142059Sjhb return (error); 308142059Sjhb } 309142059Sjhb args->stringspace -= length; 310142059Sjhb args->endp += length; 311142059Sjhb args->envc++; 312142059Sjhb } 313100384Speter } 314100384Speter 315142059Sjhb return (0); 316100384Speter} 317100384Speter 318142059Sjhbint 319142059Sjhbfreebsd32_execve(struct thread *td, struct freebsd32_execve_args *uap) 320142059Sjhb{ 321142059Sjhb struct image_args eargs; 322142059Sjhb int error; 323142059Sjhb 324142059Sjhb error = freebsd32_exec_copyin_args(&eargs, uap->fname, UIO_USERSPACE, 325142059Sjhb uap->argv, uap->envv); 326142059Sjhb if (error == 0) 327142059Sjhb error = kern_execve(td, &eargs, NULL); 328142059Sjhb exec_free_args(&eargs); 329142059Sjhb return (error); 330142059Sjhb} 331142059Sjhb 332114987Speter#ifdef __ia64__ 333100384Speterstatic int 334119333Speterfreebsd32_mmap_partial(struct thread *td, vm_offset_t start, vm_offset_t end, 335119333Speter int prot, int fd, off_t pos) 336100384Speter{ 337100384Speter vm_map_t map; 338100384Speter vm_map_entry_t entry; 339100384Speter int rv; 340100384Speter 341100384Speter map = &td->td_proc->p_vmspace->vm_map; 342100384Speter if (fd != -1) 343100384Speter prot |= VM_PROT_WRITE; 344100384Speter 345100384Speter if (vm_map_lookup_entry(map, start, &entry)) { 346100384Speter if ((entry->protection & prot) != prot) { 347100384Speter rv = vm_map_protect(map, 348100384Speter trunc_page(start), 349100384Speter round_page(end), 350100384Speter entry->protection | prot, 351100384Speter FALSE); 352100384Speter if (rv != KERN_SUCCESS) 353100384Speter return (EINVAL); 354100384Speter } 355100384Speter } else { 356100384Speter vm_offset_t addr = trunc_page(start); 357100384Speter rv = vm_map_find(map, 0, 0, 358100384Speter &addr, PAGE_SIZE, FALSE, prot, 359100384Speter VM_PROT_ALL, 0); 360100384Speter if (rv != KERN_SUCCESS) 361100384Speter return (EINVAL); 362100384Speter } 363100384Speter 364100384Speter if (fd != -1) { 365100384Speter struct pread_args r; 366107849Salfred r.fd = fd; 367107849Salfred r.buf = (void *) start; 368107849Salfred r.nbyte = end - start; 369107849Salfred r.offset = pos; 370100384Speter return (pread(td, &r)); 371100384Speter } else { 372100384Speter while (start < end) { 373100384Speter subyte((void *) start, 0); 374100384Speter start++; 375100384Speter } 376100384Speter return (0); 377100384Speter } 378100384Speter} 379114987Speter#endif 380100384Speter 381100384Speterint 382119333Speterfreebsd32_mmap(struct thread *td, struct freebsd32_mmap_args *uap) 383100384Speter{ 384100384Speter struct mmap_args ap; 385107849Salfred vm_offset_t addr = (vm_offset_t) uap->addr; 386107849Salfred vm_size_t len = uap->len; 387107849Salfred int prot = uap->prot; 388107849Salfred int flags = uap->flags; 389107849Salfred int fd = uap->fd; 390107849Salfred off_t pos = (uap->poslo 391107849Salfred | ((off_t)uap->poshi << 32)); 392114987Speter#ifdef __ia64__ 393100384Speter vm_size_t pageoff; 394100384Speter int error; 395100384Speter 396100384Speter /* 397100384Speter * Attempt to handle page size hassles. 398100384Speter */ 399100384Speter pageoff = (pos & PAGE_MASK); 400100384Speter if (flags & MAP_FIXED) { 401100384Speter vm_offset_t start, end; 402100384Speter start = addr; 403100384Speter end = addr + len; 404100384Speter 405100384Speter if (start != trunc_page(start)) { 406119333Speter error = freebsd32_mmap_partial(td, start, 407119333Speter round_page(start), prot, 408119333Speter fd, pos); 409100384Speter if (fd != -1) 410100384Speter pos += round_page(start) - start; 411100384Speter start = round_page(start); 412100384Speter } 413100384Speter if (end != round_page(end)) { 414100384Speter vm_offset_t t = trunc_page(end); 415119333Speter error = freebsd32_mmap_partial(td, t, end, 416100384Speter prot, fd, 417100384Speter pos + t - start); 418100384Speter end = trunc_page(end); 419100384Speter } 420100384Speter if (end > start && fd != -1 && (pos & PAGE_MASK)) { 421100384Speter /* 422100384Speter * We can't map this region at all. The specified 423100384Speter * address doesn't have the same alignment as the file 424100384Speter * position. Fake the mapping by simply reading the 425100384Speter * entire region into memory. First we need to make 426100384Speter * sure the region exists. 427100384Speter */ 428100384Speter vm_map_t map; 429100384Speter struct pread_args r; 430100384Speter int rv; 431100384Speter 432100384Speter prot |= VM_PROT_WRITE; 433100384Speter map = &td->td_proc->p_vmspace->vm_map; 434100384Speter rv = vm_map_remove(map, start, end); 435100384Speter if (rv != KERN_SUCCESS) 436100384Speter return (EINVAL); 437100384Speter rv = vm_map_find(map, 0, 0, 438100384Speter &start, end - start, FALSE, 439100384Speter prot, VM_PROT_ALL, 0); 440100384Speter if (rv != KERN_SUCCESS) 441100384Speter return (EINVAL); 442107849Salfred r.fd = fd; 443107849Salfred r.buf = (void *) start; 444107849Salfred r.nbyte = end - start; 445107849Salfred r.offset = pos; 446100384Speter error = pread(td, &r); 447100384Speter if (error) 448100384Speter return (error); 449100384Speter 450100384Speter td->td_retval[0] = addr; 451100384Speter return (0); 452100384Speter } 453100384Speter if (end == start) { 454100384Speter /* 455100384Speter * After dealing with the ragged ends, there 456100384Speter * might be none left. 457100384Speter */ 458100384Speter td->td_retval[0] = addr; 459100384Speter return (0); 460100384Speter } 461100384Speter addr = start; 462100384Speter len = end - start; 463100384Speter } 464114987Speter#endif 465100384Speter 466107849Salfred ap.addr = (void *) addr; 467107849Salfred ap.len = len; 468107849Salfred ap.prot = prot; 469107849Salfred ap.flags = flags; 470107849Salfred ap.fd = fd; 471107849Salfred ap.pos = pos; 472100384Speter 473100384Speter return (mmap(td, &ap)); 474100384Speter} 475100384Speter 476100384Speterstruct itimerval32 { 477100384Speter struct timeval32 it_interval; 478100384Speter struct timeval32 it_value; 479100384Speter}; 480100384Speter 481121719SpeterCTASSERT(sizeof(struct itimerval32) == 16); 482121719Speter 483100384Speterint 484119333Speterfreebsd32_setitimer(struct thread *td, struct freebsd32_setitimer_args *uap) 485100384Speter{ 486142059Sjhb struct itimerval itv, oitv, *itvp; 487142059Sjhb struct itimerval32 i32; 488100384Speter int error; 489100384Speter 490142059Sjhb if (uap->itv != NULL) { 491142059Sjhb error = copyin(uap->itv, &i32, sizeof(i32)); 492100384Speter if (error) 493100384Speter return (error); 494142059Sjhb TV_CP(i32, itv, it_interval); 495142059Sjhb TV_CP(i32, itv, it_value); 496142059Sjhb itvp = &itv; 497142059Sjhb } else 498142059Sjhb itvp = NULL; 499142059Sjhb error = kern_setitimer(td, uap->which, itvp, &oitv); 500142059Sjhb if (error || uap->oitv == NULL) 501100384Speter return (error); 502142059Sjhb TV_CP(oitv, i32, it_interval); 503142059Sjhb TV_CP(oitv, i32, it_value); 504142059Sjhb return (copyout(&i32, uap->oitv, sizeof(i32))); 505100384Speter} 506100384Speter 507100384Speterint 508125171Speterfreebsd32_getitimer(struct thread *td, struct freebsd32_getitimer_args *uap) 509125171Speter{ 510142059Sjhb struct itimerval itv; 511142059Sjhb struct itimerval32 i32; 512125171Speter int error; 513125171Speter 514142059Sjhb error = kern_getitimer(td, uap->which, &itv); 515142059Sjhb if (error || uap->itv == NULL) 516125171Speter return (error); 517142059Sjhb TV_CP(itv, i32, it_interval); 518142059Sjhb TV_CP(itv, i32, it_value); 519142059Sjhb return (copyout(&i32, uap->itv, sizeof(i32))); 520125171Speter} 521125171Speter 522125171Speterint 523119333Speterfreebsd32_select(struct thread *td, struct freebsd32_select_args *uap) 524100384Speter{ 525142059Sjhb struct timeval32 tv32; 526142059Sjhb struct timeval tv, *tvp; 527100384Speter int error; 528100384Speter 529142059Sjhb if (uap->tv != NULL) { 530142059Sjhb error = copyin(uap->tv, &tv32, sizeof(tv32)); 531100384Speter if (error) 532100384Speter return (error); 533142059Sjhb CP(tv32, tv, tv_sec); 534142059Sjhb CP(tv32, tv, tv_usec); 535142059Sjhb tvp = &tv; 536142059Sjhb } else 537142059Sjhb tvp = NULL; 538100384Speter /* 539100384Speter * XXX big-endian needs to convert the fd_sets too. 540142059Sjhb * XXX Do pointers need PTRIN()? 541100384Speter */ 542142059Sjhb return (kern_select(td, uap->nd, uap->in, uap->ou, uap->ex, tvp)); 543100384Speter} 544100384Speter 545114987Speterstruct kevent32 { 546114987Speter u_int32_t ident; /* identifier for this event */ 547114987Speter short filter; /* filter for event */ 548114987Speter u_short flags; 549114987Speter u_int fflags; 550114987Speter int32_t data; 551114987Speter u_int32_t udata; /* opaque user data identifier */ 552114987Speter}; 553114987Speter 554121719SpeterCTASSERT(sizeof(struct kevent32) == 20); 555121719Speter 556100384Speterint 557119333Speterfreebsd32_kevent(struct thread *td, struct freebsd32_kevent_args *uap) 558114987Speter{ 559114987Speter struct timespec32 ts32; 560142934Sps struct timespec ts, *tsp; 561142934Sps struct kevent *ks; 562114987Speter struct kevent32 ks32; 563142934Sps struct kevent *changes, *events; 564142934Sps int error, i; 565114987Speter 566114987Speter 567114987Speter if (uap->timeout) { 568114987Speter error = copyin(uap->timeout, &ts32, sizeof(ts32)); 569114987Speter if (error) 570114987Speter return (error); 571114987Speter CP(ts32, ts, tv_sec); 572114987Speter CP(ts32, ts, tv_nsec); 573142934Sps tsp = &ts; 574142934Sps } else 575142934Sps tsp = NULL; 576142934Sps if (uap->changelist && uap->nchanges > 0) { 577142934Sps changes = malloc(sizeof(struct kevent) * uap->nchanges, M_TEMP, 578142934Sps M_WAITOK); 579114987Speter for (i = 0; i < uap->nchanges; i++) { 580119333Speter error = copyin(&uap->changelist[i], &ks32, 581119333Speter sizeof(ks32)); 582142934Sps if (error) { 583142934Sps free(changes, M_TEMP); 584114987Speter return (error); 585142934Sps } 586142934Sps ks = &changes[i]; 587114987Speter CP(ks32, *ks, ident); 588114987Speter CP(ks32, *ks, filter); 589114987Speter CP(ks32, *ks, flags); 590114987Speter CP(ks32, *ks, fflags); 591114987Speter CP(ks32, *ks, data); 592114987Speter PTRIN_CP(ks32, *ks, udata); 593114987Speter } 594142934Sps } else 595142934Sps changes = NULL; 596142934Sps if (uap->eventlist && uap->nevents > 0) 597142934Sps events = malloc(sizeof(struct kevent) * uap->nevents, M_TEMP, 598142934Sps M_WAITOK); 599142934Sps else 600142934Sps events = NULL; 601142934Sps error = kern_kevent(td, uap->fd, changes, uap->nchanges, UIO_SYSSPACE, 602142934Sps events, uap->nevents, UIO_SYSSPACE, tsp); 603142934Sps free(changes, M_TEMP); 604142934Sps if (uap->eventlist && events && td->td_retval[0] > 0) { 605142934Sps for (i = 0; i < td->td_retval[0]; i++) { 606142934Sps ks = &events[i]; 607114987Speter CP(*ks, ks32, ident); 608114987Speter CP(*ks, ks32, filter); 609114987Speter CP(*ks, ks32, flags); 610114987Speter CP(*ks, ks32, fflags); 611114987Speter CP(*ks, ks32, data); 612114987Speter PTROUT_CP(*ks, ks32, udata); 613119333Speter error = copyout(&ks32, &uap->eventlist[i], 614119333Speter sizeof(ks32)); 615114987Speter if (error) 616142934Sps break; 617114987Speter } 618114987Speter } 619142934Sps if (events) 620142934Sps free(events, M_TEMP); 621142934Sps return (error); 622114987Speter} 623114987Speter 624114987Speterint 625119333Speterfreebsd32_gettimeofday(struct thread *td, 626119333Speter struct freebsd32_gettimeofday_args *uap) 627100384Speter{ 628123425Speter struct timeval atv; 629123425Speter struct timeval32 atv32; 630123425Speter struct timezone rtz; 631123425Speter int error = 0; 632100384Speter 633123425Speter if (uap->tp) { 634123425Speter microtime(&atv); 635123425Speter CP(atv, atv32, tv_sec); 636123425Speter CP(atv, atv32, tv_usec); 637123425Speter error = copyout(&atv32, uap->tp, sizeof (atv32)); 638100384Speter } 639123425Speter if (error == 0 && uap->tzp != NULL) { 640123425Speter rtz.tz_minuteswest = tz_minuteswest; 641123425Speter rtz.tz_dsttime = tz_dsttime; 642123425Speter error = copyout(&rtz, uap->tzp, sizeof (rtz)); 643100384Speter } 644100384Speter return (error); 645100384Speter} 646100384Speter 647100384Speterint 648119333Speterfreebsd32_getrusage(struct thread *td, struct freebsd32_getrusage_args *uap) 649100384Speter{ 650136152Sjhb struct rusage32 s32; 651136152Sjhb struct rusage s; 652100384Speter int error; 653100384Speter 654136152Sjhb error = kern_getrusage(td, uap->who, &s); 655100384Speter if (error) 656100384Speter return (error); 657136152Sjhb if (uap->rusage != NULL) { 658100384Speter TV_CP(s, s32, ru_utime); 659100384Speter TV_CP(s, s32, ru_stime); 660100384Speter CP(s, s32, ru_maxrss); 661100384Speter CP(s, s32, ru_ixrss); 662100384Speter CP(s, s32, ru_idrss); 663100384Speter CP(s, s32, ru_isrss); 664100384Speter CP(s, s32, ru_minflt); 665100384Speter CP(s, s32, ru_majflt); 666100384Speter CP(s, s32, ru_nswap); 667100384Speter CP(s, s32, ru_inblock); 668100384Speter CP(s, s32, ru_oublock); 669100384Speter CP(s, s32, ru_msgsnd); 670100384Speter CP(s, s32, ru_msgrcv); 671100384Speter CP(s, s32, ru_nsignals); 672100384Speter CP(s, s32, ru_nvcsw); 673100384Speter CP(s, s32, ru_nivcsw); 674136152Sjhb error = copyout(&s32, uap->rusage, sizeof(s32)); 675100384Speter } 676100384Speter return (error); 677100384Speter} 678100384Speter 679100384Speterstruct iovec32 { 680100384Speter u_int32_t iov_base; 681100384Speter int iov_len; 682100384Speter}; 683100384Speter 684121719SpeterCTASSERT(sizeof(struct iovec32) == 8); 685121719Speter 686144450Sjhbstatic int 687144450Sjhbfreebsd32_copyinuio(struct iovec32 *iovp, u_int iovcnt, struct uio **uiop) 688100384Speter{ 689144450Sjhb struct iovec32 iov32; 690144450Sjhb struct iovec *iov; 691144450Sjhb struct uio *uio; 692144450Sjhb u_int iovlen; 693144450Sjhb int error, i; 694100384Speter 695144450Sjhb *uiop = NULL; 696144450Sjhb if (iovcnt > UIO_MAXIOV) 697100384Speter return (EINVAL); 698144450Sjhb iovlen = iovcnt * sizeof(struct iovec); 699144450Sjhb uio = malloc(iovlen + sizeof *uio, M_IOV, M_WAITOK); 700144450Sjhb iov = (struct iovec *)(uio + 1); 701144450Sjhb for (i = 0; i < iovcnt; i++) { 702144450Sjhb error = copyin(&iovp[i], &iov32, sizeof(struct iovec32)); 703144450Sjhb if (error) { 704144450Sjhb free(uio, M_IOV); 705144450Sjhb return (error); 706144450Sjhb } 707144450Sjhb iov[i].iov_base = PTRIN(iov32.iov_base); 708144450Sjhb iov[i].iov_len = iov32.iov_len; 709100384Speter } 710144450Sjhb uio->uio_iov = iov; 711144450Sjhb uio->uio_iovcnt = iovcnt; 712144450Sjhb uio->uio_segflg = UIO_USERSPACE; 713144450Sjhb uio->uio_offset = -1; 714144450Sjhb uio->uio_resid = 0; 715144450Sjhb for (i = 0; i < iovcnt; i++) { 716144450Sjhb if (iov->iov_len > INT_MAX - uio->uio_resid) { 717144450Sjhb free(uio, M_IOV); 718144450Sjhb return (EINVAL); 719144450Sjhb } 720144450Sjhb uio->uio_resid += iov->iov_len; 721144450Sjhb iov++; 722144450Sjhb } 723144450Sjhb *uiop = uio; 724144450Sjhb return (0); 725144450Sjhb} 726100384Speter 727144450Sjhbint 728144450Sjhbfreebsd32_readv(struct thread *td, struct freebsd32_readv_args *uap) 729144450Sjhb{ 730144450Sjhb struct uio *auio; 731144450Sjhb int error; 732100384Speter 733144450Sjhb error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio); 734144450Sjhb if (error) 735144450Sjhb return (error); 736144450Sjhb error = kern_readv(td, uap->fd, auio); 737144450Sjhb free(auio, M_IOV); 738100384Speter return (error); 739100384Speter} 740100384Speter 741100384Speterint 742119333Speterfreebsd32_writev(struct thread *td, struct freebsd32_writev_args *uap) 743100384Speter{ 744144450Sjhb struct uio *auio; 745144450Sjhb int error; 746100384Speter 747144450Sjhb error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio); 748144450Sjhb if (error) 749144450Sjhb return (error); 750144450Sjhb error = kern_writev(td, uap->fd, auio); 751144450Sjhb free(auio, M_IOV); 752100384Speter return (error); 753100384Speter} 754100384Speter 755100384Speterint 756119333Speterfreebsd32_settimeofday(struct thread *td, 757119333Speter struct freebsd32_settimeofday_args *uap) 758100384Speter{ 759144450Sjhb struct timeval32 tv32; 760144450Sjhb struct timeval tv, *tvp; 761144450Sjhb struct timezone tz, *tzp; 762100384Speter int error; 763100384Speter 764144450Sjhb if (uap->tv) { 765144450Sjhb error = copyin(uap->tv, &tv32, sizeof(tv32)); 766100384Speter if (error) 767100384Speter return (error); 768144450Sjhb CP(tv32, tv, tv_sec); 769144450Sjhb CP(tv32, tv, tv_usec); 770144450Sjhb tvp = &tv; 771144450Sjhb } else 772144450Sjhb tvp = NULL; 773144450Sjhb if (uap->tzp) { 774144450Sjhb error = copyin(uap->tzp, &tz, sizeof(tz)); 775100384Speter if (error) 776100384Speter return (error); 777144450Sjhb tzp = &tz; 778144450Sjhb } else 779144450Sjhb tzp = NULL; 780144450Sjhb return (kern_settimeofday(td, tvp, tzp)); 781100384Speter} 782100384Speter 783100384Speterint 784119333Speterfreebsd32_utimes(struct thread *td, struct freebsd32_utimes_args *uap) 785100384Speter{ 786142059Sjhb struct timeval32 s32[2]; 787142059Sjhb struct timeval s[2], *sp; 788100384Speter int error; 789100384Speter 790142059Sjhb if (uap->tptr != NULL) { 791142059Sjhb error = copyin(uap->tptr, s32, sizeof(s32)); 792100384Speter if (error) 793100384Speter return (error); 794100384Speter CP(s32[0], s[0], tv_sec); 795100384Speter CP(s32[0], s[0], tv_usec); 796100384Speter CP(s32[1], s[1], tv_sec); 797100384Speter CP(s32[1], s[1], tv_usec); 798142059Sjhb sp = s; 799142059Sjhb } else 800142059Sjhb sp = NULL; 801142059Sjhb return (kern_utimes(td, uap->path, UIO_USERSPACE, sp, UIO_SYSSPACE)); 802100384Speter} 803100384Speter 804100384Speterint 805119333Speterfreebsd32_adjtime(struct thread *td, struct freebsd32_adjtime_args *uap) 806100384Speter{ 807144450Sjhb struct timeval32 tv32; 808144450Sjhb struct timeval delta, olddelta, *deltap; 809100384Speter int error; 810100384Speter 811144450Sjhb if (uap->delta) { 812144450Sjhb error = copyin(uap->delta, &tv32, sizeof(tv32)); 813100384Speter if (error) 814100384Speter return (error); 815144450Sjhb CP(tv32, delta, tv_sec); 816144450Sjhb CP(tv32, delta, tv_usec); 817144450Sjhb deltap = δ 818144450Sjhb } else 819144450Sjhb deltap = NULL; 820144450Sjhb error = kern_adjtime(td, deltap, &olddelta); 821144450Sjhb if (uap->olddelta && error == 0) { 822144450Sjhb CP(olddelta, tv32, tv_sec); 823144450Sjhb CP(olddelta, tv32, tv_usec); 824144450Sjhb error = copyout(&tv32, uap->olddelta, sizeof(tv32)); 825100384Speter } 826100384Speter return (error); 827100384Speter} 828100384Speter 829128597Smarcel#ifdef COMPAT_FREEBSD4 830100384Speterint 831128260Speterfreebsd4_freebsd32_statfs(struct thread *td, struct freebsd4_freebsd32_statfs_args *uap) 832100384Speter{ 833142059Sjhb struct statfs32 s32; 834142059Sjhb struct statfs s; 835100384Speter int error; 836100384Speter 837142059Sjhb error = kern_statfs(td, uap->path, UIO_USERSPACE, &s); 838100384Speter if (error) 839100384Speter return (error); 840142059Sjhb copy_statfs(&s, &s32); 841142059Sjhb return (copyout(&s32, uap->buf, sizeof(s32))); 842100384Speter} 843128597Smarcel#endif 844100384Speter 845128597Smarcel#ifdef COMPAT_FREEBSD4 846100384Speterint 847128260Speterfreebsd4_freebsd32_fstatfs(struct thread *td, struct freebsd4_freebsd32_fstatfs_args *uap) 848100384Speter{ 849142059Sjhb struct statfs32 s32; 850142059Sjhb struct statfs s; 851100384Speter int error; 852100384Speter 853142059Sjhb error = kern_fstatfs(td, uap->fd, &s); 854100384Speter if (error) 855100384Speter return (error); 856142059Sjhb copy_statfs(&s, &s32); 857142059Sjhb return (copyout(&s32, uap->buf, sizeof(s32))); 858100384Speter} 859128597Smarcel#endif 860100384Speter 861128597Smarcel#ifdef COMPAT_FREEBSD4 862100384Speterint 863128260Speterfreebsd4_freebsd32_fhstatfs(struct thread *td, struct freebsd4_freebsd32_fhstatfs_args *uap) 864128260Speter{ 865142059Sjhb struct statfs32 s32; 866142059Sjhb struct statfs s; 867142059Sjhb fhandle_t fh; 868128260Speter int error; 869128260Speter 870142059Sjhb if ((error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t))) != 0) 871142059Sjhb return (error); 872142059Sjhb error = kern_fhstatfs(td, fh, &s); 873128260Speter if (error) 874128260Speter return (error); 875142059Sjhb copy_statfs(&s, &s32); 876142059Sjhb return (copyout(&s32, uap->buf, sizeof(s32))); 877128260Speter} 878128597Smarcel#endif 879128260Speter 880128260Speterint 881119333Speterfreebsd32_semsys(struct thread *td, struct freebsd32_semsys_args *uap) 882100384Speter{ 883100384Speter /* 884100384Speter * Vector through to semsys if it is loaded. 885100384Speter */ 886100384Speter return sysent[169].sy_call(td, uap); 887100384Speter} 888100384Speter 889100384Speterint 890119333Speterfreebsd32_msgsys(struct thread *td, struct freebsd32_msgsys_args *uap) 891100384Speter{ 892100384Speter /* 893100384Speter * Vector through to msgsys if it is loaded. 894100384Speter */ 895100384Speter return sysent[170].sy_call(td, uap); 896100384Speter} 897100384Speter 898100384Speterint 899119333Speterfreebsd32_shmsys(struct thread *td, struct freebsd32_shmsys_args *uap) 900100384Speter{ 901100384Speter /* 902100384Speter * Vector through to shmsys if it is loaded. 903100384Speter */ 904100384Speter return sysent[171].sy_call(td, uap); 905100384Speter} 906100384Speter 907100384Speterint 908119333Speterfreebsd32_pread(struct thread *td, struct freebsd32_pread_args *uap) 909100384Speter{ 910100384Speter struct pread_args ap; 911100384Speter 912107849Salfred ap.fd = uap->fd; 913107849Salfred ap.buf = uap->buf; 914107849Salfred ap.nbyte = uap->nbyte; 915119333Speter ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 916100384Speter return (pread(td, &ap)); 917100384Speter} 918100384Speter 919100384Speterint 920119333Speterfreebsd32_pwrite(struct thread *td, struct freebsd32_pwrite_args *uap) 921100384Speter{ 922100384Speter struct pwrite_args ap; 923100384Speter 924107849Salfred ap.fd = uap->fd; 925107849Salfred ap.buf = uap->buf; 926107849Salfred ap.nbyte = uap->nbyte; 927119333Speter ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 928100384Speter return (pwrite(td, &ap)); 929100384Speter} 930100384Speter 931100384Speterint 932119333Speterfreebsd32_lseek(struct thread *td, struct freebsd32_lseek_args *uap) 933100384Speter{ 934100384Speter int error; 935100384Speter struct lseek_args ap; 936100384Speter off_t pos; 937100384Speter 938107849Salfred ap.fd = uap->fd; 939119333Speter ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 940107849Salfred ap.whence = uap->whence; 941100384Speter error = lseek(td, &ap); 942100384Speter /* Expand the quad return into two parts for eax and edx */ 943100384Speter pos = *(off_t *)(td->td_retval); 944100384Speter td->td_retval[0] = pos & 0xffffffff; /* %eax */ 945100384Speter td->td_retval[1] = pos >> 32; /* %edx */ 946100384Speter return error; 947100384Speter} 948100384Speter 949100384Speterint 950119333Speterfreebsd32_truncate(struct thread *td, struct freebsd32_truncate_args *uap) 951100384Speter{ 952100384Speter struct truncate_args ap; 953100384Speter 954107849Salfred ap.path = uap->path; 955119333Speter ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32)); 956100384Speter return (truncate(td, &ap)); 957100384Speter} 958100384Speter 959100384Speterint 960119333Speterfreebsd32_ftruncate(struct thread *td, struct freebsd32_ftruncate_args *uap) 961100384Speter{ 962100384Speter struct ftruncate_args ap; 963100384Speter 964107849Salfred ap.fd = uap->fd; 965119333Speter ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32)); 966100384Speter return (ftruncate(td, &ap)); 967100384Speter} 968100384Speter 969104738Speter#ifdef COMPAT_FREEBSD4 970100384Speterint 971119333Speterfreebsd4_freebsd32_sendfile(struct thread *td, 972119333Speter struct freebsd4_freebsd32_sendfile_args *uap) 973104738Speter{ 974104738Speter struct freebsd4_sendfile_args ap; 975104738Speter 976107849Salfred ap.fd = uap->fd; 977107849Salfred ap.s = uap->s; 978119333Speter ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 979107849Salfred ap.nbytes = uap->nbytes; /* XXX check */ 980107849Salfred ap.hdtr = uap->hdtr; /* XXX check */ 981107849Salfred ap.sbytes = uap->sbytes; /* XXX FIXME!! */ 982107849Salfred ap.flags = uap->flags; 983104738Speter return (freebsd4_sendfile(td, &ap)); 984104738Speter} 985104738Speter#endif 986104738Speter 987104738Speterint 988119333Speterfreebsd32_sendfile(struct thread *td, struct freebsd32_sendfile_args *uap) 989100384Speter{ 990100384Speter struct sendfile_args ap; 991100384Speter 992107849Salfred ap.fd = uap->fd; 993107849Salfred ap.s = uap->s; 994119333Speter ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 995107849Salfred ap.nbytes = uap->nbytes; /* XXX check */ 996107849Salfred ap.hdtr = uap->hdtr; /* XXX check */ 997107849Salfred ap.sbytes = uap->sbytes; /* XXX FIXME!! */ 998107849Salfred ap.flags = uap->flags; 999100384Speter return (sendfile(td, &ap)); 1000100384Speter} 1001100384Speter 1002100384Speterstruct stat32 { 1003130640Sphk dev_t st_dev; 1004100384Speter ino_t st_ino; 1005100384Speter mode_t st_mode; 1006100384Speter nlink_t st_nlink; 1007100384Speter uid_t st_uid; 1008100384Speter gid_t st_gid; 1009130640Sphk dev_t st_rdev; 1010100384Speter struct timespec32 st_atimespec; 1011100384Speter struct timespec32 st_mtimespec; 1012100384Speter struct timespec32 st_ctimespec; 1013100384Speter off_t st_size; 1014100384Speter int64_t st_blocks; 1015100384Speter u_int32_t st_blksize; 1016100384Speter u_int32_t st_flags; 1017100384Speter u_int32_t st_gen; 1018121719Speter struct timespec32 st_birthtimespec; 1019121719Speter unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec32)); 1020121719Speter unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec32)); 1021100384Speter}; 1022100384Speter 1023121719Speter 1024121719SpeterCTASSERT(sizeof(struct stat32) == 96); 1025121719Speter 1026100384Speterstatic void 1027100384Spetercopy_stat( struct stat *in, struct stat32 *out) 1028100384Speter{ 1029100384Speter CP(*in, *out, st_dev); 1030100384Speter CP(*in, *out, st_ino); 1031100384Speter CP(*in, *out, st_mode); 1032100384Speter CP(*in, *out, st_nlink); 1033100384Speter CP(*in, *out, st_uid); 1034100384Speter CP(*in, *out, st_gid); 1035100384Speter CP(*in, *out, st_rdev); 1036100384Speter TS_CP(*in, *out, st_atimespec); 1037100384Speter TS_CP(*in, *out, st_mtimespec); 1038100384Speter TS_CP(*in, *out, st_ctimespec); 1039100384Speter CP(*in, *out, st_size); 1040100384Speter CP(*in, *out, st_blocks); 1041100384Speter CP(*in, *out, st_blksize); 1042100384Speter CP(*in, *out, st_flags); 1043100384Speter CP(*in, *out, st_gen); 1044100384Speter} 1045100384Speter 1046100384Speterint 1047119333Speterfreebsd32_stat(struct thread *td, struct freebsd32_stat_args *uap) 1048100384Speter{ 1049123746Speter struct stat sb; 1050123746Speter struct stat32 sb32; 1051100384Speter int error; 1052100384Speter 1053142059Sjhb error = kern_stat(td, uap->path, UIO_USERSPACE, &sb); 1054100384Speter if (error) 1055100384Speter return (error); 1056123746Speter copy_stat(&sb, &sb32); 1057123746Speter error = copyout(&sb32, uap->ub, sizeof (sb32)); 1058100384Speter return (error); 1059100384Speter} 1060100384Speter 1061100384Speterint 1062119333Speterfreebsd32_fstat(struct thread *td, struct freebsd32_fstat_args *uap) 1063100384Speter{ 1064123746Speter struct stat ub; 1065123746Speter struct stat32 ub32; 1066100384Speter int error; 1067100384Speter 1068142059Sjhb error = kern_fstat(td, uap->fd, &ub); 1069100384Speter if (error) 1070100384Speter return (error); 1071123746Speter copy_stat(&ub, &ub32); 1072123746Speter error = copyout(&ub32, uap->ub, sizeof(ub32)); 1073100384Speter return (error); 1074100384Speter} 1075100384Speter 1076100384Speterint 1077119333Speterfreebsd32_lstat(struct thread *td, struct freebsd32_lstat_args *uap) 1078100384Speter{ 1079123746Speter struct stat sb; 1080123746Speter struct stat32 sb32; 1081142059Sjhb int error; 1082100384Speter 1083142059Sjhb error = kern_lstat(td, uap->path, UIO_USERSPACE, &sb); 1084100384Speter if (error) 1085100384Speter return (error); 1086123746Speter copy_stat(&sb, &sb32); 1087123746Speter error = copyout(&sb32, uap->ub, sizeof (sb32)); 1088100384Speter return (error); 1089100384Speter} 1090100384Speter 1091100384Speter/* 1092100384Speter * MPSAFE 1093100384Speter */ 1094100384Speterint 1095119333Speterfreebsd32_sysctl(struct thread *td, struct freebsd32_sysctl_args *uap) 1096100384Speter{ 1097100384Speter int error, name[CTL_MAXNAME]; 1098100384Speter size_t j, oldlen; 1099100384Speter 1100100384Speter if (uap->namelen > CTL_MAXNAME || uap->namelen < 2) 1101100384Speter return (EINVAL); 1102136404Speter error = copyin(uap->name, name, uap->namelen * sizeof(int)); 1103100384Speter if (error) 1104100384Speter return (error); 1105100384Speter mtx_lock(&Giant); 1106100384Speter if (uap->oldlenp) 1107100384Speter oldlen = fuword32(uap->oldlenp); 1108100384Speter else 1109100384Speter oldlen = 0; 1110100384Speter error = userland_sysctl(td, name, uap->namelen, 1111100384Speter uap->old, &oldlen, 1, 1112136404Speter uap->new, uap->newlen, &j, SCTL_MASK32); 1113100384Speter if (error && error != ENOMEM) 1114100384Speter goto done2; 1115136404Speter if (uap->oldlenp) 1116100384Speter suword32(uap->oldlenp, j); 1117100384Speterdone2: 1118100384Speter mtx_unlock(&Giant); 1119100384Speter return (error); 1120100384Speter} 1121100384Speter 1122100384Speterstruct sigaction32 { 1123100384Speter u_int32_t sa_u; 1124100384Speter int sa_flags; 1125100384Speter sigset_t sa_mask; 1126100384Speter}; 1127100384Speter 1128121719SpeterCTASSERT(sizeof(struct sigaction32) == 24); 1129121719Speter 1130100384Speterint 1131119333Speterfreebsd32_sigaction(struct thread *td, struct freebsd32_sigaction_args *uap) 1132100384Speter{ 1133113859Sjhb struct sigaction32 s32; 1134113859Sjhb struct sigaction sa, osa, *sap; 1135100384Speter int error; 1136100384Speter 1137113859Sjhb if (uap->act) { 1138113859Sjhb error = copyin(uap->act, &s32, sizeof(s32)); 1139100384Speter if (error) 1140100384Speter return (error); 1141113859Sjhb sa.sa_handler = PTRIN(s32.sa_u); 1142113859Sjhb CP(s32, sa, sa_flags); 1143113859Sjhb CP(s32, sa, sa_mask); 1144113859Sjhb sap = &sa; 1145113859Sjhb } else 1146113859Sjhb sap = NULL; 1147113859Sjhb error = kern_sigaction(td, uap->sig, sap, &osa, 0); 1148146583Sps if (error == 0 && uap->oact != NULL) { 1149113859Sjhb s32.sa_u = PTROUT(osa.sa_handler); 1150113859Sjhb CP(osa, s32, sa_flags); 1151113859Sjhb CP(osa, s32, sa_mask); 1152113859Sjhb error = copyout(&s32, uap->oact, sizeof(s32)); 1153100384Speter } 1154100384Speter return (error); 1155100384Speter} 1156100384Speter 1157114987Speter#ifdef COMPAT_FREEBSD4 1158114987Speterint 1159119333Speterfreebsd4_freebsd32_sigaction(struct thread *td, 1160119333Speter struct freebsd4_freebsd32_sigaction_args *uap) 1161114987Speter{ 1162114987Speter struct sigaction32 s32; 1163114987Speter struct sigaction sa, osa, *sap; 1164114987Speter int error; 1165114987Speter 1166114987Speter if (uap->act) { 1167114987Speter error = copyin(uap->act, &s32, sizeof(s32)); 1168114987Speter if (error) 1169114987Speter return (error); 1170114987Speter sa.sa_handler = PTRIN(s32.sa_u); 1171114987Speter CP(s32, sa, sa_flags); 1172114987Speter CP(s32, sa, sa_mask); 1173114987Speter sap = &sa; 1174114987Speter } else 1175114987Speter sap = NULL; 1176114987Speter error = kern_sigaction(td, uap->sig, sap, &osa, KSA_FREEBSD4); 1177146583Sps if (error == 0 && uap->oact != NULL) { 1178114987Speter s32.sa_u = PTROUT(osa.sa_handler); 1179114987Speter CP(osa, s32, sa_flags); 1180114987Speter CP(osa, s32, sa_mask); 1181114987Speter error = copyout(&s32, uap->oact, sizeof(s32)); 1182114987Speter } 1183114987Speter return (error); 1184114987Speter} 1185114987Speter#endif 1186114987Speter 1187140481Spsint 1188140481Spsfreebsd32_nanosleep(struct thread *td, struct freebsd32_nanosleep_args *uap) 1189140481Sps{ 1190140481Sps struct timespec32 rmt32, rqt32; 1191140481Sps struct timespec rmt, rqt; 1192140481Sps int error; 1193140481Sps 1194140481Sps error = copyin(uap->rqtp, &rqt32, sizeof(rqt)); 1195140481Sps if (error) 1196140481Sps return (error); 1197140481Sps 1198140481Sps CP(rqt32, rqt, tv_sec); 1199140481Sps CP(rqt32, rqt, tv_nsec); 1200140481Sps 1201140481Sps if (uap->rmtp && 1202140481Sps !useracc((caddr_t)uap->rmtp, sizeof(rmt), VM_PROT_WRITE)) 1203140481Sps return (EFAULT); 1204140481Sps error = kern_nanosleep(td, &rqt, &rmt); 1205140481Sps if (error && uap->rmtp) { 1206140481Sps int error2; 1207140481Sps 1208140481Sps CP(rmt, rmt32, tv_sec); 1209140481Sps CP(rmt, rmt32, tv_nsec); 1210140481Sps 1211140481Sps error2 = copyout(&rmt32, uap->rmtp, sizeof(rmt)); 1212140481Sps if (error2) 1213140481Sps error = error2; 1214140481Sps } 1215140481Sps return (error); 1216140481Sps} 1217140481Sps 1218100384Speter#if 0 1219100384Speter 1220100384Speterint 1221119333Speterfreebsd32_xxx(struct thread *td, struct freebsd32_xxx_args *uap) 1222100384Speter{ 1223100384Speter int error; 1224100384Speter caddr_t sg; 1225100384Speter struct yyy32 *p32, s32; 1226100384Speter struct yyy *p = NULL, s; 1227100384Speter 1228107849Salfred p32 = uap->zzz; 1229100384Speter if (p32) { 1230100384Speter sg = stackgap_init(); 1231100384Speter p = stackgap_alloc(&sg, sizeof(struct yyy)); 1232107849Salfred uap->zzz = (struct yyy32 *)p; 1233100384Speter error = copyin(p32, &s32, sizeof(s32)); 1234100384Speter if (error) 1235100384Speter return (error); 1236100384Speter /* translate in */ 1237100384Speter error = copyout(&s, p, sizeof(s)); 1238100384Speter if (error) 1239100384Speter return (error); 1240100384Speter } 1241100384Speter error = xxx(td, (struct xxx_args *) uap); 1242100384Speter if (error) 1243100384Speter return (error); 1244100384Speter if (p32) { 1245100384Speter error = copyin(p, &s, sizeof(s)); 1246100384Speter if (error) 1247100384Speter return (error); 1248100384Speter /* translate out */ 1249100384Speter error = copyout(&s32, p32, sizeof(s32)); 1250100384Speter } 1251100384Speter return (error); 1252100384Speter} 1253100384Speter 1254100384Speter#endif 1255