freebsd32_misc.c revision 147654
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 147654 2005-06-29 15:16:20Z jhb $"); 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> 55146950Sps#include <sys/eventvar.h> /* Must come after sys/selinfo.h */ 56100384Speter#include <sys/pipe.h> /* Must come after sys/selinfo.h */ 57100384Speter#include <sys/signal.h> 58100384Speter#include <sys/signalvar.h> 59100384Speter#include <sys/socket.h> 60100384Speter#include <sys/socketvar.h> 61100384Speter#include <sys/stat.h> 62113859Sjhb#include <sys/syscallsubr.h> 63100384Speter#include <sys/sysctl.h> 64100384Speter#include <sys/sysent.h> 65100384Speter#include <sys/sysproto.h> 66100384Speter#include <sys/systm.h> 67100384Speter#include <sys/unistd.h> 68100384Speter#include <sys/vnode.h> 69127140Sjhb#include <sys/wait.h> 70100384Speter 71100384Speter#include <vm/vm.h> 72100384Speter#include <vm/vm_kern.h> 73100384Speter#include <vm/vm_param.h> 74100384Speter#include <vm/pmap.h> 75100384Speter#include <vm/vm_map.h> 76100384Speter#include <vm/vm_object.h> 77100384Speter#include <vm/vm_extern.h> 78100384Speter 79119333Speter#include <compat/freebsd32/freebsd32_util.h> 80119333Speter#include <compat/freebsd32/freebsd32.h> 81119333Speter#include <compat/freebsd32/freebsd32_proto.h> 82100384Speter 83121719SpeterCTASSERT(sizeof(struct timeval32) == 8); 84121719SpeterCTASSERT(sizeof(struct timespec32) == 8); 85121719SpeterCTASSERT(sizeof(struct statfs32) == 256); 86121719SpeterCTASSERT(sizeof(struct rusage32) == 72); 87121719Speter 88100384Speterint 89119333Speterfreebsd32_wait4(struct thread *td, struct freebsd32_wait4_args *uap) 90100384Speter{ 91127140Sjhb int error, status; 92127140Sjhb struct rusage32 ru32; 93136152Sjhb struct rusage ru, *rup; 94100384Speter 95136152Sjhb if (uap->rusage != NULL) 96136152Sjhb rup = &ru; 97136152Sjhb else 98136152Sjhb rup = NULL; 99136152Sjhb error = kern_wait(td, uap->pid, &status, uap->options, rup); 100100384Speter if (error) 101100384Speter return (error); 102127140Sjhb if (uap->status != NULL) 103127140Sjhb error = copyout(&status, uap->status, sizeof(status)); 104127140Sjhb if (uap->rusage != NULL && error == 0) { 105100384Speter TV_CP(ru, ru32, ru_utime); 106100384Speter TV_CP(ru, ru32, ru_stime); 107100384Speter CP(ru, ru32, ru_maxrss); 108100384Speter CP(ru, ru32, ru_ixrss); 109100384Speter CP(ru, ru32, ru_idrss); 110100384Speter CP(ru, ru32, ru_isrss); 111100384Speter CP(ru, ru32, ru_minflt); 112100384Speter CP(ru, ru32, ru_majflt); 113100384Speter CP(ru, ru32, ru_nswap); 114100384Speter CP(ru, ru32, ru_inblock); 115100384Speter CP(ru, ru32, ru_oublock); 116100384Speter CP(ru, ru32, ru_msgsnd); 117100384Speter CP(ru, ru32, ru_msgrcv); 118100384Speter CP(ru, ru32, ru_nsignals); 119100384Speter CP(ru, ru32, ru_nvcsw); 120100384Speter CP(ru, ru32, ru_nivcsw); 121127140Sjhb error = copyout(&ru32, uap->rusage, sizeof(ru32)); 122100384Speter } 123100384Speter return (error); 124100384Speter} 125100384Speter 126128597Smarcel#ifdef COMPAT_FREEBSD4 127100384Speterstatic void 128100384Spetercopy_statfs(struct statfs *in, struct statfs32 *out) 129100384Speter{ 130100384Speter CP(*in, *out, f_bsize); 131100384Speter CP(*in, *out, f_iosize); 132100384Speter CP(*in, *out, f_blocks); 133100384Speter CP(*in, *out, f_bfree); 134100384Speter CP(*in, *out, f_bavail); 135100384Speter CP(*in, *out, f_files); 136100384Speter CP(*in, *out, f_ffree); 137100384Speter CP(*in, *out, f_fsid); 138100384Speter CP(*in, *out, f_owner); 139100384Speter CP(*in, *out, f_type); 140100384Speter CP(*in, *out, f_flags); 141100384Speter CP(*in, *out, f_flags); 142100384Speter CP(*in, *out, f_syncwrites); 143100384Speter CP(*in, *out, f_asyncwrites); 144100384Speter bcopy(in->f_fstypename, 145100384Speter out->f_fstypename, MFSNAMELEN); 146100384Speter bcopy(in->f_mntonname, 147128260Speter out->f_mntonname, min(MNAMELEN, FREEBSD4_MNAMELEN)); 148100384Speter CP(*in, *out, f_syncreads); 149100384Speter CP(*in, *out, f_asyncreads); 150100384Speter bcopy(in->f_mntfromname, 151128260Speter out->f_mntfromname, min(MNAMELEN, FREEBSD4_MNAMELEN)); 152100384Speter} 153128597Smarcel#endif 154100384Speter 155128597Smarcel#ifdef COMPAT_FREEBSD4 156100384Speterint 157128260Speterfreebsd4_freebsd32_getfsstat(struct thread *td, struct freebsd4_freebsd32_getfsstat_args *uap) 158100384Speter{ 159147178Spjd struct statfs *buf, *sp; 160147178Spjd struct statfs32 stat32; 161147178Spjd size_t count, size; 162100384Speter int error; 163100384Speter 164147178Spjd count = uap->bufsize / sizeof(struct statfs32); 165147178Spjd size = count * sizeof(struct statfs); 166147302Spjd error = kern_getfsstat(td, &buf, size, UIO_SYSSPACE, uap->flags); 167147302Spjd if (size > 0) { 168100384Speter count = td->td_retval[0]; 169147178Spjd sp = buf; 170147178Spjd while (count > 0 && error == 0) { 171147178Spjd copy_statfs(sp, &stat32); 172147178Spjd error = copyout(&stat32, uap->buf, sizeof(stat32)); 173147178Spjd sp++; 174147178Spjd uap->buf++; 175147178Spjd count--; 176100384Speter } 177147178Spjd free(buf, M_TEMP); 178100384Speter } 179100384Speter return (error); 180100384Speter} 181128597Smarcel#endif 182100384Speter 183100384Speterstruct sigaltstack32 { 184100384Speter u_int32_t ss_sp; 185100384Speter u_int32_t ss_size; 186100384Speter int ss_flags; 187100384Speter}; 188100384Speter 189121719SpeterCTASSERT(sizeof(struct sigaltstack32) == 12); 190121719Speter 191100384Speterint 192119333Speterfreebsd32_sigaltstack(struct thread *td, 193119333Speter struct freebsd32_sigaltstack_args *uap) 194100384Speter{ 195113859Sjhb struct sigaltstack32 s32; 196113859Sjhb struct sigaltstack ss, oss, *ssp; 197100384Speter int error; 198100384Speter 199113859Sjhb if (uap->ss != NULL) { 200113859Sjhb error = copyin(uap->ss, &s32, sizeof(s32)); 201100384Speter if (error) 202100384Speter return (error); 203113859Sjhb PTRIN_CP(s32, ss, ss_sp); 204113859Sjhb CP(s32, ss, ss_size); 205113859Sjhb CP(s32, ss, ss_flags); 206113859Sjhb ssp = &ss; 207113859Sjhb } else 208113859Sjhb ssp = NULL; 209113859Sjhb error = kern_sigaltstack(td, ssp, &oss); 210113859Sjhb if (error == 0 && uap->oss != NULL) { 211113859Sjhb PTROUT_CP(oss, s32, ss_sp); 212113859Sjhb CP(oss, s32, ss_size); 213113859Sjhb CP(oss, s32, ss_flags); 214113859Sjhb error = copyout(&s32, uap->oss, sizeof(s32)); 215100384Speter } 216100384Speter return (error); 217100384Speter} 218100384Speter 219142059Sjhb/* 220142059Sjhb * Custom version of exec_copyin_args() so that we can translate 221142059Sjhb * the pointers. 222142059Sjhb */ 223142059Sjhbstatic int 224142059Sjhbfreebsd32_exec_copyin_args(struct image_args *args, char *fname, 225142059Sjhb enum uio_seg segflg, u_int32_t *argv, u_int32_t *envv) 226100384Speter{ 227142059Sjhb char *argp, *envp; 228142059Sjhb u_int32_t *p32, arg; 229142059Sjhb size_t length; 230100384Speter int error; 231100384Speter 232142059Sjhb bzero(args, sizeof(*args)); 233142059Sjhb if (argv == NULL) 234142059Sjhb return (EFAULT); 235100384Speter 236142059Sjhb /* 237142059Sjhb * Allocate temporary demand zeroed space for argument and 238142059Sjhb * environment strings 239142059Sjhb */ 240147588Sjhb args->buf = (char *) kmem_alloc_wait(exec_map, 241147588Sjhb PATH_MAX + ARG_MAX + MAXSHELLCMDLEN); 242142059Sjhb if (args->buf == NULL) 243142059Sjhb return (ENOMEM); 244142059Sjhb args->begin_argv = args->buf; 245142059Sjhb args->endp = args->begin_argv; 246142059Sjhb args->stringspace = ARG_MAX; 247142059Sjhb 248142059Sjhb args->fname = args->buf + ARG_MAX; 249142059Sjhb 250142059Sjhb /* 251142059Sjhb * Copy the file name. 252142059Sjhb */ 253142059Sjhb error = (segflg == UIO_SYSSPACE) ? 254142059Sjhb copystr(fname, args->fname, PATH_MAX, &length) : 255142059Sjhb copyinstr(fname, args->fname, PATH_MAX, &length); 256142059Sjhb if (error != 0) 257142059Sjhb return (error); 258142059Sjhb 259142059Sjhb /* 260142059Sjhb * extract arguments first 261142059Sjhb */ 262142059Sjhb p32 = argv; 263142059Sjhb for (;;) { 264142059Sjhb error = copyin(p32++, &arg, sizeof(arg)); 265142059Sjhb if (error) 266142059Sjhb return (error); 267142059Sjhb if (arg == 0) 268142059Sjhb break; 269142059Sjhb argp = PTRIN(arg); 270142059Sjhb error = copyinstr(argp, args->endp, args->stringspace, &length); 271142059Sjhb if (error) { 272142059Sjhb if (error == ENAMETOOLONG) 273142059Sjhb return (E2BIG); 274142059Sjhb else 275142059Sjhb return (error); 276142059Sjhb } 277142059Sjhb args->stringspace -= length; 278142059Sjhb args->endp += length; 279142059Sjhb args->argc++; 280100384Speter } 281142059Sjhb 282142059Sjhb args->begin_envv = args->endp; 283142059Sjhb 284142059Sjhb /* 285142059Sjhb * extract environment strings 286142059Sjhb */ 287142059Sjhb if (envv) { 288142059Sjhb p32 = envv; 289142059Sjhb for (;;) { 290100384Speter error = copyin(p32++, &arg, sizeof(arg)); 291100384Speter if (error) 292142059Sjhb return (error); 293142059Sjhb if (arg == 0) 294142059Sjhb break; 295142059Sjhb envp = PTRIN(arg); 296142059Sjhb error = copyinstr(envp, args->endp, args->stringspace, 297142059Sjhb &length); 298142059Sjhb if (error) { 299142059Sjhb if (error == ENAMETOOLONG) 300142059Sjhb return (E2BIG); 301142059Sjhb else 302142059Sjhb return (error); 303142059Sjhb } 304142059Sjhb args->stringspace -= length; 305142059Sjhb args->endp += length; 306142059Sjhb args->envc++; 307142059Sjhb } 308100384Speter } 309100384Speter 310142059Sjhb return (0); 311100384Speter} 312100384Speter 313142059Sjhbint 314142059Sjhbfreebsd32_execve(struct thread *td, struct freebsd32_execve_args *uap) 315142059Sjhb{ 316142059Sjhb struct image_args eargs; 317142059Sjhb int error; 318142059Sjhb 319142059Sjhb error = freebsd32_exec_copyin_args(&eargs, uap->fname, UIO_USERSPACE, 320142059Sjhb uap->argv, uap->envv); 321142059Sjhb if (error == 0) 322142059Sjhb error = kern_execve(td, &eargs, NULL); 323142059Sjhb exec_free_args(&eargs); 324142059Sjhb return (error); 325142059Sjhb} 326142059Sjhb 327114987Speter#ifdef __ia64__ 328100384Speterstatic int 329119333Speterfreebsd32_mmap_partial(struct thread *td, vm_offset_t start, vm_offset_t end, 330119333Speter int prot, int fd, off_t pos) 331100384Speter{ 332100384Speter vm_map_t map; 333100384Speter vm_map_entry_t entry; 334100384Speter int rv; 335100384Speter 336100384Speter map = &td->td_proc->p_vmspace->vm_map; 337100384Speter if (fd != -1) 338100384Speter prot |= VM_PROT_WRITE; 339100384Speter 340100384Speter if (vm_map_lookup_entry(map, start, &entry)) { 341100384Speter if ((entry->protection & prot) != prot) { 342100384Speter rv = vm_map_protect(map, 343100384Speter trunc_page(start), 344100384Speter round_page(end), 345100384Speter entry->protection | prot, 346100384Speter FALSE); 347100384Speter if (rv != KERN_SUCCESS) 348100384Speter return (EINVAL); 349100384Speter } 350100384Speter } else { 351100384Speter vm_offset_t addr = trunc_page(start); 352100384Speter rv = vm_map_find(map, 0, 0, 353100384Speter &addr, PAGE_SIZE, FALSE, prot, 354100384Speter VM_PROT_ALL, 0); 355100384Speter if (rv != KERN_SUCCESS) 356100384Speter return (EINVAL); 357100384Speter } 358100384Speter 359100384Speter if (fd != -1) { 360100384Speter struct pread_args r; 361107849Salfred r.fd = fd; 362107849Salfred r.buf = (void *) start; 363107849Salfred r.nbyte = end - start; 364107849Salfred r.offset = pos; 365100384Speter return (pread(td, &r)); 366100384Speter } else { 367100384Speter while (start < end) { 368100384Speter subyte((void *) start, 0); 369100384Speter start++; 370100384Speter } 371100384Speter return (0); 372100384Speter } 373100384Speter} 374114987Speter#endif 375100384Speter 376100384Speterint 377119333Speterfreebsd32_mmap(struct thread *td, struct freebsd32_mmap_args *uap) 378100384Speter{ 379100384Speter struct mmap_args ap; 380107849Salfred vm_offset_t addr = (vm_offset_t) uap->addr; 381107849Salfred vm_size_t len = uap->len; 382107849Salfred int prot = uap->prot; 383107849Salfred int flags = uap->flags; 384107849Salfred int fd = uap->fd; 385107849Salfred off_t pos = (uap->poslo 386107849Salfred | ((off_t)uap->poshi << 32)); 387114987Speter#ifdef __ia64__ 388100384Speter vm_size_t pageoff; 389100384Speter int error; 390100384Speter 391100384Speter /* 392100384Speter * Attempt to handle page size hassles. 393100384Speter */ 394100384Speter pageoff = (pos & PAGE_MASK); 395100384Speter if (flags & MAP_FIXED) { 396100384Speter vm_offset_t start, end; 397100384Speter start = addr; 398100384Speter end = addr + len; 399100384Speter 400100384Speter if (start != trunc_page(start)) { 401119333Speter error = freebsd32_mmap_partial(td, start, 402119333Speter round_page(start), prot, 403119333Speter fd, pos); 404100384Speter if (fd != -1) 405100384Speter pos += round_page(start) - start; 406100384Speter start = round_page(start); 407100384Speter } 408100384Speter if (end != round_page(end)) { 409100384Speter vm_offset_t t = trunc_page(end); 410119333Speter error = freebsd32_mmap_partial(td, t, end, 411100384Speter prot, fd, 412100384Speter pos + t - start); 413100384Speter end = trunc_page(end); 414100384Speter } 415100384Speter if (end > start && fd != -1 && (pos & PAGE_MASK)) { 416100384Speter /* 417100384Speter * We can't map this region at all. The specified 418100384Speter * address doesn't have the same alignment as the file 419100384Speter * position. Fake the mapping by simply reading the 420100384Speter * entire region into memory. First we need to make 421100384Speter * sure the region exists. 422100384Speter */ 423100384Speter vm_map_t map; 424100384Speter struct pread_args r; 425100384Speter int rv; 426100384Speter 427100384Speter prot |= VM_PROT_WRITE; 428100384Speter map = &td->td_proc->p_vmspace->vm_map; 429100384Speter rv = vm_map_remove(map, start, end); 430100384Speter if (rv != KERN_SUCCESS) 431100384Speter return (EINVAL); 432100384Speter rv = vm_map_find(map, 0, 0, 433100384Speter &start, end - start, FALSE, 434100384Speter prot, VM_PROT_ALL, 0); 435100384Speter if (rv != KERN_SUCCESS) 436100384Speter return (EINVAL); 437107849Salfred r.fd = fd; 438107849Salfred r.buf = (void *) start; 439107849Salfred r.nbyte = end - start; 440107849Salfred r.offset = pos; 441100384Speter error = pread(td, &r); 442100384Speter if (error) 443100384Speter return (error); 444100384Speter 445100384Speter td->td_retval[0] = addr; 446100384Speter return (0); 447100384Speter } 448100384Speter if (end == start) { 449100384Speter /* 450100384Speter * After dealing with the ragged ends, there 451100384Speter * might be none left. 452100384Speter */ 453100384Speter td->td_retval[0] = addr; 454100384Speter return (0); 455100384Speter } 456100384Speter addr = start; 457100384Speter len = end - start; 458100384Speter } 459114987Speter#endif 460100384Speter 461107849Salfred ap.addr = (void *) addr; 462107849Salfred ap.len = len; 463107849Salfred ap.prot = prot; 464107849Salfred ap.flags = flags; 465107849Salfred ap.fd = fd; 466107849Salfred ap.pos = pos; 467100384Speter 468100384Speter return (mmap(td, &ap)); 469100384Speter} 470100384Speter 471100384Speterstruct itimerval32 { 472100384Speter struct timeval32 it_interval; 473100384Speter struct timeval32 it_value; 474100384Speter}; 475100384Speter 476121719SpeterCTASSERT(sizeof(struct itimerval32) == 16); 477121719Speter 478100384Speterint 479119333Speterfreebsd32_setitimer(struct thread *td, struct freebsd32_setitimer_args *uap) 480100384Speter{ 481142059Sjhb struct itimerval itv, oitv, *itvp; 482142059Sjhb struct itimerval32 i32; 483100384Speter int error; 484100384Speter 485142059Sjhb if (uap->itv != NULL) { 486142059Sjhb error = copyin(uap->itv, &i32, sizeof(i32)); 487100384Speter if (error) 488100384Speter return (error); 489142059Sjhb TV_CP(i32, itv, it_interval); 490142059Sjhb TV_CP(i32, itv, it_value); 491142059Sjhb itvp = &itv; 492142059Sjhb } else 493142059Sjhb itvp = NULL; 494142059Sjhb error = kern_setitimer(td, uap->which, itvp, &oitv); 495142059Sjhb if (error || uap->oitv == NULL) 496100384Speter return (error); 497142059Sjhb TV_CP(oitv, i32, it_interval); 498142059Sjhb TV_CP(oitv, i32, it_value); 499142059Sjhb return (copyout(&i32, uap->oitv, sizeof(i32))); 500100384Speter} 501100384Speter 502100384Speterint 503125171Speterfreebsd32_getitimer(struct thread *td, struct freebsd32_getitimer_args *uap) 504125171Speter{ 505142059Sjhb struct itimerval itv; 506142059Sjhb struct itimerval32 i32; 507125171Speter int error; 508125171Speter 509142059Sjhb error = kern_getitimer(td, uap->which, &itv); 510142059Sjhb if (error || uap->itv == NULL) 511125171Speter return (error); 512142059Sjhb TV_CP(itv, i32, it_interval); 513142059Sjhb TV_CP(itv, i32, it_value); 514142059Sjhb return (copyout(&i32, uap->itv, sizeof(i32))); 515125171Speter} 516125171Speter 517125171Speterint 518119333Speterfreebsd32_select(struct thread *td, struct freebsd32_select_args *uap) 519100384Speter{ 520142059Sjhb struct timeval32 tv32; 521142059Sjhb struct timeval tv, *tvp; 522100384Speter int error; 523100384Speter 524142059Sjhb if (uap->tv != NULL) { 525142059Sjhb error = copyin(uap->tv, &tv32, sizeof(tv32)); 526100384Speter if (error) 527100384Speter return (error); 528142059Sjhb CP(tv32, tv, tv_sec); 529142059Sjhb CP(tv32, tv, tv_usec); 530142059Sjhb tvp = &tv; 531142059Sjhb } else 532142059Sjhb tvp = NULL; 533100384Speter /* 534100384Speter * XXX big-endian needs to convert the fd_sets too. 535142059Sjhb * XXX Do pointers need PTRIN()? 536100384Speter */ 537142059Sjhb return (kern_select(td, uap->nd, uap->in, uap->ou, uap->ex, tvp)); 538100384Speter} 539100384Speter 540114987Speterstruct kevent32 { 541114987Speter u_int32_t ident; /* identifier for this event */ 542114987Speter short filter; /* filter for event */ 543114987Speter u_short flags; 544114987Speter u_int fflags; 545114987Speter int32_t data; 546114987Speter u_int32_t udata; /* opaque user data identifier */ 547114987Speter}; 548114987Speter 549121719SpeterCTASSERT(sizeof(struct kevent32) == 20); 550146950Spsstatic int freebsd32_kevent_copyout(void *arg, struct kevent *kevp, int count); 551146950Spsstatic int freebsd32_kevent_copyin(void *arg, struct kevent *kevp, int count); 552121719Speter 553146950Sps/* 554146950Sps * Copy 'count' items into the destination list pointed to by uap->eventlist. 555146950Sps */ 556146950Spsstatic int 557146950Spsfreebsd32_kevent_copyout(void *arg, struct kevent *kevp, int count) 558146950Sps{ 559146950Sps struct freebsd32_kevent_args *uap; 560146950Sps struct kevent32 ks32[KQ_NEVENTS]; 561146950Sps int i, error = 0; 562146950Sps 563146950Sps KASSERT(count <= KQ_NEVENTS, ("count (%d) > KQ_NEVENTS", count)); 564146950Sps uap = (struct freebsd32_kevent_args *)arg; 565146950Sps 566146950Sps for (i = 0; i < count; i++) { 567146950Sps CP(kevp[i], ks32[i], ident); 568146950Sps CP(kevp[i], ks32[i], filter); 569146950Sps CP(kevp[i], ks32[i], flags); 570146950Sps CP(kevp[i], ks32[i], fflags); 571146950Sps CP(kevp[i], ks32[i], data); 572146950Sps PTROUT_CP(kevp[i], ks32[i], udata); 573146950Sps } 574146950Sps error = copyout(ks32, uap->eventlist, count * sizeof *ks32); 575146950Sps if (error == 0) 576146950Sps uap->eventlist += count; 577146950Sps return (error); 578146950Sps} 579146950Sps 580146950Sps/* 581146950Sps * Copy 'count' items from the list pointed to by uap->changelist. 582146950Sps */ 583146950Spsstatic int 584146950Spsfreebsd32_kevent_copyin(void *arg, struct kevent *kevp, int count) 585146950Sps{ 586146950Sps struct freebsd32_kevent_args *uap; 587146950Sps struct kevent32 ks32[KQ_NEVENTS]; 588146950Sps int i, error = 0; 589146950Sps 590146950Sps KASSERT(count <= KQ_NEVENTS, ("count (%d) > KQ_NEVENTS", count)); 591146950Sps uap = (struct freebsd32_kevent_args *)arg; 592146950Sps 593146950Sps error = copyin(uap->changelist, ks32, count * sizeof *ks32); 594146950Sps if (error) 595146950Sps goto done; 596146950Sps uap->changelist += count; 597146950Sps 598146950Sps for (i = 0; i < count; i++) { 599146950Sps CP(ks32[i], kevp[i], ident); 600146950Sps CP(ks32[i], kevp[i], filter); 601146950Sps CP(ks32[i], kevp[i], flags); 602146950Sps CP(ks32[i], kevp[i], fflags); 603146950Sps CP(ks32[i], kevp[i], data); 604146950Sps PTRIN_CP(ks32[i], kevp[i], udata); 605146950Sps } 606146950Spsdone: 607146950Sps return (error); 608146950Sps} 609146950Sps 610100384Speterint 611119333Speterfreebsd32_kevent(struct thread *td, struct freebsd32_kevent_args *uap) 612114987Speter{ 613114987Speter struct timespec32 ts32; 614142934Sps struct timespec ts, *tsp; 615146950Sps struct kevent_copyops k_ops = { uap, 616146950Sps freebsd32_kevent_copyout, 617146950Sps freebsd32_kevent_copyin}; 618146950Sps int error; 619114987Speter 620114987Speter 621114987Speter if (uap->timeout) { 622114987Speter error = copyin(uap->timeout, &ts32, sizeof(ts32)); 623114987Speter if (error) 624114987Speter return (error); 625114987Speter CP(ts32, ts, tv_sec); 626114987Speter CP(ts32, ts, tv_nsec); 627142934Sps tsp = &ts; 628142934Sps } else 629142934Sps tsp = NULL; 630146950Sps error = kern_kevent(td, uap->fd, uap->nchanges, uap->nevents, 631146950Sps &k_ops, tsp); 632142934Sps return (error); 633114987Speter} 634114987Speter 635114987Speterint 636119333Speterfreebsd32_gettimeofday(struct thread *td, 637119333Speter struct freebsd32_gettimeofday_args *uap) 638100384Speter{ 639123425Speter struct timeval atv; 640123425Speter struct timeval32 atv32; 641123425Speter struct timezone rtz; 642123425Speter int error = 0; 643100384Speter 644123425Speter if (uap->tp) { 645123425Speter microtime(&atv); 646123425Speter CP(atv, atv32, tv_sec); 647123425Speter CP(atv, atv32, tv_usec); 648123425Speter error = copyout(&atv32, uap->tp, sizeof (atv32)); 649100384Speter } 650123425Speter if (error == 0 && uap->tzp != NULL) { 651123425Speter rtz.tz_minuteswest = tz_minuteswest; 652123425Speter rtz.tz_dsttime = tz_dsttime; 653123425Speter error = copyout(&rtz, uap->tzp, sizeof (rtz)); 654100384Speter } 655100384Speter return (error); 656100384Speter} 657100384Speter 658100384Speterint 659119333Speterfreebsd32_getrusage(struct thread *td, struct freebsd32_getrusage_args *uap) 660100384Speter{ 661136152Sjhb struct rusage32 s32; 662136152Sjhb struct rusage s; 663100384Speter int error; 664100384Speter 665136152Sjhb error = kern_getrusage(td, uap->who, &s); 666100384Speter if (error) 667100384Speter return (error); 668136152Sjhb if (uap->rusage != NULL) { 669100384Speter TV_CP(s, s32, ru_utime); 670100384Speter TV_CP(s, s32, ru_stime); 671100384Speter CP(s, s32, ru_maxrss); 672100384Speter CP(s, s32, ru_ixrss); 673100384Speter CP(s, s32, ru_idrss); 674100384Speter CP(s, s32, ru_isrss); 675100384Speter CP(s, s32, ru_minflt); 676100384Speter CP(s, s32, ru_majflt); 677100384Speter CP(s, s32, ru_nswap); 678100384Speter CP(s, s32, ru_inblock); 679100384Speter CP(s, s32, ru_oublock); 680100384Speter CP(s, s32, ru_msgsnd); 681100384Speter CP(s, s32, ru_msgrcv); 682100384Speter CP(s, s32, ru_nsignals); 683100384Speter CP(s, s32, ru_nvcsw); 684100384Speter CP(s, s32, ru_nivcsw); 685136152Sjhb error = copyout(&s32, uap->rusage, sizeof(s32)); 686100384Speter } 687100384Speter return (error); 688100384Speter} 689100384Speter 690100384Speterstruct iovec32 { 691100384Speter u_int32_t iov_base; 692100384Speter int iov_len; 693100384Speter}; 694100384Speter 695121719SpeterCTASSERT(sizeof(struct iovec32) == 8); 696121719Speter 697144450Sjhbstatic int 698144450Sjhbfreebsd32_copyinuio(struct iovec32 *iovp, u_int iovcnt, struct uio **uiop) 699100384Speter{ 700144450Sjhb struct iovec32 iov32; 701144450Sjhb struct iovec *iov; 702144450Sjhb struct uio *uio; 703144450Sjhb u_int iovlen; 704144450Sjhb int error, i; 705100384Speter 706144450Sjhb *uiop = NULL; 707144450Sjhb if (iovcnt > UIO_MAXIOV) 708100384Speter return (EINVAL); 709144450Sjhb iovlen = iovcnt * sizeof(struct iovec); 710144450Sjhb uio = malloc(iovlen + sizeof *uio, M_IOV, M_WAITOK); 711144450Sjhb iov = (struct iovec *)(uio + 1); 712144450Sjhb for (i = 0; i < iovcnt; i++) { 713144450Sjhb error = copyin(&iovp[i], &iov32, sizeof(struct iovec32)); 714144450Sjhb if (error) { 715144450Sjhb free(uio, M_IOV); 716144450Sjhb return (error); 717144450Sjhb } 718144450Sjhb iov[i].iov_base = PTRIN(iov32.iov_base); 719144450Sjhb iov[i].iov_len = iov32.iov_len; 720100384Speter } 721144450Sjhb uio->uio_iov = iov; 722144450Sjhb uio->uio_iovcnt = iovcnt; 723144450Sjhb uio->uio_segflg = UIO_USERSPACE; 724144450Sjhb uio->uio_offset = -1; 725144450Sjhb uio->uio_resid = 0; 726144450Sjhb for (i = 0; i < iovcnt; i++) { 727144450Sjhb if (iov->iov_len > INT_MAX - uio->uio_resid) { 728144450Sjhb free(uio, M_IOV); 729144450Sjhb return (EINVAL); 730144450Sjhb } 731144450Sjhb uio->uio_resid += iov->iov_len; 732144450Sjhb iov++; 733144450Sjhb } 734144450Sjhb *uiop = uio; 735144450Sjhb return (0); 736144450Sjhb} 737100384Speter 738144450Sjhbint 739144450Sjhbfreebsd32_readv(struct thread *td, struct freebsd32_readv_args *uap) 740144450Sjhb{ 741144450Sjhb struct uio *auio; 742144450Sjhb int error; 743100384Speter 744144450Sjhb error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio); 745144450Sjhb if (error) 746144450Sjhb return (error); 747144450Sjhb error = kern_readv(td, uap->fd, auio); 748144450Sjhb free(auio, M_IOV); 749100384Speter return (error); 750100384Speter} 751100384Speter 752100384Speterint 753119333Speterfreebsd32_writev(struct thread *td, struct freebsd32_writev_args *uap) 754100384Speter{ 755144450Sjhb struct uio *auio; 756144450Sjhb int error; 757100384Speter 758144450Sjhb error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio); 759144450Sjhb if (error) 760144450Sjhb return (error); 761144450Sjhb error = kern_writev(td, uap->fd, auio); 762144450Sjhb free(auio, M_IOV); 763100384Speter return (error); 764100384Speter} 765100384Speter 766100384Speterint 767119333Speterfreebsd32_settimeofday(struct thread *td, 768119333Speter struct freebsd32_settimeofday_args *uap) 769100384Speter{ 770144450Sjhb struct timeval32 tv32; 771144450Sjhb struct timeval tv, *tvp; 772144450Sjhb struct timezone tz, *tzp; 773100384Speter int error; 774100384Speter 775144450Sjhb if (uap->tv) { 776144450Sjhb error = copyin(uap->tv, &tv32, sizeof(tv32)); 777100384Speter if (error) 778100384Speter return (error); 779144450Sjhb CP(tv32, tv, tv_sec); 780144450Sjhb CP(tv32, tv, tv_usec); 781144450Sjhb tvp = &tv; 782144450Sjhb } else 783144450Sjhb tvp = NULL; 784144450Sjhb if (uap->tzp) { 785144450Sjhb error = copyin(uap->tzp, &tz, sizeof(tz)); 786100384Speter if (error) 787100384Speter return (error); 788144450Sjhb tzp = &tz; 789144450Sjhb } else 790144450Sjhb tzp = NULL; 791144450Sjhb return (kern_settimeofday(td, tvp, tzp)); 792100384Speter} 793100384Speter 794100384Speterint 795119333Speterfreebsd32_utimes(struct thread *td, struct freebsd32_utimes_args *uap) 796100384Speter{ 797142059Sjhb struct timeval32 s32[2]; 798142059Sjhb struct timeval s[2], *sp; 799100384Speter int error; 800100384Speter 801142059Sjhb if (uap->tptr != NULL) { 802142059Sjhb error = copyin(uap->tptr, s32, sizeof(s32)); 803100384Speter if (error) 804100384Speter return (error); 805100384Speter CP(s32[0], s[0], tv_sec); 806100384Speter CP(s32[0], s[0], tv_usec); 807100384Speter CP(s32[1], s[1], tv_sec); 808100384Speter CP(s32[1], s[1], tv_usec); 809142059Sjhb sp = s; 810142059Sjhb } else 811142059Sjhb sp = NULL; 812142059Sjhb return (kern_utimes(td, uap->path, UIO_USERSPACE, sp, UIO_SYSSPACE)); 813100384Speter} 814100384Speter 815100384Speterint 816119333Speterfreebsd32_adjtime(struct thread *td, struct freebsd32_adjtime_args *uap) 817100384Speter{ 818144450Sjhb struct timeval32 tv32; 819144450Sjhb struct timeval delta, olddelta, *deltap; 820100384Speter int error; 821100384Speter 822144450Sjhb if (uap->delta) { 823144450Sjhb error = copyin(uap->delta, &tv32, sizeof(tv32)); 824100384Speter if (error) 825100384Speter return (error); 826144450Sjhb CP(tv32, delta, tv_sec); 827144450Sjhb CP(tv32, delta, tv_usec); 828144450Sjhb deltap = δ 829144450Sjhb } else 830144450Sjhb deltap = NULL; 831144450Sjhb error = kern_adjtime(td, deltap, &olddelta); 832144450Sjhb if (uap->olddelta && error == 0) { 833144450Sjhb CP(olddelta, tv32, tv_sec); 834144450Sjhb CP(olddelta, tv32, tv_usec); 835144450Sjhb error = copyout(&tv32, uap->olddelta, sizeof(tv32)); 836100384Speter } 837100384Speter return (error); 838100384Speter} 839100384Speter 840128597Smarcel#ifdef COMPAT_FREEBSD4 841100384Speterint 842128260Speterfreebsd4_freebsd32_statfs(struct thread *td, struct freebsd4_freebsd32_statfs_args *uap) 843100384Speter{ 844142059Sjhb struct statfs32 s32; 845142059Sjhb struct statfs s; 846100384Speter int error; 847100384Speter 848142059Sjhb error = kern_statfs(td, uap->path, UIO_USERSPACE, &s); 849100384Speter if (error) 850100384Speter return (error); 851142059Sjhb copy_statfs(&s, &s32); 852142059Sjhb return (copyout(&s32, uap->buf, sizeof(s32))); 853100384Speter} 854128597Smarcel#endif 855100384Speter 856128597Smarcel#ifdef COMPAT_FREEBSD4 857100384Speterint 858128260Speterfreebsd4_freebsd32_fstatfs(struct thread *td, struct freebsd4_freebsd32_fstatfs_args *uap) 859100384Speter{ 860142059Sjhb struct statfs32 s32; 861142059Sjhb struct statfs s; 862100384Speter int error; 863100384Speter 864142059Sjhb error = kern_fstatfs(td, uap->fd, &s); 865100384Speter if (error) 866100384Speter return (error); 867142059Sjhb copy_statfs(&s, &s32); 868142059Sjhb return (copyout(&s32, uap->buf, sizeof(s32))); 869100384Speter} 870128597Smarcel#endif 871100384Speter 872128597Smarcel#ifdef COMPAT_FREEBSD4 873100384Speterint 874128260Speterfreebsd4_freebsd32_fhstatfs(struct thread *td, struct freebsd4_freebsd32_fhstatfs_args *uap) 875128260Speter{ 876142059Sjhb struct statfs32 s32; 877142059Sjhb struct statfs s; 878142059Sjhb fhandle_t fh; 879128260Speter int error; 880128260Speter 881142059Sjhb if ((error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t))) != 0) 882142059Sjhb return (error); 883142059Sjhb error = kern_fhstatfs(td, fh, &s); 884128260Speter if (error) 885128260Speter return (error); 886142059Sjhb copy_statfs(&s, &s32); 887142059Sjhb return (copyout(&s32, uap->buf, sizeof(s32))); 888128260Speter} 889128597Smarcel#endif 890128260Speter 891128260Speterint 892119333Speterfreebsd32_semsys(struct thread *td, struct freebsd32_semsys_args *uap) 893100384Speter{ 894100384Speter /* 895100384Speter * Vector through to semsys if it is loaded. 896100384Speter */ 897100384Speter return sysent[169].sy_call(td, uap); 898100384Speter} 899100384Speter 900100384Speterint 901119333Speterfreebsd32_msgsys(struct thread *td, struct freebsd32_msgsys_args *uap) 902100384Speter{ 903100384Speter /* 904100384Speter * Vector through to msgsys if it is loaded. 905100384Speter */ 906100384Speter return sysent[170].sy_call(td, uap); 907100384Speter} 908100384Speter 909100384Speterint 910119333Speterfreebsd32_shmsys(struct thread *td, struct freebsd32_shmsys_args *uap) 911100384Speter{ 912100384Speter /* 913100384Speter * Vector through to shmsys if it is loaded. 914100384Speter */ 915100384Speter return sysent[171].sy_call(td, uap); 916100384Speter} 917100384Speter 918100384Speterint 919119333Speterfreebsd32_pread(struct thread *td, struct freebsd32_pread_args *uap) 920100384Speter{ 921100384Speter struct pread_args ap; 922100384Speter 923107849Salfred ap.fd = uap->fd; 924107849Salfred ap.buf = uap->buf; 925107849Salfred ap.nbyte = uap->nbyte; 926119333Speter ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 927100384Speter return (pread(td, &ap)); 928100384Speter} 929100384Speter 930100384Speterint 931119333Speterfreebsd32_pwrite(struct thread *td, struct freebsd32_pwrite_args *uap) 932100384Speter{ 933100384Speter struct pwrite_args ap; 934100384Speter 935107849Salfred ap.fd = uap->fd; 936107849Salfred ap.buf = uap->buf; 937107849Salfred ap.nbyte = uap->nbyte; 938119333Speter ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 939100384Speter return (pwrite(td, &ap)); 940100384Speter} 941100384Speter 942100384Speterint 943119333Speterfreebsd32_lseek(struct thread *td, struct freebsd32_lseek_args *uap) 944100384Speter{ 945100384Speter int error; 946100384Speter struct lseek_args ap; 947100384Speter off_t pos; 948100384Speter 949107849Salfred ap.fd = uap->fd; 950119333Speter ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 951107849Salfred ap.whence = uap->whence; 952100384Speter error = lseek(td, &ap); 953100384Speter /* Expand the quad return into two parts for eax and edx */ 954100384Speter pos = *(off_t *)(td->td_retval); 955100384Speter td->td_retval[0] = pos & 0xffffffff; /* %eax */ 956100384Speter td->td_retval[1] = pos >> 32; /* %edx */ 957100384Speter return error; 958100384Speter} 959100384Speter 960100384Speterint 961119333Speterfreebsd32_truncate(struct thread *td, struct freebsd32_truncate_args *uap) 962100384Speter{ 963100384Speter struct truncate_args ap; 964100384Speter 965107849Salfred ap.path = uap->path; 966119333Speter ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32)); 967100384Speter return (truncate(td, &ap)); 968100384Speter} 969100384Speter 970100384Speterint 971119333Speterfreebsd32_ftruncate(struct thread *td, struct freebsd32_ftruncate_args *uap) 972100384Speter{ 973100384Speter struct ftruncate_args ap; 974100384Speter 975107849Salfred ap.fd = uap->fd; 976119333Speter ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32)); 977100384Speter return (ftruncate(td, &ap)); 978100384Speter} 979100384Speter 980104738Speter#ifdef COMPAT_FREEBSD4 981100384Speterint 982119333Speterfreebsd4_freebsd32_sendfile(struct thread *td, 983119333Speter struct freebsd4_freebsd32_sendfile_args *uap) 984104738Speter{ 985104738Speter struct freebsd4_sendfile_args ap; 986104738Speter 987107849Salfred ap.fd = uap->fd; 988107849Salfred ap.s = uap->s; 989119333Speter ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 990107849Salfred ap.nbytes = uap->nbytes; /* XXX check */ 991107849Salfred ap.hdtr = uap->hdtr; /* XXX check */ 992107849Salfred ap.sbytes = uap->sbytes; /* XXX FIXME!! */ 993107849Salfred ap.flags = uap->flags; 994104738Speter return (freebsd4_sendfile(td, &ap)); 995104738Speter} 996104738Speter#endif 997104738Speter 998104738Speterint 999119333Speterfreebsd32_sendfile(struct thread *td, struct freebsd32_sendfile_args *uap) 1000100384Speter{ 1001100384Speter struct sendfile_args ap; 1002100384Speter 1003107849Salfred ap.fd = uap->fd; 1004107849Salfred ap.s = uap->s; 1005119333Speter ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 1006107849Salfred ap.nbytes = uap->nbytes; /* XXX check */ 1007107849Salfred ap.hdtr = uap->hdtr; /* XXX check */ 1008107849Salfred ap.sbytes = uap->sbytes; /* XXX FIXME!! */ 1009107849Salfred ap.flags = uap->flags; 1010100384Speter return (sendfile(td, &ap)); 1011100384Speter} 1012100384Speter 1013100384Speterstruct stat32 { 1014130640Sphk dev_t st_dev; 1015100384Speter ino_t st_ino; 1016100384Speter mode_t st_mode; 1017100384Speter nlink_t st_nlink; 1018100384Speter uid_t st_uid; 1019100384Speter gid_t st_gid; 1020130640Sphk dev_t st_rdev; 1021100384Speter struct timespec32 st_atimespec; 1022100384Speter struct timespec32 st_mtimespec; 1023100384Speter struct timespec32 st_ctimespec; 1024100384Speter off_t st_size; 1025100384Speter int64_t st_blocks; 1026100384Speter u_int32_t st_blksize; 1027100384Speter u_int32_t st_flags; 1028100384Speter u_int32_t st_gen; 1029121719Speter struct timespec32 st_birthtimespec; 1030121719Speter unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec32)); 1031121719Speter unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec32)); 1032100384Speter}; 1033100384Speter 1034121719Speter 1035121719SpeterCTASSERT(sizeof(struct stat32) == 96); 1036121719Speter 1037100384Speterstatic void 1038100384Spetercopy_stat( struct stat *in, struct stat32 *out) 1039100384Speter{ 1040100384Speter CP(*in, *out, st_dev); 1041100384Speter CP(*in, *out, st_ino); 1042100384Speter CP(*in, *out, st_mode); 1043100384Speter CP(*in, *out, st_nlink); 1044100384Speter CP(*in, *out, st_uid); 1045100384Speter CP(*in, *out, st_gid); 1046100384Speter CP(*in, *out, st_rdev); 1047100384Speter TS_CP(*in, *out, st_atimespec); 1048100384Speter TS_CP(*in, *out, st_mtimespec); 1049100384Speter TS_CP(*in, *out, st_ctimespec); 1050100384Speter CP(*in, *out, st_size); 1051100384Speter CP(*in, *out, st_blocks); 1052100384Speter CP(*in, *out, st_blksize); 1053100384Speter CP(*in, *out, st_flags); 1054100384Speter CP(*in, *out, st_gen); 1055100384Speter} 1056100384Speter 1057100384Speterint 1058119333Speterfreebsd32_stat(struct thread *td, struct freebsd32_stat_args *uap) 1059100384Speter{ 1060123746Speter struct stat sb; 1061123746Speter struct stat32 sb32; 1062100384Speter int error; 1063100384Speter 1064142059Sjhb error = kern_stat(td, uap->path, UIO_USERSPACE, &sb); 1065100384Speter if (error) 1066100384Speter return (error); 1067123746Speter copy_stat(&sb, &sb32); 1068123746Speter error = copyout(&sb32, uap->ub, sizeof (sb32)); 1069100384Speter return (error); 1070100384Speter} 1071100384Speter 1072100384Speterint 1073119333Speterfreebsd32_fstat(struct thread *td, struct freebsd32_fstat_args *uap) 1074100384Speter{ 1075123746Speter struct stat ub; 1076123746Speter struct stat32 ub32; 1077100384Speter int error; 1078100384Speter 1079142059Sjhb error = kern_fstat(td, uap->fd, &ub); 1080100384Speter if (error) 1081100384Speter return (error); 1082123746Speter copy_stat(&ub, &ub32); 1083123746Speter error = copyout(&ub32, uap->ub, sizeof(ub32)); 1084100384Speter return (error); 1085100384Speter} 1086100384Speter 1087100384Speterint 1088119333Speterfreebsd32_lstat(struct thread *td, struct freebsd32_lstat_args *uap) 1089100384Speter{ 1090123746Speter struct stat sb; 1091123746Speter struct stat32 sb32; 1092142059Sjhb int error; 1093100384Speter 1094142059Sjhb error = kern_lstat(td, uap->path, UIO_USERSPACE, &sb); 1095100384Speter if (error) 1096100384Speter return (error); 1097123746Speter copy_stat(&sb, &sb32); 1098123746Speter error = copyout(&sb32, uap->ub, sizeof (sb32)); 1099100384Speter return (error); 1100100384Speter} 1101100384Speter 1102100384Speter/* 1103100384Speter * MPSAFE 1104100384Speter */ 1105100384Speterint 1106119333Speterfreebsd32_sysctl(struct thread *td, struct freebsd32_sysctl_args *uap) 1107100384Speter{ 1108100384Speter int error, name[CTL_MAXNAME]; 1109100384Speter size_t j, oldlen; 1110100384Speter 1111100384Speter if (uap->namelen > CTL_MAXNAME || uap->namelen < 2) 1112100384Speter return (EINVAL); 1113136404Speter error = copyin(uap->name, name, uap->namelen * sizeof(int)); 1114100384Speter if (error) 1115100384Speter return (error); 1116100384Speter mtx_lock(&Giant); 1117100384Speter if (uap->oldlenp) 1118100384Speter oldlen = fuword32(uap->oldlenp); 1119100384Speter else 1120100384Speter oldlen = 0; 1121100384Speter error = userland_sysctl(td, name, uap->namelen, 1122100384Speter uap->old, &oldlen, 1, 1123136404Speter uap->new, uap->newlen, &j, SCTL_MASK32); 1124100384Speter if (error && error != ENOMEM) 1125100384Speter goto done2; 1126136404Speter if (uap->oldlenp) 1127100384Speter suword32(uap->oldlenp, j); 1128100384Speterdone2: 1129100384Speter mtx_unlock(&Giant); 1130100384Speter return (error); 1131100384Speter} 1132100384Speter 1133100384Speterstruct sigaction32 { 1134100384Speter u_int32_t sa_u; 1135100384Speter int sa_flags; 1136100384Speter sigset_t sa_mask; 1137100384Speter}; 1138100384Speter 1139121719SpeterCTASSERT(sizeof(struct sigaction32) == 24); 1140121719Speter 1141100384Speterint 1142119333Speterfreebsd32_sigaction(struct thread *td, struct freebsd32_sigaction_args *uap) 1143100384Speter{ 1144113859Sjhb struct sigaction32 s32; 1145113859Sjhb struct sigaction sa, osa, *sap; 1146100384Speter int error; 1147100384Speter 1148113859Sjhb if (uap->act) { 1149113859Sjhb error = copyin(uap->act, &s32, sizeof(s32)); 1150100384Speter if (error) 1151100384Speter return (error); 1152113859Sjhb sa.sa_handler = PTRIN(s32.sa_u); 1153113859Sjhb CP(s32, sa, sa_flags); 1154113859Sjhb CP(s32, sa, sa_mask); 1155113859Sjhb sap = &sa; 1156113859Sjhb } else 1157113859Sjhb sap = NULL; 1158113859Sjhb error = kern_sigaction(td, uap->sig, sap, &osa, 0); 1159146583Sps if (error == 0 && uap->oact != NULL) { 1160113859Sjhb s32.sa_u = PTROUT(osa.sa_handler); 1161113859Sjhb CP(osa, s32, sa_flags); 1162113859Sjhb CP(osa, s32, sa_mask); 1163113859Sjhb error = copyout(&s32, uap->oact, sizeof(s32)); 1164100384Speter } 1165100384Speter return (error); 1166100384Speter} 1167100384Speter 1168114987Speter#ifdef COMPAT_FREEBSD4 1169114987Speterint 1170119333Speterfreebsd4_freebsd32_sigaction(struct thread *td, 1171119333Speter struct freebsd4_freebsd32_sigaction_args *uap) 1172114987Speter{ 1173114987Speter struct sigaction32 s32; 1174114987Speter struct sigaction sa, osa, *sap; 1175114987Speter int error; 1176114987Speter 1177114987Speter if (uap->act) { 1178114987Speter error = copyin(uap->act, &s32, sizeof(s32)); 1179114987Speter if (error) 1180114987Speter return (error); 1181114987Speter sa.sa_handler = PTRIN(s32.sa_u); 1182114987Speter CP(s32, sa, sa_flags); 1183114987Speter CP(s32, sa, sa_mask); 1184114987Speter sap = &sa; 1185114987Speter } else 1186114987Speter sap = NULL; 1187114987Speter error = kern_sigaction(td, uap->sig, sap, &osa, KSA_FREEBSD4); 1188146583Sps if (error == 0 && uap->oact != NULL) { 1189114987Speter s32.sa_u = PTROUT(osa.sa_handler); 1190114987Speter CP(osa, s32, sa_flags); 1191114987Speter CP(osa, s32, sa_mask); 1192114987Speter error = copyout(&s32, uap->oact, sizeof(s32)); 1193114987Speter } 1194114987Speter return (error); 1195114987Speter} 1196114987Speter#endif 1197114987Speter 1198140481Spsint 1199140481Spsfreebsd32_nanosleep(struct thread *td, struct freebsd32_nanosleep_args *uap) 1200140481Sps{ 1201140481Sps struct timespec32 rmt32, rqt32; 1202140481Sps struct timespec rmt, rqt; 1203140481Sps int error; 1204140481Sps 1205140481Sps error = copyin(uap->rqtp, &rqt32, sizeof(rqt)); 1206140481Sps if (error) 1207140481Sps return (error); 1208140481Sps 1209140481Sps CP(rqt32, rqt, tv_sec); 1210140481Sps CP(rqt32, rqt, tv_nsec); 1211140481Sps 1212140481Sps if (uap->rmtp && 1213140481Sps !useracc((caddr_t)uap->rmtp, sizeof(rmt), VM_PROT_WRITE)) 1214140481Sps return (EFAULT); 1215140481Sps error = kern_nanosleep(td, &rqt, &rmt); 1216140481Sps if (error && uap->rmtp) { 1217140481Sps int error2; 1218140481Sps 1219140481Sps CP(rmt, rmt32, tv_sec); 1220140481Sps CP(rmt, rmt32, tv_nsec); 1221140481Sps 1222140481Sps error2 = copyout(&rmt32, uap->rmtp, sizeof(rmt)); 1223140481Sps if (error2) 1224140481Sps error = error2; 1225140481Sps } 1226140481Sps return (error); 1227140481Sps} 1228140481Sps 1229100384Speter#if 0 1230100384Speter 1231100384Speterint 1232119333Speterfreebsd32_xxx(struct thread *td, struct freebsd32_xxx_args *uap) 1233100384Speter{ 1234100384Speter int error; 1235100384Speter struct yyy32 *p32, s32; 1236100384Speter struct yyy *p = NULL, s; 1237100384Speter 1238147654Sjhb if (uap->zzz) { 1239147654Sjhb error = copyin(uap->zzz, &s32, sizeof(s32)); 1240100384Speter if (error) 1241100384Speter return (error); 1242100384Speter /* translate in */ 1243147654Sjhb p = &s; 1244100384Speter } 1245147654Sjhb error = kern_xxx(td, p); 1246100384Speter if (error) 1247100384Speter return (error); 1248147654Sjhb if (uap->zzz) { 1249100384Speter /* translate out */ 1250100384Speter error = copyout(&s32, p32, sizeof(s32)); 1251100384Speter } 1252100384Speter return (error); 1253100384Speter} 1254100384Speter 1255100384Speter#endif 1256